From 5e5234f81f512f0b2a1c056c510e25b11263e918 Mon Sep 17 00:00:00 2001 From: gedi Date: Tue, 7 Jul 2015 15:07:20 +0300 Subject: [PATCH] test runnable source builder --- builder.go | 44 ++++----- builder_test.go | 225 +++++++++++++++++++++++++++++++++++++++++++++ tag_filter_test.go | 2 +- 3 files changed, 245 insertions(+), 26 deletions(-) create mode 100644 builder_test.go diff --git a/builder.go b/builder.go index 3954051..efac14c 100644 --- a/builder.go +++ b/builder.go @@ -39,8 +39,8 @@ func (b *builder) hasImport(a *ast.ImportSpec) bool { return false } -func newBuilder(buildPath string) (*builder, error) { - b := &builder{ +func newBuilderSkel() *builder { + return &builder{ files: make(map[string]*ast.File), fset: token.NewFileSet(), tpl: template.Must(template.New("main").Parse(`package main @@ -57,15 +57,20 @@ func main() { }) }`)), } +} +func newBuilder(buildPath string) (*builder, error) { + b := newBuilderSkel() err := filepath.Walk(buildPath, func(path string, file os.FileInfo, err error) error { if file.IsDir() && file.Name() != "." { return filepath.SkipDir } if err == nil && strings.HasSuffix(path, ".go") { - if err := b.parseFile(path); err != nil { + f, err := parser.ParseFile(b.fset, path, nil, 0) + if err != nil { return err } + b.register(f, path) } return err }) @@ -73,11 +78,7 @@ func main() { return b, err } -func (b *builder) parseFile(path string) error { - f, err := parser.ParseFile(b.fset, path, nil, 0) - if err != nil { - return err - } +func (b *builder) register(f *ast.File, path string) { // mark godog package as internal if f.Name.Name == "godog" && !b.Internal { b.Internal = true @@ -86,8 +87,6 @@ func (b *builder) parseFile(path string) error { b.registerContexts(f) b.deleteImports(f) b.files[path] = f - - return nil } func (b *builder) deleteImports(f *ast.File) { @@ -149,7 +148,7 @@ func (b *builder) registerContexts(f *ast.File) { } } -func (b *builder) merge() (*ast.File, error) { +func (b *builder) merge() ([]byte, error) { var buf bytes.Buffer if err := b.tpl.Execute(&buf, b); err != nil { return nil, err @@ -168,7 +167,7 @@ func (b *builder) merge() (*ast.File, error) { ret, err := ast.MergePackageFiles(pkg, 0), nil if err != nil { - return ret, err + return nil, err } // @TODO: we reread the file, probably something goes wrong with position @@ -190,7 +189,13 @@ func (b *builder) merge() (*ast.File, error) { ipath, _ := strconv.Unquote(spec.Path.Value) addImport(b.fset, ret, name, ipath) } - return ret, nil + + buf.Reset() + if err := format.Node(&buf, b.fset, ret); err != nil { + return nil, err + } + + return buf.Bytes(), nil } // Build creates a runnable Godog executable file @@ -209,18 +214,7 @@ func Build() ([]byte, error) { return nil, err } - merged, err := b.merge() - if err != nil { - return nil, err - } - - var buf bytes.Buffer - - if err := format.Node(&buf, b.fset, merged); err != nil { - return nil, err - } - - return buf.Bytes(), nil + return b.merge() } // taken from https://github.com/golang/tools/blob/master/go/ast/astutil/imports.go#L17 diff --git a/builder_test.go b/builder_test.go new file mode 100644 index 0000000..94ba5d9 --- /dev/null +++ b/builder_test.go @@ -0,0 +1,225 @@ +package godog + +import ( + "fmt" + "go/parser" + "go/token" + "strings" + "testing" +) + +var builderMainFile = ` +package main +import "fmt" +func main() { + fmt.Println("hello") +}` + +var builderPackAliases = ` +package main +import ( + a "fmt" + b "fmt" +) +func Tester() { + a.Println("a") + b.Println("b") +}` + +var builderAnonymousImport = ` +package main +import ( + _ "github.com/go-sql-driver/mysql" +) +` + +var builderContextSrc = ` +package main +import ( + "github.com/DATA-DOG/godog" +) + +func myContext(s *godog.Suite) { + +} +` + +var builderLibrarySrc = ` +package lib +import "fmt" +func test() { + fmt.Println("hello") +} +` + +var builderInternalPackageSrc = ` +package godog +import "fmt" +func test() { + fmt.Println("hello") +} +` + +func (b *builder) registerMulti(contents []string) error { + for i, c := range contents { + f, err := parser.ParseFile(token.NewFileSet(), "", []byte(c), 0) + if err != nil { + return err + } + b.register(f, fmt.Sprintf("path%d", i)) + } + return nil +} + +func (b *builder) cleanSpacing(src string) string { + var lines []string + for _, ln := range strings.Split(src, "\n") { + if ln == "" { + continue + } + lines = append(lines, strings.TrimSpace(ln)) + } + return strings.Join(lines, "\n") +} + +func TestUsualSourceFileMerge(t *testing.T) { + b := newBuilderSkel() + err := b.registerMulti([]string{ + builderMainFile, builderPackAliases, builderAnonymousImport, + }) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + data, err := b.merge() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + expected := `package main + +import ( + "fmt" + a "fmt" + b "fmt" + "github.com/DATA-DOG/godog" + _ "github.com/go-sql-driver/mysql" +) + +func main() { + godog.Run(func(suite *godog.Suite) { + + }) +} +func Tester() { + a.Println("a") + b.Println("b") +}` + + actual := string(data) + if b.cleanSpacing(expected) != b.cleanSpacing(actual) { + t.Fatalf("expected output does not match: %s", actual) + } +} + +func TestShouldCallContextOnMerged(t *testing.T) { + b := newBuilderSkel() + err := b.registerMulti([]string{ + builderMainFile, builderContextSrc, + }) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + data, err := b.merge() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + expected := `package main +import ( + "fmt" + "github.com/DATA-DOG/godog" +) + +func main() { + godog.Run(func(suite *godog.Suite) { + myContext(suite) + }) +} + +func myContext(s *godog.Suite) { +}` + + actual := string(data) + if b.cleanSpacing(expected) != b.cleanSpacing(actual) { + t.Fatalf("expected output does not match: %s", actual) + } +} + +func TestBuildLibraryPackage(t *testing.T) { + b := newBuilderSkel() + err := b.registerMulti([]string{ + builderLibrarySrc, + }) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + data, err := b.merge() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + expected := `package main +import ( + "fmt" + "github.com/DATA-DOG/godog" +) + +func main() { + godog.Run(func(suite *godog.Suite) { + + }) +} + +func test() { + fmt.Println( + "hello", + ) +}` + + actual := string(data) + if b.cleanSpacing(expected) != b.cleanSpacing(actual) { + t.Fatalf("expected output does not match: %s", actual) + } +} + +func TestBuildInternalPackage(t *testing.T) { + b := newBuilderSkel() + err := b.registerMulti([]string{ + builderInternalPackageSrc, + }) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + data, err := b.merge() + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + expected := `package main +import "fmt" + +func main() { + Run(func(suite *Suite) { + + }) +} + +func test() { + fmt.Println("hello") +}` + + actual := string(data) + if b.cleanSpacing(expected) != b.cleanSpacing(actual) { + t.Fatalf("expected output does not match: %s", actual) + } +} diff --git a/tag_filter_test.go b/tag_filter_test.go index 8b965b9..57440e2 100644 --- a/tag_filter_test.go +++ b/tag_filter_test.go @@ -16,7 +16,7 @@ func assertMatchesTagFilter(tags []string, filter string, t *testing.T) { } } -func Test_tag_filter(t *testing.T) { +func TestTagFilter(t *testing.T) { assertMatchesTagFilter([]string{"wip"}, "@wip", t) assertMatchesTagFilter([]string{}, "~@wip", t) assertMatchesTagFilter([]string{"one", "two"}, "@two,@three", t)