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
5package analysistest_test
6
7import (
8	"fmt"
9	"log"
10	"os"
11	"reflect"
12	"strings"
13	"testing"
14
15	"golang.org/x/tools/go/analysis/analysistest"
16	"golang.org/x/tools/go/analysis/passes/findcall"
17	"golang.org/x/tools/internal/testenv"
18)
19
20func init() {
21	// This test currently requires GOPATH mode.
22	// Explicitly disabling module mode should suffice, but
23	// we'll also turn off GOPROXY just for good measure.
24	if err := os.Setenv("GO111MODULE", "off"); err != nil {
25		log.Fatal(err)
26	}
27	if err := os.Setenv("GOPROXY", "off"); err != nil {
28		log.Fatal(err)
29	}
30}
31
32// TestTheTest tests the analysistest testing infrastructure.
33func TestTheTest(t *testing.T) {
34	testenv.NeedsTool(t, "go")
35
36	// We'll simulate a partly failing test of the findcall analysis,
37	// which (by default) reports calls to functions named 'println'.
38	findcall.Analyzer.Flags.Set("name", "println")
39
40	filemap := map[string]string{
41		"a/b.go": `package main // want package:"found"
42
43func main() {
44	// The expectation is ill-formed:
45	print() // want: "diagnostic"
46	print() // want foo"fact"
47	print() // want foo:
48	print() // want "\xZZ scan error"
49
50	// A diagnostic is reported at this line, but the expectation doesn't match:
51	println("hello, world") // want "wrong expectation text"
52
53	// An unexpected diagnostic is reported at this line:
54	println() // trigger an unexpected diagnostic
55
56	// No diagnostic is reported at this line:
57	print()	// want "unsatisfied expectation"
58
59	// OK
60	println("hello, world") // want "call of println"
61
62	// OK /* */-form.
63	println("안녕, 세계") /* want "call of println" */
64
65	// OK  (nested comment)
66	println("Γειά σου, Κόσμε") // some comment // want "call of println"
67
68	// OK (nested comment in /**/)
69	println("你好,世界") /* some comment // want "call of println" */
70
71	// OK (multiple expectations on same line)
72	println(); println() // want "call of println(...)" "call of println(...)"
73}
74
75// OK (facts and diagnostics on same line)
76func println(...interface{}) { println() } // want println:"found" "call of println(...)"
77
78`,
79		"a/b.go.golden": `package main // want package:"found"
80
81func 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
114// OK (facts and diagnostics on same line)
115func println(...interface{}) { println_TEST_() } // want println:"found" "call of println(...)"
116`,
117		"a/b_test.go": `package main
118
119// Test file shouldn't mess with things (issue #40574)
120`,
121	}
122	dir, cleanup, err := analysistest.WriteFiles(filemap)
123	if err != nil {
124		t.Fatal(err)
125	}
126	defer cleanup()
127
128	var got []string
129	t2 := errorfunc(func(s string) { got = append(got, s) }) // a fake *testing.T
130	analysistest.RunWithSuggestedFixes(t2, dir, findcall.Analyzer, "a")
131
132	want := []string{
133		`a/b.go:5: in 'want' comment: unexpected ":"`,
134		`a/b.go:6: in 'want' comment: got String after foo, want ':'`,
135		`a/b.go:7: in 'want' comment: got EOF, want regular expression`,
136		`a/b.go:8: in 'want' comment: invalid char escape`,
137		`a/b.go:11:9: diagnostic "call of println(...)" does not match pattern "wrong expectation text"`,
138		`a/b.go:14:9: unexpected diagnostic: call of println(...)`,
139		`a/b.go:11: no diagnostic was reported matching "wrong expectation text"`,
140		`a/b.go:17: no diagnostic was reported matching "unsatisfied expectation"`,
141		// duplicate copies of each message from the test package (see issue #40574)
142		`a/b.go:5: in 'want' comment: unexpected ":"`,
143		`a/b.go:6: in 'want' comment: got String after foo, want ':'`,
144		`a/b.go:7: in 'want' comment: got EOF, want regular expression`,
145		`a/b.go:8: in 'want' comment: invalid char escape`,
146		`a/b.go:11:9: diagnostic "call of println(...)" does not match pattern "wrong expectation text"`,
147		`a/b.go:14:9: unexpected diagnostic: call of println(...)`,
148		`a/b.go:11: no diagnostic was reported matching "wrong expectation text"`,
149		`a/b.go:17: no diagnostic was reported matching "unsatisfied expectation"`,
150	}
151	if !reflect.DeepEqual(got, want) {
152		t.Errorf("got:\n%s\nwant:\n%s",
153			strings.Join(got, "\n"),
154			strings.Join(want, "\n"))
155	}
156}
157
158type errorfunc func(string)
159
160func (f errorfunc) Errorf(format string, args ...interface{}) {
161	f(fmt.Sprintf(format, args...))
162}
163