package main import ( "bufio" "bytes" "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "regexp" "strconv" "testing" "github.com/vattle/sqlboiler/bdb" ) var state *State var rgxHasSpaces = regexp.MustCompile(`^\s+`) func init() { state = &State{ Driver: fakeDB(0), Tables: []bdb.Table{ { Name: "patrick_table", Columns: []bdb.Column{ {Name: "patrick_column", Type: "string", Nullable: false}, {Name: "aaron_column", Type: "null.String", Nullable: true}, {Name: "id", Type: "null.Int", Nullable: true}, {Name: "fun_id", Type: "int64", Nullable: false}, {Name: "time", Type: "null.Time", Nullable: true}, {Name: "fun_time", Type: "time.Time", Nullable: false}, {Name: "cool_stuff_forever", Type: "[]byte", Nullable: false}, }, PKey: &bdb.PrimaryKey{ Name: "pkey_thing", Columns: []string{"id", "fun_id"}, }, }, { Name: "spiderman", Columns: []bdb.Column{ {Name: "id", Type: "int64", Nullable: false}, }, PKey: &bdb.PrimaryKey{ Name: "pkey_id", Columns: []string{"id"}, }, }, { Name: "spiderman_table_two", Columns: []bdb.Column{ {Name: "id", Type: "int64", Nullable: false}, {Name: "patrick", Type: "string", Nullable: false}, }, PKey: &bdb.PrimaryKey{ Name: "pkey_id", Columns: []string{"id"}, }, }, }, Config: &Config{ PkgName: "patrick", OutFolder: "", DriverName: "postgres", }, } } func TestLoadTemplate(t *testing.T) { t.Parallel() template, err := loadTemplate("templates_test/main_test", "postgres_main.tpl") if err != nil { t.Fatalf("Unable to loadTemplate: %s", err) } if template == nil { t.Fatal("Unable to load template.") } } func TestTemplates(t *testing.T) { if testing.Short() { t.SkipNow() } if err := checkPKeys(state.Tables); err != nil { t.Fatalf("%s", err) } // Initialize the templates var err error state.Templates, err = loadTemplates("templates") if err != nil { t.Fatalf("Unable to initialize templates: %s", err) } if len(state.Templates.Templates()) == 0 { t.Errorf("Templates is empty.") } state.SingletonTemplates, err = loadTemplates("templates/singleton") if err != nil { t.Fatalf("Unable to initialize singleton templates: %s", err) } if len(state.SingletonTemplates.Templates()) == 0 { t.Errorf("SingletonTemplates is empty.") } state.TestTemplates, err = loadTemplates("templates_test") if err != nil { t.Fatalf("Unable to initialize templates: %s", err) } if len(state.Templates.Templates()) == 0 { t.Errorf("Templates is empty.") } state.TestMainTemplate, err = loadTemplate("templates_test/main_test", "postgres_main.tpl") if err != nil { t.Fatalf("Unable to initialize templates: %s", err) } state.SingletonTestTemplates, err = loadTemplates("templates_test/singleton") if err != nil { t.Fatalf("Unable to initialize single test templates: %s", err) } if len(state.SingletonTestTemplates.Templates()) == 0 { t.Errorf("SingleTestTemplates is empty.") } state.Config.OutFolder, err = ioutil.TempDir("", "templates") if err != nil { t.Fatalf("Unable to create tempdir: %s", err) } defer func() { if t.Failed() { t.Log("template test output:", state.Config.OutFolder) return } os.RemoveAll(state.Config.OutFolder) }() if err = state.Run(true); err != nil { t.Errorf("Unable to run SQLBoilerRun: %s", err) } buf := &bytes.Buffer{} cmd := exec.Command("go", "test", "-c") cmd.Dir = state.Config.OutFolder cmd.Stderr = buf if err = cmd.Run(); err != nil { t.Errorf("go test cmd execution failed: %s", err) outputCompileErrors(buf, state.Config.OutFolder) fmt.Println() } } func outputCompileErrors(buf *bytes.Buffer, outFolder string) { type errObj struct { errMsg string fileName string lineNumber int } var errObjects []errObj lineBuf := &bytes.Buffer{} bufLines := bytes.Split(buf.Bytes(), []byte{'\n'}) for i := 0; i < len(bufLines); i++ { lineBuf.Reset() if !bytes.HasPrefix(bufLines[i], []byte("./")) { continue } fmt.Fprintf(lineBuf, "%s\n", bufLines[i]) splits := bytes.Split(bufLines[i], []byte{':'}) lineNum, err := strconv.Atoi(string(splits[1])) if err != nil { panic(fmt.Sprintf("Cant convert line number to int: %s", bufLines[i])) } eObj := errObj{ fileName: string(splits[0]), lineNumber: lineNum, } for y := i; y < len(bufLines); y++ { if !rgxHasSpaces.Match(bufLines[y]) { break } fmt.Fprintf(lineBuf, "%s\n", bufLines[y]) i++ } eObj.errMsg = lineBuf.String() errObjects = append(errObjects, eObj) } for _, eObj := range errObjects { fmt.Printf("-----------------\n") fmt.Println(eObj.errMsg) filePath := filepath.Join(outFolder, eObj.fileName) fh, err := os.Open(filePath) if err != nil { panic(fmt.Sprintf("Cant open the file: %#v", eObj)) } scanner := bufio.NewScanner(fh) throwaway := eObj.lineNumber - 5 for throwaway > 0 && scanner.Scan() { throwaway-- } for i := 0; i < 6; i++ { if scanner.Scan() { b := scanner.Bytes() if len(b) != 0 { fmt.Printf("%s\n", b) } else { i-- } } } fh.Close() } }