Source file
src/strconv/quote_test.go
Documentation: strconv
1
2
3
4
5 package strconv_test
6
7 import (
8 . "strconv"
9 "strings"
10 "testing"
11 "unicode"
12 )
13
14
15 func TestIsPrint(t *testing.T) {
16 n := 0
17 for r := rune(0); r <= unicode.MaxRune; r++ {
18 if IsPrint(r) != unicode.IsPrint(r) {
19 t.Errorf("IsPrint(%U)=%t incorrect", r, IsPrint(r))
20 n++
21 if n > 10 {
22 return
23 }
24 }
25 }
26 }
27
28
29 func TestIsGraphic(t *testing.T) {
30 n := 0
31 for r := rune(0); r <= unicode.MaxRune; r++ {
32 if IsGraphic(r) != unicode.IsGraphic(r) {
33 t.Errorf("IsGraphic(%U)=%t incorrect", r, IsGraphic(r))
34 n++
35 if n > 10 {
36 return
37 }
38 }
39 }
40 }
41
42 type quoteTest struct {
43 in string
44 out string
45 ascii string
46 graphic string
47 }
48
49 var quotetests = []quoteTest{
50 {"\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`},
51 {"\\", `"\\"`, `"\\"`, `"\\"`},
52 {"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`, `"abc\xffdef"`},
53 {"\u263a", `"☺"`, `"\u263a"`, `"☺"`},
54 {"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`, `"\U0010ffff"`},
55 {"\x04", `"\x04"`, `"\x04"`, `"\x04"`},
56
57 {"!\u00a0!\u2000!\u3000!", `"!\u00a0!\u2000!\u3000!"`, `"!\u00a0!\u2000!\u3000!"`, "\"!\u00a0!\u2000!\u3000!\""},
58 }
59
60 func TestQuote(t *testing.T) {
61 for _, tt := range quotetests {
62 if out := Quote(tt.in); out != tt.out {
63 t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out)
64 }
65 if out := AppendQuote([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
66 t.Errorf("AppendQuote(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
67 }
68 }
69 }
70
71 func TestQuoteToASCII(t *testing.T) {
72 for _, tt := range quotetests {
73 if out := QuoteToASCII(tt.in); out != tt.ascii {
74 t.Errorf("QuoteToASCII(%s) = %s, want %s", tt.in, out, tt.ascii)
75 }
76 if out := AppendQuoteToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
77 t.Errorf("AppendQuoteToASCII(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
78 }
79 }
80 }
81
82 func TestQuoteToGraphic(t *testing.T) {
83 for _, tt := range quotetests {
84 if out := QuoteToGraphic(tt.in); out != tt.graphic {
85 t.Errorf("QuoteToGraphic(%s) = %s, want %s", tt.in, out, tt.graphic)
86 }
87 if out := AppendQuoteToGraphic([]byte("abc"), tt.in); string(out) != "abc"+tt.graphic {
88 t.Errorf("AppendQuoteToGraphic(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.graphic)
89 }
90 }
91 }
92
93 func BenchmarkQuote(b *testing.B) {
94 for i := 0; i < b.N; i++ {
95 Quote("\a\b\f\r\n\t\v\a\b\f\r\n\t\v\a\b\f\r\n\t\v")
96 }
97 }
98
99 func BenchmarkQuoteRune(b *testing.B) {
100 for i := 0; i < b.N; i++ {
101 QuoteRune('\a')
102 }
103 }
104
105 var benchQuoteBuf []byte
106
107 func BenchmarkAppendQuote(b *testing.B) {
108 for i := 0; i < b.N; i++ {
109 benchQuoteBuf = AppendQuote(benchQuoteBuf[:0], "\a\b\f\r\n\t\v\a\b\f\r\n\t\v\a\b\f\r\n\t\v")
110 }
111 }
112
113 var benchQuoteRuneBuf []byte
114
115 func BenchmarkAppendQuoteRune(b *testing.B) {
116 for i := 0; i < b.N; i++ {
117 benchQuoteRuneBuf = AppendQuoteRune(benchQuoteRuneBuf[:0], '\a')
118 }
119 }
120
121 type quoteRuneTest struct {
122 in rune
123 out string
124 ascii string
125 graphic string
126 }
127
128 var quoterunetests = []quoteRuneTest{
129 {'a', `'a'`, `'a'`, `'a'`},
130 {'\a', `'\a'`, `'\a'`, `'\a'`},
131 {'\\', `'\\'`, `'\\'`, `'\\'`},
132 {0xFF, `'ÿ'`, `'\u00ff'`, `'ÿ'`},
133 {0x263a, `'☺'`, `'\u263a'`, `'☺'`},
134 {0xfffd, `'�'`, `'\ufffd'`, `'�'`},
135 {0x0010ffff, `'\U0010ffff'`, `'\U0010ffff'`, `'\U0010ffff'`},
136 {0x0010ffff + 1, `'�'`, `'\ufffd'`, `'�'`},
137 {0x04, `'\x04'`, `'\x04'`, `'\x04'`},
138
139 {'\u00a0', `'\u00a0'`, `'\u00a0'`, "'\u00a0'"},
140 {'\u2000', `'\u2000'`, `'\u2000'`, "'\u2000'"},
141 {'\u3000', `'\u3000'`, `'\u3000'`, "'\u3000'"},
142 }
143
144 func TestQuoteRune(t *testing.T) {
145 for _, tt := range quoterunetests {
146 if out := QuoteRune(tt.in); out != tt.out {
147 t.Errorf("QuoteRune(%U) = %s, want %s", tt.in, out, tt.out)
148 }
149 if out := AppendQuoteRune([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
150 t.Errorf("AppendQuoteRune(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
151 }
152 }
153 }
154
155 func TestQuoteRuneToASCII(t *testing.T) {
156 for _, tt := range quoterunetests {
157 if out := QuoteRuneToASCII(tt.in); out != tt.ascii {
158 t.Errorf("QuoteRuneToASCII(%U) = %s, want %s", tt.in, out, tt.ascii)
159 }
160 if out := AppendQuoteRuneToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
161 t.Errorf("AppendQuoteRuneToASCII(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
162 }
163 }
164 }
165
166 func TestQuoteRuneToGraphic(t *testing.T) {
167 for _, tt := range quoterunetests {
168 if out := QuoteRuneToGraphic(tt.in); out != tt.graphic {
169 t.Errorf("QuoteRuneToGraphic(%U) = %s, want %s", tt.in, out, tt.graphic)
170 }
171 if out := AppendQuoteRuneToGraphic([]byte("abc"), tt.in); string(out) != "abc"+tt.graphic {
172 t.Errorf("AppendQuoteRuneToGraphic(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.graphic)
173 }
174 }
175 }
176
177 type canBackquoteTest struct {
178 in string
179 out bool
180 }
181
182 var canbackquotetests = []canBackquoteTest{
183 {"`", false},
184 {string(rune(0)), false},
185 {string(rune(1)), false},
186 {string(rune(2)), false},
187 {string(rune(3)), false},
188 {string(rune(4)), false},
189 {string(rune(5)), false},
190 {string(rune(6)), false},
191 {string(rune(7)), false},
192 {string(rune(8)), false},
193 {string(rune(9)), true},
194 {string(rune(10)), false},
195 {string(rune(11)), false},
196 {string(rune(12)), false},
197 {string(rune(13)), false},
198 {string(rune(14)), false},
199 {string(rune(15)), false},
200 {string(rune(16)), false},
201 {string(rune(17)), false},
202 {string(rune(18)), false},
203 {string(rune(19)), false},
204 {string(rune(20)), false},
205 {string(rune(21)), false},
206 {string(rune(22)), false},
207 {string(rune(23)), false},
208 {string(rune(24)), false},
209 {string(rune(25)), false},
210 {string(rune(26)), false},
211 {string(rune(27)), false},
212 {string(rune(28)), false},
213 {string(rune(29)), false},
214 {string(rune(30)), false},
215 {string(rune(31)), false},
216 {string(rune(0x7F)), false},
217 {`' !"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, true},
218 {`0123456789`, true},
219 {`ABCDEFGHIJKLMNOPQRSTUVWXYZ`, true},
220 {`abcdefghijklmnopqrstuvwxyz`, true},
221 {`☺`, true},
222 {"\x80", false},
223 {"a\xe0\xa0z", false},
224 {"\ufeffabc", false},
225 {"a\ufeffz", false},
226 }
227
228 func TestCanBackquote(t *testing.T) {
229 for _, tt := range canbackquotetests {
230 if out := CanBackquote(tt.in); out != tt.out {
231 t.Errorf("CanBackquote(%q) = %v, want %v", tt.in, out, tt.out)
232 }
233 }
234 }
235
236 type unQuoteTest struct {
237 in string
238 out string
239 }
240
241 var unquotetests = []unQuoteTest{
242 {`""`, ""},
243 {`"a"`, "a"},
244 {`"abc"`, "abc"},
245 {`"☺"`, "☺"},
246 {`"hello world"`, "hello world"},
247 {`"\xFF"`, "\xFF"},
248 {`"\377"`, "\377"},
249 {`"\u1234"`, "\u1234"},
250 {`"\U00010111"`, "\U00010111"},
251 {`"\U0001011111"`, "\U0001011111"},
252 {`"\a\b\f\n\r\t\v\\\""`, "\a\b\f\n\r\t\v\\\""},
253 {`"'"`, "'"},
254
255 {`'a'`, "a"},
256 {`'☹'`, "☹"},
257 {`'\a'`, "\a"},
258 {`'\x10'`, "\x10"},
259 {`'\377'`, "\377"},
260 {`'\u1234'`, "\u1234"},
261 {`'\U00010111'`, "\U00010111"},
262 {`'\t'`, "\t"},
263 {`' '`, " "},
264 {`'\''`, "'"},
265 {`'"'`, "\""},
266
267 {"``", ``},
268 {"`a`", `a`},
269 {"`abc`", `abc`},
270 {"`☺`", `☺`},
271 {"`hello world`", `hello world`},
272 {"`\\xFF`", `\xFF`},
273 {"`\\377`", `\377`},
274 {"`\\`", `\`},
275 {"`\n`", "\n"},
276 {"` `", ` `},
277 {"` `", ` `},
278 {"`a\rb`", "ab"},
279 }
280
281 var misquoted = []string{
282 ``,
283 `"`,
284 `"a`,
285 `"'`,
286 `b"`,
287 `"\"`,
288 `"\9"`,
289 `"\19"`,
290 `"\129"`,
291 `'\'`,
292 `'\9'`,
293 `'\19'`,
294 `'\129'`,
295 `'ab'`,
296 `"\x1!"`,
297 `"\U12345678"`,
298 `"\z"`,
299 "`",
300 "`xxx",
301 "``x\r",
302 "`\"",
303 `"\'"`,
304 `'\"'`,
305 "\"\n\"",
306 "\"\\n\n\"",
307 "'\n'",
308 }
309
310 func TestUnquote(t *testing.T) {
311 for _, tt := range unquotetests {
312 testUnquote(t, tt.in, tt.out, nil)
313 }
314 for _, tt := range quotetests {
315 testUnquote(t, tt.out, tt.in, nil)
316 }
317 for _, s := range misquoted {
318 testUnquote(t, s, "", ErrSyntax)
319 }
320 }
321
322
323 func TestUnquoteInvalidUTF8(t *testing.T) {
324 tests := []struct {
325 in string
326
327
328 want string
329 wantErr error
330 }{
331 {in: `"foo"`, want: "foo"},
332 {in: `"foo`, wantErr: ErrSyntax},
333 {in: `"` + "\xc0" + `"`, want: "\xef\xbf\xbd"},
334 {in: `"a` + "\xc0" + `"`, want: "a\xef\xbf\xbd"},
335 {in: `"\t` + "\xc0" + `"`, want: "\t\xef\xbf\xbd"},
336 }
337 for _, tt := range tests {
338 testUnquote(t, tt.in, tt.want, tt.wantErr)
339 }
340 }
341
342 func testUnquote(t *testing.T, in, want string, wantErr error) {
343
344 got, gotErr := Unquote(in)
345 if got != want || gotErr != wantErr {
346 t.Errorf("Unquote(%q) = (%q, %v), want (%q, %v)", in, got, gotErr, want, wantErr)
347 }
348
349
350
351
352 if gotErr == nil {
353 want = in
354 }
355 suffix := "\n\r\\\"`'"
356 if len(in) > 0 {
357 suffix = strings.ReplaceAll(suffix, in[:1], "")
358 }
359 in += suffix
360 got, gotErr = QuotedPrefix(in)
361 if gotErr == nil && wantErr != nil {
362 _, wantErr = Unquote(got)
363 want = got
364 }
365 if got != want || gotErr != wantErr {
366 t.Errorf("QuotedPrefix(%q) = (%q, %v), want (%q, %v)", in, got, gotErr, want, wantErr)
367 }
368 }
369
370 func BenchmarkUnquoteEasy(b *testing.B) {
371 for i := 0; i < b.N; i++ {
372 Unquote(`"Give me a rock, paper and scissors and I will move the world."`)
373 }
374 }
375
376 func BenchmarkUnquoteHard(b *testing.B) {
377 for i := 0; i < b.N; i++ {
378 Unquote(`"\x47ive me a \x72ock, \x70aper and \x73cissors and \x49 will move the world."`)
379 }
380 }
381
View as plain text