Source file
src/go/doc/comment_test.go
1
2
3
4
5 package doc
6
7 import (
8 "bytes"
9 "reflect"
10 "strings"
11 "testing"
12 )
13
14 var headingTests = []struct {
15 line string
16 ok bool
17 }{
18 {"Section", true},
19 {"A typical usage", true},
20 {"ΔΛΞ is Greek", true},
21 {"Foo 42", true},
22 {"", false},
23 {"section", false},
24 {"A typical usage:", false},
25 {"This code:", false},
26 {"δ is Greek", false},
27 {"Foo §", false},
28 {"Fermat's Last Sentence", true},
29 {"Fermat's", true},
30 {"'sX", false},
31 {"Ted 'Too' Bar", false},
32 {"Use n+m", false},
33 {"Scanning:", false},
34 {"N:M", false},
35 }
36
37 func TestIsHeading(t *testing.T) {
38 for _, tt := range headingTests {
39 if h := heading(tt.line); (len(h) > 0) != tt.ok {
40 t.Errorf("isHeading(%q) = %v, want %v", tt.line, h, tt.ok)
41 }
42 }
43 }
44
45 var blocksTests = []struct {
46 in string
47 out []block
48 text string
49 }{
50 {
51 in: `Para 1.
52 Para 1 line 2.
53
54 Para 2.
55
56 Section
57
58 Para 3.
59
60 pre
61 pre1
62
63 Para 4.
64
65 pre
66 pre1
67
68 pre2
69
70 Para 5.
71
72
73 pre
74
75
76 pre1
77 pre2
78
79 Para 6.
80 pre
81 pre2
82 `,
83 out: []block{
84 {opPara, []string{"Para 1.\n", "Para 1 line 2.\n"}},
85 {opPara, []string{"Para 2.\n"}},
86 {opHead, []string{"Section"}},
87 {opPara, []string{"Para 3.\n"}},
88 {opPre, []string{"pre\n", "pre1\n"}},
89 {opPara, []string{"Para 4.\n"}},
90 {opPre, []string{"pre\n", "pre1\n", "\n", "pre2\n"}},
91 {opPara, []string{"Para 5.\n"}},
92 {opPre, []string{"pre\n", "\n", "\n", "pre1\n", "pre2\n"}},
93 {opPara, []string{"Para 6.\n"}},
94 {opPre, []string{"pre\n", "pre2\n"}},
95 },
96 text: `. Para 1. Para 1 line 2.
97
98 . Para 2.
99
100
101 . Section
102
103 . Para 3.
104
105 $ pre
106 $ pre1
107
108 . Para 4.
109
110 $ pre
111 $ pre1
112
113 $ pre2
114
115 . Para 5.
116
117 $ pre
118
119
120 $ pre1
121 $ pre2
122
123 . Para 6.
124
125 $ pre
126 $ pre2
127 `,
128 },
129 {
130 in: "Para.\n\tshould not be ``escaped''",
131 out: []block{
132 {opPara, []string{"Para.\n"}},
133 {opPre, []string{"should not be ``escaped''"}},
134 },
135 text: ". Para.\n\n$ should not be ``escaped''",
136 },
137 {
138 in: "// A very long line of 46 char for line wrapping.",
139 out: []block{
140 {opPara, []string{"// A very long line of 46 char for line wrapping."}},
141 },
142 text: `. // A very long line of 46 char for line
143 . // wrapping.
144 `,
145 },
146 {
147 in: `/* A very long line of 46 char for line wrapping.
148 A very long line of 46 char for line wrapping. */`,
149 out: []block{
150 {opPara, []string{"/* A very long line of 46 char for line wrapping.\n", "A very long line of 46 char for line wrapping. */"}},
151 },
152 text: `. /* A very long line of 46 char for line
153 . wrapping. A very long line of 46 char
154 . for line wrapping. */
155 `,
156 },
157 {
158 in: `A line of 36 char for line wrapping.
159 //Another line starting with //`,
160 out: []block{
161 {opPara, []string{"A line of 36 char for line wrapping.\n",
162 "//Another line starting with //"}},
163 },
164 text: `. A line of 36 char for line wrapping.
165 . //Another line starting with //
166 `,
167 },
168 }
169
170 func TestBlocks(t *testing.T) {
171 for i, tt := range blocksTests {
172 b := blocks(tt.in)
173 if !reflect.DeepEqual(b, tt.out) {
174 t.Errorf("#%d: mismatch\nhave: %v\nwant: %v", i, b, tt.out)
175 }
176 }
177 }
178
179 func TestToText(t *testing.T) {
180 var buf bytes.Buffer
181 for i, tt := range blocksTests {
182 ToText(&buf, tt.in, ". ", "$\t", 40)
183 if have := buf.String(); have != tt.text {
184 t.Errorf("#%d: mismatch\nhave: %s\nwant: %s\nhave vs want:\n%q\n%q", i, have, tt.text, have, tt.text)
185 }
186 buf.Reset()
187 }
188 }
189
190 var emphasizeTests = []struct {
191 in, out string
192 }{
193 {"", ""},
194 {"http://[::1]:8080/foo.txt", `<a href="http://[::1]:8080/foo.txt">http://[::1]:8080/foo.txt</a>`},
195 {"before (https://www.google.com) after", `before (<a href="https://www.google.com">https://www.google.com</a>) after`},
196 {"before https://www.google.com:30/x/y/z:b::c. After", `before <a href="https://www.google.com:30/x/y/z:b::c">https://www.google.com:30/x/y/z:b::c</a>. After`},
197 {"http://www.google.com/path/:;!-/?query=%34b#093124", `<a href="http://www.google.com/path/:;!-/?query=%34b#093124">http://www.google.com/path/:;!-/?query=%34b#093124</a>`},
198 {"http://www.google.com/path/:;!-/?query=%34bar#093124", `<a href="http://www.google.com/path/:;!-/?query=%34bar#093124">http://www.google.com/path/:;!-/?query=%34bar#093124</a>`},
199 {"http://www.google.com/index.html! After", `<a href="http://www.google.com/index.html">http://www.google.com/index.html</a>! After`},
200 {"http://www.google.com/", `<a href="http://www.google.com/">http://www.google.com/</a>`},
201 {"https://www.google.com/", `<a href="https://www.google.com/">https://www.google.com/</a>`},
202 {"http://www.google.com/path.", `<a href="http://www.google.com/path">http://www.google.com/path</a>.`},
203 {"http://en.wikipedia.org/wiki/Camellia_(cipher)", `<a href="http://en.wikipedia.org/wiki/Camellia_(cipher)">http://en.wikipedia.org/wiki/Camellia_(cipher)</a>`},
204 {"(http://www.google.com/)", `(<a href="http://www.google.com/">http://www.google.com/</a>)`},
205 {"http://gmail.com)", `<a href="http://gmail.com">http://gmail.com</a>)`},
206 {"((http://gmail.com))", `((<a href="http://gmail.com">http://gmail.com</a>))`},
207 {"http://gmail.com ((http://gmail.com)) ()", `<a href="http://gmail.com">http://gmail.com</a> ((<a href="http://gmail.com">http://gmail.com</a>)) ()`},
208 {"Foo bar http://example.com/ quux!", `Foo bar <a href="http://example.com/">http://example.com/</a> quux!`},
209 {"Hello http://example.com/%2f/ /world.", `Hello <a href="http://example.com/%2f/">http://example.com/%2f/</a> /world.`},
210 {"Lorem http: ipsum //host/path", "Lorem http: ipsum //host/path"},
211 {"javascript://is/not/linked", "javascript://is/not/linked"},
212 {"http://foo", `<a href="http://foo">http://foo</a>`},
213 {"art by [[https://www.example.com/person/][Person Name]]", `art by [[<a href="https://www.example.com/person/">https://www.example.com/person/</a>][Person Name]]`},
214 {"please visit (http://golang.org/)", `please visit (<a href="http://golang.org/">http://golang.org/</a>)`},
215 {"please visit http://golang.org/hello())", `please visit <a href="http://golang.org/hello()">http://golang.org/hello()</a>)`},
216 {"http://git.qemu.org/?p=qemu.git;a=blob;f=qapi-schema.json;hb=HEAD", `<a href="http://git.qemu.org/?p=qemu.git;a=blob;f=qapi-schema.json;hb=HEAD">http://git.qemu.org/?p=qemu.git;a=blob;f=qapi-schema.json;hb=HEAD</a>`},
217 {"https://foo.bar/bal/x(])", `<a href="https://foo.bar/bal/x(">https://foo.bar/bal/x(</a>])`},
218 {"foo [ http://bar(])", `foo [ <a href="http://bar(">http://bar(</a>])`},
219 }
220
221 func TestEmphasize(t *testing.T) {
222 for i, tt := range emphasizeTests {
223 var buf bytes.Buffer
224 emphasize(&buf, tt.in, nil, true)
225 out := buf.String()
226 if out != tt.out {
227 t.Errorf("#%d: mismatch\nhave: %v\nwant: %v", i, out, tt.out)
228 }
229 }
230 }
231
232 func TestCommentEscape(t *testing.T) {
233 commentTests := []struct {
234 in, out string
235 }{
236 {"typically invoked as ``go tool asm'',", "typically invoked as " + ldquo + "go tool asm" + rdquo + ","},
237 {"For more detail, run ``go help test'' and ``go help testflag''", "For more detail, run " + ldquo + "go help test" + rdquo + " and " + ldquo + "go help testflag" + rdquo},
238 }
239 for i, tt := range commentTests {
240 var buf strings.Builder
241 commentEscape(&buf, tt.in, true)
242 out := buf.String()
243 if out != tt.out {
244 t.Errorf("#%d: mismatch\nhave: %q\nwant: %q", i, out, tt.out)
245 }
246 }
247 }
248
View as plain text