golang.org/x/tools@v0.21.0/go/analysis/analysistest/analysistest_test.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package analysistest_test 6 7 import ( 8 "fmt" 9 "go/token" 10 "log" 11 "os" 12 "reflect" 13 "strings" 14 "testing" 15 16 "golang.org/x/tools/go/analysis" 17 "golang.org/x/tools/go/analysis/analysistest" 18 "golang.org/x/tools/go/analysis/passes/findcall" 19 "golang.org/x/tools/internal/testenv" 20 ) 21 22 func init() { 23 // Run() decides when tests use GOPATH mode or modules. 24 // We turn off GOPROXY just for good measure. 25 if err := os.Setenv("GOPROXY", "off"); err != nil { 26 log.Fatal(err) 27 } 28 } 29 30 // TestTheTest tests the analysistest testing infrastructure. 31 func TestTheTest(t *testing.T) { 32 testenv.NeedsTool(t, "go") 33 34 // We'll simulate a partly failing test of the findcall analysis, 35 // which (by default) reports calls to functions named 'println'. 36 findcall.Analyzer.Flags.Set("name", "println") 37 38 filemap := map[string]string{ 39 "a/b.go": `package main // want package:"found" 40 41 func main() { 42 // The expectation is ill-formed: 43 print() // want: "diagnostic" 44 print() // want foo"fact" 45 print() // want foo: 46 print() // want "\xZZ scan error" 47 48 // A diagnostic is reported at this line, but the expectation doesn't match: 49 println("hello, world") // want "wrong expectation text" 50 51 // An unexpected diagnostic is reported at this line: 52 println() // trigger an unexpected diagnostic 53 54 // No diagnostic is reported at this line: 55 print() // want "unsatisfied expectation" 56 57 // OK 58 println("hello, world") // want "call of println" 59 60 // OK /* */-form. 61 println("안녕, 세계") /* want "call of println" */ 62 63 // OK (nested comment) 64 println("Γειά σου, Κόσμε") // some comment // want "call of println" 65 66 // OK (nested comment in /**/) 67 println("你好,世界") /* some comment // want "call of println" */ 68 69 // OK (multiple expectations on same line) 70 println(); println() // want "call of println(...)" "call of println(...)" 71 72 // A Line that is not formatted correctly in the golden file. 73 } 74 75 // OK (facts and diagnostics on same line) 76 func println(...interface{}) { println() } // want println:"found" "call of println(...)" 77 78 `, 79 "a/b.go.golden": `package main // want package:"found" 80 81 func main() { 82 // The expectation is ill-formed: 83 print() // want: "diagnostic" 84 print() // want foo"fact" 85 print() // want foo: 86 print() // want "\xZZ scan error" 87 88 // A diagnostic is reported at this line, but the expectation doesn't match: 89 println_TEST_("hello, world") // want "wrong expectation text" 90 91 // An unexpected diagnostic is reported at this line: 92 println_TEST_() // trigger an unexpected diagnostic 93 94 // No diagnostic is reported at this line: 95 print() // want "unsatisfied expectation" 96 97 // OK 98 println_TEST_("hello, world") // want "call of println" 99 100 // OK /* */-form. 101 println_TEST_("안녕, 세계") /* want "call of println" */ 102 103 // OK (nested comment) 104 println_TEST_("Γειά σου, Κόσμε") // some comment // want "call of println" 105 106 // OK (nested comment in /**/) 107 println_TEST_("你好,世界") /* some comment // want "call of println" */ 108 109 // OK (multiple expectations on same line) 110 println_TEST_() 111 println_TEST_() // want "call of println(...)" "call of println(...)" 112 113 // A Line that is not formatted correctly in the golden file. 114 } 115 116 // OK (facts and diagnostics on same line) 117 func println(...interface{}) { println_TEST_() } // want println:"found" "call of println(...)" 118 `, 119 "a/b_test.go": `package main 120 121 // Test file shouldn't mess with things (issue #40574) 122 `, 123 } 124 dir, cleanup, err := analysistest.WriteFiles(filemap) 125 if err != nil { 126 t.Fatal(err) 127 } 128 defer cleanup() 129 130 var got []string 131 t2 := errorfunc(func(s string) { got = append(got, s) }) // a fake *testing.T 132 analysistest.RunWithSuggestedFixes(t2, dir, findcall.Analyzer, "a") 133 134 want := []string{ 135 `a/b.go:5: in 'want' comment: unexpected ":"`, 136 `a/b.go:6: in 'want' comment: got String after foo, want ':'`, 137 `a/b.go:7: in 'want' comment: got EOF, want regular expression`, 138 `a/b.go:8: in 'want' comment: invalid char escape`, 139 "a/b.go:11:9: diagnostic \"call of println(...)\" does not match pattern `wrong expectation text`", 140 `a/b.go:14:9: unexpected diagnostic: call of println(...)`, 141 "a/b.go:11: no diagnostic was reported matching `wrong expectation text`", 142 "a/b.go:17: no diagnostic was reported matching `unsatisfied expectation`", 143 // duplicate copies of each message from the test package (see issue #40574) 144 `a/b.go:5: in 'want' comment: unexpected ":"`, 145 `a/b.go:6: in 'want' comment: got String after foo, want ':'`, 146 `a/b.go:7: in 'want' comment: got EOF, want regular expression`, 147 `a/b.go:8: in 'want' comment: invalid char escape`, 148 "a/b.go:11:9: diagnostic \"call of println(...)\" does not match pattern `wrong expectation text`", 149 `a/b.go:14:9: unexpected diagnostic: call of println(...)`, 150 "a/b.go:11: no diagnostic was reported matching `wrong expectation text`", 151 "a/b.go:17: no diagnostic was reported matching `unsatisfied expectation`", 152 } 153 if !reflect.DeepEqual(got, want) { 154 t.Errorf("got:\n%s\nwant:\n%s", 155 strings.Join(got, "\n"), 156 strings.Join(want, "\n")) 157 } 158 } 159 160 // TestNoEnd tests that a missing SuggestedFix.End position is 161 // correctly interpreted as if equal to SuggestedFix.Pos (see issue #64199). 162 func TestNoEnd(t *testing.T) { 163 noend := &analysis.Analyzer{ 164 Name: "noend", 165 Doc: "inserts /*hello*/ before first decl", 166 Run: func(pass *analysis.Pass) (any, error) { 167 decl := pass.Files[0].Decls[0] 168 pass.Report(analysis.Diagnostic{ 169 Pos: decl.Pos(), 170 End: token.NoPos, 171 Message: "say hello", 172 SuggestedFixes: []analysis.SuggestedFix{{ 173 Message: "say hello", 174 TextEdits: []analysis.TextEdit{ 175 { 176 Pos: decl.Pos(), 177 End: token.NoPos, 178 NewText: []byte("/*hello*/"), 179 }, 180 }, 181 }}, 182 }) 183 return nil, nil 184 }, 185 } 186 187 filemap := map[string]string{ 188 "a/a.go": `package a 189 190 func F() {} // want "say hello"`, 191 "a/a.go.golden": `package a 192 193 /*hello*/ 194 func F() {} // want "say hello"`, 195 } 196 dir, cleanup, err := analysistest.WriteFiles(filemap) 197 if err != nil { 198 t.Fatal(err) 199 } 200 defer cleanup() 201 202 analysistest.RunWithSuggestedFixes(t, dir, noend, "a") 203 } 204 205 type errorfunc func(string) 206 207 func (f errorfunc) Errorf(format string, args ...interface{}) { 208 f(fmt.Sprintf(format, args...)) 209 }