1package predeclared 2 3import ( 4 "bytes" 5 "fmt" 6 "go/parser" 7 "go/token" 8 "io/ioutil" 9 "strings" 10 "testing" 11 12 "golang.org/x/tools/go/analysis" 13) 14 15func outPath(p string) string { return strings.TrimSuffix(p, ".go") + ".out" } 16 17func equalBytes(t *testing.T, a, b []byte, normalize func([]byte) []byte) { 18 if normalize != nil { 19 a = normalize(a) 20 b = normalize(b) 21 } 22 if !bytes.Equal(a, b) { 23 t.Errorf(`bytes not equal 24want: %s 25got: %s 26`, a, b) 27 } 28} 29 30func setupConfig(p string) *config { 31 ignore := "" 32 qualified := false 33 34 // Get the first line. 35 b, err := ioutil.ReadFile(p) 36 if err != nil { 37 panic(fmt.Sprintf("failed to read file: %s", p)) 38 } 39 idx := bytes.IndexByte(b, '\n') 40 if idx == -1 { 41 panic(fmt.Sprintf("no lines in file: %s", p)) 42 } 43 // Does it have the prefix? 44 const prefix = "//predeclared" 45 line := string(b[:idx]) 46 if !strings.HasPrefix(line, prefix) { 47 return newConfig(ignore, qualified) 48 } else { 49 line = strings.TrimPrefix(line, prefix) 50 } 51 // Parse. 52 args := strings.Fields(line) 53 for i := 0; i < len(args); { 54 arg := args[i] 55 switch arg { 56 case "-ignore": 57 i++ 58 ignore = args[i] 59 case "-q": 60 qualified = true 61 default: 62 panic("unhandled flag") 63 } 64 i++ 65 } 66 67 return newConfig(ignore, qualified) 68} 69 70func TestAll(t *testing.T) { 71 filenames := []string{ 72 "testdata/example1.go", 73 "testdata/example2.go", 74 "testdata/example3.go", 75 "testdata/ignore.go", 76 "testdata/all.go", 77 "testdata/all-q.go", 78 "testdata/no-issues.go", 79 "testdata/no-issues2.go", 80 } 81 82 for i, path := range filenames { 83 if testing.Verbose() { 84 t.Logf("test [%d]: %s", i, path) 85 } 86 runOneFile(t, setupConfig(path), path) 87 } 88} 89 90func runOneFile(t *testing.T, cfg *config, path string) { 91 src, err := ioutil.ReadFile(path) 92 if err != nil { 93 t.Errorf("failed to read file: %s", err) 94 return 95 } 96 97 outContent, err := ioutil.ReadFile(outPath(path)) 98 if err != nil { 99 t.Errorf("failed to read out file: %s", err) 100 return 101 } 102 103 fset := token.NewFileSet() 104 file, err := parser.ParseFile(fset, path, src, parser.AllErrors) 105 if err != nil { 106 t.Errorf("failed to parse file") 107 return 108 } 109 110 dummyReportFunc := func(analysis.Diagnostic) {} 111 112 issues := processFile(dummyReportFunc, cfg, fset, file) 113 var buf bytes.Buffer 114 for _, issue := range issues { 115 fmt.Fprintf(&buf, "%s\n", issue) 116 } 117 118 equalBytes(t, outContent, buf.Bytes(), bytes.TrimSpace) 119} 120