From 2772b1df346b68cbdbd0be8092ec16cf46d20cab Mon Sep 17 00:00:00 2001 From: gedi Date: Mon, 13 Jun 2016 23:32:04 +0300 Subject: [PATCH] cleanup and fix locating for godog dependency --- ast.go | 108 +----------------------------- ast_context_test.go | 76 --------------------- ast_test.go | 160 ++++++++++---------------------------------- builder.go | 15 ++--- 4 files changed, 43 insertions(+), 316 deletions(-) delete mode 100644 ast_context_test.go diff --git a/ast.go b/ast.go index e931ddf..fe275e0 100644 --- a/ast.go +++ b/ast.go @@ -1,12 +1,6 @@ package godog -import ( - "go/ast" - "go/build" - "go/token" - "path" - "strings" -) +import "go/ast" func astContexts(f *ast.File) []string { var contexts []string @@ -35,103 +29,3 @@ func astContexts(f *ast.File) []string { } return contexts } - -func astRemoveUnusedImports(f *ast.File) { - used := astUsedPackages(f) - isUsed := func(p string) bool { - for _, ref := range used { - if p == ref { - return true - } - } - return p == "_" - } - var decls []ast.Decl - for _, d := range f.Decls { - gen, ok := d.(*ast.GenDecl) - if ok && gen.Tok == token.IMPORT { - var specs []ast.Spec - for _, spec := range gen.Specs { - impspec := spec.(*ast.ImportSpec) - ipath := strings.Trim(impspec.Path.Value, `\"`) - check := astImportPathToName(ipath) - if impspec.Name != nil { - check = impspec.Name.Name - } - - if isUsed(check) { - specs = append(specs, spec) - } - } - - if len(specs) == 0 { - continue - } - gen.Specs = specs - } - decls = append(decls, d) - } - f.Decls = decls -} - -func astDeleteTestMainFunc(f *ast.File) { - var decls []ast.Decl - var hadTestMain bool - for _, d := range f.Decls { - fun, ok := d.(*ast.FuncDecl) - if !ok { - decls = append(decls, d) - continue - } - if fun.Name.Name != "TestMain" { - decls = append(decls, fun) - } else { - hadTestMain = true - } - } - f.Decls = decls - - if hadTestMain { - astRemoveUnusedImports(f) - } -} - -type visitFn func(node ast.Node) ast.Visitor - -func (fn visitFn) Visit(node ast.Node) ast.Visitor { - return fn(node) -} - -func astUsedPackages(f *ast.File) []string { - var refs []string - var visitor visitFn - visitor = visitFn(func(node ast.Node) ast.Visitor { - if node == nil { - return visitor - } - switch v := node.(type) { - case *ast.SelectorExpr: - xident, ok := v.X.(*ast.Ident) - if !ok { - break - } - if xident.Obj != nil { - // if the parser can resolve it, it's not a package ref - break - } - refs = append(refs, xident.Name) - } - return visitor - }) - ast.Walk(visitor, f) - return refs -} - -// importPathToName finds out the actual package name, as declared in its .go files. -// If there's a problem, it falls back to using importPathToNameBasic. -func astImportPathToName(importPath string) (packageName string) { - if buildPkg, err := build.Import(importPath, "", 0); err == nil { - return buildPkg.Name - } - return path.Base(importPath) -} diff --git a/ast_context_test.go b/ast_context_test.go deleted file mode 100644 index 8e1fa20..0000000 --- a/ast_context_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package godog - -import ( - "go/parser" - "go/token" - "testing" -) - -var astContextSrc = `package main - -import ( - "github.com/DATA-DOG/godog" -) - -func myContext(s *godog.Suite) { -}` - -var astTwoContextSrc = `package lib - -import ( - "github.com/DATA-DOG/godog" -) - -func apiContext(s *godog.Suite) { -} - -func dbContext(s *godog.Suite) { -}` - -func astContextParse(src string, t *testing.T) []string { - fset := token.NewFileSet() - f, err := parser.ParseFile(fset, "", []byte(src), 0) - if err != nil { - t.Fatalf("unexpected error while parsing ast: %v", err) - } - - return astContexts(f) -} - -func TestShouldGetSingleContextFromSource(t *testing.T) { - actual := astContextParse(astContextSrc, t) - expect := []string{"myContext"} - - if len(actual) != len(expect) { - t.Fatalf("number of found contexts do not match, expected %d, but got %d", len(expect), len(actual)) - } - - for i, c := range expect { - if c != actual[i] { - t.Fatalf("expected context '%s' at pos %d, but got: '%s'", c, i, actual[i]) - } - } -} - -func TestShouldGetTwoContextsFromSource(t *testing.T) { - actual := astContextParse(astTwoContextSrc, t) - expect := []string{"apiContext", "dbContext"} - - if len(actual) != len(expect) { - t.Fatalf("number of found contexts do not match, expected %d, but got %d", len(expect), len(actual)) - } - - for i, c := range expect { - if c != actual[i] { - t.Fatalf("expected context '%s' at pos %d, but got: '%s'", c, i, actual[i]) - } - } -} - -func TestShouldNotFindAnyContextsInEmptyFile(t *testing.T) { - actual := astContextParse(`package main`, t) - - if len(actual) != 0 { - t.Fatalf("expected no contexts to be found, but there was some: %v", actual) - } -} diff --git a/ast_test.go b/ast_test.go index ebf11b5..d14bc79 100644 --- a/ast_test.go +++ b/ast_test.go @@ -1,162 +1,76 @@ package godog import ( - "bytes" - "go/format" "go/parser" "go/token" - "strings" "testing" ) -var astMainFile = `package main - -import "fmt" - -func main() { - fmt.Println("hello") -}` - -var astNormalFile = `package main - -import "fmt" - -func hello() { - fmt.Println("hello") -}` - -var astTestMainFile = `package main +var astContextSrc = `package main import ( - "fmt" - "testing" - "os" + "github.com/DATA-DOG/godog" ) -func TestMain(m *testing.M) { - fmt.Println("hello") - os.Exit(0) +func MyContext(s *godog.Suite) { }` -var astPackAliases = `package main +var astTwoContextSrc = `package lib import ( - "testing" - a "fmt" - b "fmt" + "github.com/DATA-DOG/godog" ) -func TestMain(m *testing.M) { - a.Println("a") - b.Println("b") +func ApiContext(s *godog.Suite) { +} + +func DBContext(s *godog.Suite) { }` -var astAnonymousImport = `package main - -import ( - "testing" - _ "github.com/go-sql-driver/mysql" -) - -func TestMain(m *testing.M) { -}` - -var astLibrarySrc = `package lib - -import "fmt" - -func test() { - fmt.Println("hello") -}` - -var astInternalPackageSrc = `package godog - -import "fmt" - -func test() { - fmt.Println("hello") -}` - -func astProcess(src string, t *testing.T) string { +func astContextParse(src string, t *testing.T) []string { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "", []byte(src), 0) if err != nil { t.Fatalf("unexpected error while parsing ast: %v", err) } - astDeleteTestMainFunc(f) - - var buf bytes.Buffer - if err := format.Node(&buf, fset, f); err != nil { - t.Fatalf("failed to build source file: %v", err) - } - - return buf.String() + return astContexts(f) } -func TestShouldCleanTestMainFromSimpleTestFile(t *testing.T) { - actual := strings.TrimSpace(astProcess(astTestMainFile, t)) - expect := `package main` +func TestShouldGetSingleContextFromSource(t *testing.T) { + actual := astContextParse(astContextSrc, t) + expect := []string{"MyContext"} - if actual != expect { - t.Fatalf("expected output does not match: %s", actual) + if len(actual) != len(expect) { + t.Fatalf("number of found contexts do not match, expected %d, but got %d", len(expect), len(actual)) + } + + for i, c := range expect { + if c != actual[i] { + t.Fatalf("expected context '%s' at pos %d, but got: '%s'", c, i, actual[i]) + } } } -func TestShouldCleanTestMainFromFileWithPackageAliases(t *testing.T) { - actual := strings.TrimSpace(astProcess(astPackAliases, t)) - expect := `package main` +func TestShouldGetTwoContextsFromSource(t *testing.T) { + actual := astContextParse(astTwoContextSrc, t) + expect := []string{"ApiContext", "DBContext"} - if actual != expect { - t.Fatalf("expected output does not match: %s", actual) + if len(actual) != len(expect) { + t.Fatalf("number of found contexts do not match, expected %d, but got %d", len(expect), len(actual)) + } + + for i, c := range expect { + if c != actual[i] { + t.Fatalf("expected context '%s' at pos %d, but got: '%s'", c, i, actual[i]) + } } } -func TestShouldNotModifyNormalFile(t *testing.T) { - actual := strings.TrimSpace(astProcess(astNormalFile, t)) - expect := astNormalFile +func TestShouldNotFindAnyContextsInEmptyFile(t *testing.T) { + actual := astContextParse(`package main`, t) - if actual != expect { - t.Fatalf("expected output does not match: %s", actual) - } -} - -func TestShouldNotModifyMainFile(t *testing.T) { - actual := strings.TrimSpace(astProcess(astMainFile, t)) - expect := astMainFile - - if actual != expect { - t.Fatalf("expected output does not match: %s", actual) - } -} - -func TestShouldMaintainAnonymousImport(t *testing.T) { - actual := strings.TrimSpace(astProcess(astAnonymousImport, t)) - expect := `package main - -import ( - _ "github.com/go-sql-driver/mysql" -)` - - if actual != expect { - t.Fatalf("expected output does not match: %s", actual) - } -} - -func TestShouldNotModifyLibraryPackageSource(t *testing.T) { - actual := strings.TrimSpace(astProcess(astLibrarySrc, t)) - expect := astLibrarySrc - - if actual != expect { - t.Fatalf("expected output does not match: %s", actual) - } -} - -func TestShouldNotModifyGodogPackageSource(t *testing.T) { - actual := strings.TrimSpace(astProcess(astInternalPackageSrc, t)) - expect := astInternalPackageSrc - - if actual != expect { - t.Fatalf("expected output does not match: %s", actual) + if len(actual) != 0 { + t.Fatalf("expected no contexts to be found, but there was some: %v", actual) } } diff --git a/builder.go b/builder.go index cf03d82..337a5a7 100644 --- a/builder.go +++ b/builder.go @@ -2,7 +2,6 @@ package godog import ( "bytes" - "encoding/json" "fmt" "go/build" "go/parser" @@ -165,7 +164,11 @@ func locatePackage(try []string) (*build.Package, error) { if err != nil { continue } - return build.ImportDir(abs, 0) + pkg, err := build.ImportDir(abs, 0) + if err != nil { + continue + } + return pkg, nil } return nil, fmt.Errorf("failed to find godog package in any of:\n%s", strings.Join(try, "\n")) } @@ -214,11 +217,3 @@ func processPackageTestFiles(packs ...[]string) ([]string, error) { } return ctxs, nil } - -func debug(i interface{}) { - dat, err := json.MarshalIndent(i, "", " ") - if err != nil { - panic(err) - } - fmt.Fprintln(os.Stdout, string(dat)) -}