cleanup and fix locating for godog dependency
Этот коммит содержится в:
		
							родитель
							
								
									d0f68b3fe1
								
							
						
					
					
						коммит
						2772b1df34
					
				
					 4 изменённых файлов: 43 добавлений и 316 удалений
				
			
		
							
								
								
									
										108
									
								
								ast.go
									
										
									
									
									
								
							
							
						
						
									
										108
									
								
								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) | ||||
| } | ||||
|  |  | |||
|  | @ -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) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										160
									
								
								ast_test.go
									
										
									
									
									
								
							
							
						
						
									
										160
									
								
								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) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
							
								
								
									
										15
									
								
								builder.go
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								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)) | ||||
| } | ||||
|  |  | |||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 gedi
						gedi