Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / godoc / godoc_test.go
1 // Copyright 2013 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 godoc
6
7 import (
8         "bytes"
9         "go/parser"
10         "go/token"
11         "strings"
12         "testing"
13 )
14
15 func TestPkgLinkFunc(t *testing.T) {
16         for _, tc := range []struct {
17                 path string
18                 want string
19         }{
20                 {"/src/fmt", "pkg/fmt"},
21                 {"src/fmt", "pkg/fmt"},
22                 {"/fmt", "pkg/fmt"},
23                 {"fmt", "pkg/fmt"},
24         } {
25                 if got := pkgLinkFunc(tc.path); got != tc.want {
26                         t.Errorf("pkgLinkFunc(%v) = %v; want %v", tc.path, got, tc.want)
27                 }
28         }
29 }
30
31 func TestSrcPosLinkFunc(t *testing.T) {
32         for _, tc := range []struct {
33                 src  string
34                 line int
35                 low  int
36                 high int
37                 want string
38         }{
39                 {"/src/fmt/print.go", 42, 30, 50, "/src/fmt/print.go?s=30:50#L32"},
40                 {"/src/fmt/print.go", 2, 1, 5, "/src/fmt/print.go?s=1:5#L1"},
41                 {"/src/fmt/print.go", 2, 0, 0, "/src/fmt/print.go#L2"},
42                 {"/src/fmt/print.go", 0, 0, 0, "/src/fmt/print.go"},
43                 {"/src/fmt/print.go", 0, 1, 5, "/src/fmt/print.go?s=1:5#L1"},
44                 {"fmt/print.go", 0, 0, 0, "/src/fmt/print.go"},
45                 {"fmt/print.go", 0, 1, 5, "/src/fmt/print.go?s=1:5#L1"},
46         } {
47                 if got := srcPosLinkFunc(tc.src, tc.line, tc.low, tc.high); got != tc.want {
48                         t.Errorf("srcLinkFunc(%v, %v, %v, %v) = %v; want %v", tc.src, tc.line, tc.low, tc.high, got, tc.want)
49                 }
50         }
51 }
52
53 func TestSrcLinkFunc(t *testing.T) {
54         for _, tc := range []struct {
55                 src  string
56                 want string
57         }{
58                 {"/src/fmt/print.go", "/src/fmt/print.go"},
59                 {"src/fmt/print.go", "/src/fmt/print.go"},
60                 {"/fmt/print.go", "/src/fmt/print.go"},
61                 {"fmt/print.go", "/src/fmt/print.go"},
62         } {
63                 if got := srcLinkFunc(tc.src); got != tc.want {
64                         t.Errorf("srcLinkFunc(%v) = %v; want %v", tc.src, got, tc.want)
65                 }
66         }
67 }
68
69 func TestQueryLinkFunc(t *testing.T) {
70         for _, tc := range []struct {
71                 src   string
72                 query string
73                 line  int
74                 want  string
75         }{
76                 {"/src/fmt/print.go", "Sprintf", 33, "/src/fmt/print.go?h=Sprintf#L33"},
77                 {"/src/fmt/print.go", "Sprintf", 0, "/src/fmt/print.go?h=Sprintf"},
78                 {"src/fmt/print.go", "EOF", 33, "/src/fmt/print.go?h=EOF#L33"},
79                 {"src/fmt/print.go", "a%3f+%26b", 1, "/src/fmt/print.go?h=a%3f+%26b#L1"},
80         } {
81                 if got := queryLinkFunc(tc.src, tc.query, tc.line); got != tc.want {
82                         t.Errorf("queryLinkFunc(%v, %v, %v) = %v; want %v", tc.src, tc.query, tc.line, got, tc.want)
83                 }
84         }
85 }
86
87 func TestDocLinkFunc(t *testing.T) {
88         for _, tc := range []struct {
89                 src   string
90                 ident string
91                 want  string
92         }{
93                 {"fmt", "Sprintf", "/pkg/fmt/#Sprintf"},
94                 {"fmt", "EOF", "/pkg/fmt/#EOF"},
95         } {
96                 if got := docLinkFunc(tc.src, tc.ident); got != tc.want {
97                         t.Errorf("docLinkFunc(%v, %v) = %v; want %v", tc.src, tc.ident, got, tc.want)
98                 }
99         }
100 }
101
102 func TestSanitizeFunc(t *testing.T) {
103         for _, tc := range []struct {
104                 src  string
105                 want string
106         }{
107                 {},
108                 {"foo", "foo"},
109                 {"func   f()", "func f()"},
110                 {"func f(a int,)", "func f(a int)"},
111                 {"func f(a int,\n)", "func f(a int)"},
112                 {"func f(\n\ta int,\n\tb int,\n\tc int,\n)", "func f(a int, b int, c int)"},
113                 {"  (   a,   b,  c  )  ", "(a, b, c)"},
114                 {"(  a,  b, c    int, foo   bar  ,  )", "(a, b, c int, foo bar)"},
115                 {"{   a,   b}", "{a, b}"},
116                 {"[   a,   b]", "[a, b]"},
117         } {
118                 if got := sanitizeFunc(tc.src); got != tc.want {
119                         t.Errorf("sanitizeFunc(%v) = %v; want %v", tc.src, got, tc.want)
120                 }
121         }
122 }
123
124 // Test that we add <span id="StructName.FieldName"> elements
125 // to the HTML of struct fields.
126 func TestStructFieldsIDAttributes(t *testing.T) {
127         got := linkifySource(t, []byte(`
128 package foo
129
130 type T struct {
131         NoDoc string
132
133         // Doc has a comment.
134         Doc string
135
136         // Opt, if non-nil, is an option.
137         Opt *int
138
139         // Опция - другое поле.
140         Опция bool
141 }
142 `))
143         want := `type T struct {
144 <span id="T.NoDoc"></span>NoDoc <a href="/pkg/builtin/#string">string</a>
145
146 <span id="T.Doc"></span><span class="comment">// Doc has a comment.</span>
147 Doc <a href="/pkg/builtin/#string">string</a>
148
149 <span id="T.Opt"></span><span class="comment">// Opt, if non-nil, is an option.</span>
150 Opt *<a href="/pkg/builtin/#int">int</a>
151
152 <span id="T.Опция"></span><span class="comment">// Опция - другое поле.</span>
153 Опция <a href="/pkg/builtin/#bool">bool</a>
154 }`
155         if got != want {
156                 t.Errorf("got: %s\n\nwant: %s\n", got, want)
157         }
158 }
159
160 // Test that we add <span id="ConstName"> elements to the HTML
161 // of definitions in const and var specs.
162 func TestValueSpecIDAttributes(t *testing.T) {
163         got := linkifySource(t, []byte(`
164 package foo
165
166 const (
167         NoDoc string = "NoDoc"
168
169         // Doc has a comment
170         Doc = "Doc"
171
172         NoVal
173 )`))
174         want := `const (
175 <span id="NoDoc">NoDoc</span> <a href="/pkg/builtin/#string">string</a> = &#34;NoDoc&#34;
176
177 <span class="comment">// Doc has a comment</span>
178 <span id="Doc">Doc</span> = &#34;Doc&#34;
179
180 <span id="NoVal">NoVal</span>
181 )`
182         if got != want {
183                 t.Errorf("got: %s\n\nwant: %s\n", got, want)
184         }
185 }
186
187 func TestCompositeLitLinkFields(t *testing.T) {
188         got := linkifySource(t, []byte(`
189 package foo
190
191 type T struct {
192         X int
193 }
194
195 var S T = T{X: 12}`))
196         want := `type T struct {
197 <span id="T.X"></span>X <a href="/pkg/builtin/#int">int</a>
198 }
199 var <span id="S">S</span> <a href="#T">T</a> = <a href="#T">T</a>{<a href="#T.X">X</a>: 12}`
200         if got != want {
201                 t.Errorf("got: %s\n\nwant: %s\n", got, want)
202         }
203 }
204
205 func TestFuncDeclNotLink(t *testing.T) {
206         // Function.
207         got := linkifySource(t, []byte(`
208 package http
209
210 func Get(url string) (resp *Response, err error)`))
211         want := `func Get(url <a href="/pkg/builtin/#string">string</a>) (resp *<a href="#Response">Response</a>, err <a href="/pkg/builtin/#error">error</a>)`
212         if got != want {
213                 t.Errorf("got: %s\n\nwant: %s\n", got, want)
214         }
215
216         // Method.
217         got = linkifySource(t, []byte(`
218 package http
219
220 func (h Header) Get(key string) string`))
221         want = `func (h <a href="#Header">Header</a>) Get(key <a href="/pkg/builtin/#string">string</a>) <a href="/pkg/builtin/#string">string</a>`
222         if got != want {
223                 t.Errorf("got: %s\n\nwant: %s\n", got, want)
224         }
225 }
226
227 func linkifySource(t *testing.T, src []byte) string {
228         p := &Presentation{
229                 DeclLinks: true,
230         }
231         fset := token.NewFileSet()
232         af, err := parser.ParseFile(fset, "foo.go", src, parser.ParseComments)
233         if err != nil {
234                 t.Fatal(err)
235         }
236         var buf bytes.Buffer
237         pi := &PageInfo{
238                 FSet: fset,
239         }
240         sep := ""
241         for _, decl := range af.Decls {
242                 buf.WriteString(sep)
243                 sep = "\n"
244                 buf.WriteString(p.node_htmlFunc(pi, decl, true))
245         }
246         return buf.String()
247 }
248
249 func TestScanIdentifier(t *testing.T) {
250         tests := []struct {
251                 in, want string
252         }{
253                 {"foo bar", "foo"},
254                 {"foo/bar", "foo"},
255                 {" foo", ""},
256                 {"фоо", "фоо"},
257                 {"f123", "f123"},
258                 {"123f", ""},
259         }
260         for _, tt := range tests {
261                 got := scanIdentifier([]byte(tt.in))
262                 if string(got) != tt.want {
263                         t.Errorf("scanIdentifier(%q) = %q; want %q", tt.in, got, tt.want)
264                 }
265         }
266 }
267
268 func TestReplaceLeadingIndentation(t *testing.T) {
269         oldIndent := strings.Repeat(" ", 2)
270         newIndent := strings.Repeat(" ", 4)
271         tests := []struct {
272                 src, want string
273         }{
274                 {"  foo\n    bar\n  baz", "    foo\n      bar\n    baz"},
275                 {"  '`'\n  '`'\n", "    '`'\n    '`'\n"},
276                 {"  '\\''\n  '`'\n", "    '\\''\n    '`'\n"},
277                 {"  \"`\"\n  \"`\"\n", "    \"`\"\n    \"`\"\n"},
278                 {"  `foo\n  bar`", "    `foo\n      bar`"},
279                 {"  `foo\\`\n  bar", "    `foo\\`\n    bar"},
280                 {"  '\\`'`foo\n  bar", "    '\\`'`foo\n      bar"},
281                 {
282                         "  if true {\n    foo := `One\n    \tTwo\nThree`\n  }\n",
283                         "    if true {\n      foo := `One\n        \tTwo\n    Three`\n    }\n",
284                 },
285         }
286         for _, tc := range tests {
287                 if got := replaceLeadingIndentation(tc.src, oldIndent, newIndent); got != tc.want {
288                         t.Errorf("replaceLeadingIndentation:\n%v\n---\nhave:\n%v\n---\nwant:\n%v\n",
289                                 tc.src, got, tc.want)
290                 }
291         }
292 }
293
294 func TestSrcBreadcrumbFunc(t *testing.T) {
295         for _, tc := range []struct {
296                 path string
297                 want string
298         }{
299                 {"src/", `<span class="text-muted">src/</span>`},
300                 {"src/fmt/", `<a href="/src">src</a>/<span class="text-muted">fmt/</span>`},
301                 {"src/fmt/print.go", `<a href="/src">src</a>/<a href="/src/fmt">fmt</a>/<span class="text-muted">print.go</span>`},
302         } {
303                 if got := srcBreadcrumbFunc(tc.path); got != tc.want {
304                         t.Errorf("srcBreadcrumbFunc(%v) = %v; want %v", tc.path, got, tc.want)
305                 }
306         }
307 }
308
309 func TestSrcToPkgLinkFunc(t *testing.T) {
310         for _, tc := range []struct {
311                 path string
312                 want string
313         }{
314                 {"src/", `<a href="/pkg">Index</a>`},
315                 {"src/fmt/", `<a href="/pkg/fmt">fmt</a>`},
316                 {"pkg/", `<a href="/pkg">Index</a>`},
317                 {"pkg/LICENSE", `<a href="/pkg">Index</a>`},
318         } {
319                 if got := srcToPkgLinkFunc(tc.path); got != tc.want {
320                         t.Errorf("srcToPkgLinkFunc(%v) = %v; want %v", tc.path, got, tc.want)
321                 }
322         }
323 }
324
325 func TestFilterOutBuildAnnotations(t *testing.T) {
326         // TODO: simplify this by using a multiline string once we stop
327         // using go vet from 1.10 on the build dashboard.
328         // https://golang.org/issue/26627
329         src := []byte("// +build !foo\n" +
330                 "// +build !anothertag\n" +
331                 "\n" +
332                 "// non-tag comment\n" +
333                 "\n" +
334                 "package foo\n" +
335                 "\n" +
336                 "func bar() int {\n" +
337                 "       return 42\n" +
338                 "}\n")
339
340         fset := token.NewFileSet()
341         af, err := parser.ParseFile(fset, "foo.go", src, parser.ParseComments)
342         if err != nil {
343                 t.Fatal(err)
344         }
345
346         var found bool
347         for _, cg := range af.Comments {
348                 if strings.HasPrefix(cg.Text(), "+build ") {
349                         found = true
350                         break
351                 }
352         }
353         if !found {
354                 t.Errorf("TestFilterOutBuildAnnotations is broken: missing build tag in test input")
355         }
356
357         found = false
358         for _, cg := range filterOutBuildAnnotations(af.Comments) {
359                 if strings.HasPrefix(cg.Text(), "+build ") {
360                         t.Errorf("filterOutBuildAnnotations failed to filter build tag")
361                 }
362
363                 if strings.Contains(cg.Text(), "non-tag comment") {
364                         found = true
365                 }
366         }
367         if !found {
368                 t.Errorf("filterOutBuildAnnotations should not remove non-build tag comment")
369         }
370 }