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