blob: a4b5804fc89c9ca1cfdf49e10a990a71a0c2a1e4 [file] [log] [blame]
Russ Cox387df5e2008-11-24 14:51:33 -08001// Copyright 2009 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
Russ Cox3b864e42009-08-12 13:18:37 -07005package strconv_test
Russ Cox387df5e2008-11-24 14:51:33 -08006
7import (
Robert Griesemerd65a5cc2009-12-15 15:40:16 -08008 . "strconv"
9 "testing"
Rob Pikef91326b2012-03-07 13:50:31 +110010 "unicode"
Russ Cox387df5e2008-11-24 14:51:33 -080011)
12
Rob Pike74288f02015-09-02 15:08:24 -070013// Verify that our IsPrint agrees with unicode.IsPrint.
Rob Pikef91326b2012-03-07 13:50:31 +110014func TestIsPrint(t *testing.T) {
15 n := 0
16 for r := rune(0); r <= unicode.MaxRune; r++ {
17 if IsPrint(r) != unicode.IsPrint(r) {
18 t.Errorf("IsPrint(%U)=%t incorrect", r, IsPrint(r))
19 n++
20 if n > 10 {
21 return
22 }
23 }
24 }
25}
26
Rob Pike74288f02015-09-02 15:08:24 -070027// Verify that our IsGraphic agrees with unicode.IsGraphic.
28func TestIsGraphic(t *testing.T) {
29 n := 0
30 for r := rune(0); r <= unicode.MaxRune; r++ {
31 if IsGraphic(r) != unicode.IsGraphic(r) {
32 t.Errorf("IsGraphic(%U)=%t incorrect", r, IsGraphic(r))
33 n++
34 if n > 10 {
35 return
36 }
37 }
38 }
39}
40
Russ Cox8a7cbad2009-01-15 17:22:17 -080041type quoteTest struct {
Rob Pike74288f02015-09-02 15:08:24 -070042 in string
43 out string
44 ascii string
45 graphic string
Russ Cox387df5e2008-11-24 14:51:33 -080046}
47
Russ Cox91549432009-10-07 11:55:06 -070048var quotetests = []quoteTest{
Rob Pike74288f02015-09-02 15:08:24 -070049 {"\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"`},
50 {"\\", `"\\"`, `"\\"`, `"\\"`},
51 {"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`, `"abc\xffdef"`},
52 {"\u263a", `"☺"`, `"\u263a"`, `"☺"`},
53 {"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`, `"\U0010ffff"`},
54 {"\x04", `"\x04"`, `"\x04"`, `"\x04"`},
55 // Some non-printable but graphic runes. Final column is double-quoted.
56 {"!\u00a0!\u2000!\u3000!", `"!\u00a0!\u2000!\u3000!"`, `"!\u00a0!\u2000!\u3000!"`, "\"!\u00a0!\u2000!\u3000!\""},
Russ Coxbe2edb52009-03-03 08:39:12 -080057}
Russ Cox387df5e2008-11-24 14:51:33 -080058
Russ Cox839a6842009-01-20 14:40:40 -080059func TestQuote(t *testing.T) {
Rob Pikec4918db2011-05-25 15:04:07 +100060 for _, tt := range quotetests {
Russ Cox387df5e2008-11-24 14:51:33 -080061 if out := Quote(tt.in); out != tt.out {
Robert Griesemer40621d52009-11-09 12:07:39 -080062 t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out)
Russ Cox387df5e2008-11-24 14:51:33 -080063 }
Russ Coxefbeaed2011-12-05 15:48:21 -050064 if out := AppendQuote([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
65 t.Errorf("AppendQuote(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
66 }
Russ Cox387df5e2008-11-24 14:51:33 -080067 }
68}
69
Rob Pikef2f3b8f2011-06-07 12:23:08 +000070func TestQuoteToASCII(t *testing.T) {
71 for _, tt := range quotetests {
72 if out := QuoteToASCII(tt.in); out != tt.ascii {
73 t.Errorf("QuoteToASCII(%s) = %s, want %s", tt.in, out, tt.ascii)
74 }
Russ Coxefbeaed2011-12-05 15:48:21 -050075 if out := AppendQuoteToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
76 t.Errorf("AppendQuoteToASCII(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
77 }
Rob Pikef2f3b8f2011-06-07 12:23:08 +000078 }
79}
80
Rob Pike74288f02015-09-02 15:08:24 -070081func TestQuoteToGraphic(t *testing.T) {
82 for _, tt := range quotetests {
83 if out := QuoteToGraphic(tt.in); out != tt.graphic {
84 t.Errorf("QuoteToGraphic(%s) = %s, want %s", tt.in, out, tt.graphic)
85 }
86 if out := AppendQuoteToGraphic([]byte("abc"), tt.in); string(out) != "abc"+tt.graphic {
87 t.Errorf("AppendQuoteToGraphic(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.graphic)
88 }
89 }
90}
91
Justin Nuß9d73a6d2016-01-26 21:14:35 +010092func BenchmarkQuote(b *testing.B) {
93 for i := 0; i < b.N; i++ {
94 Quote("\a\b\f\r\n\t\v\a\b\f\r\n\t\v\a\b\f\r\n\t\v")
95 }
96}
97
98func BenchmarkQuoteRune(b *testing.B) {
99 for i := 0; i < b.N; i++ {
100 QuoteRune('\a')
101 }
102}
103
104var benchQuoteBuf []byte
105
106func BenchmarkAppendQuote(b *testing.B) {
107 for i := 0; i < b.N; i++ {
108 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")
109 }
110}
111
112var benchQuoteRuneBuf []byte
113
114func BenchmarkAppendQuoteRune(b *testing.B) {
115 for i := 0; i < b.N; i++ {
116 benchQuoteRuneBuf = AppendQuoteRune(benchQuoteRuneBuf[:0], '\a')
117 }
118}
119
Rob Pikec4918db2011-05-25 15:04:07 +1000120type quoteRuneTest struct {
Rob Pike74288f02015-09-02 15:08:24 -0700121 in rune
122 out string
123 ascii string
124 graphic string
Rob Pikec4918db2011-05-25 15:04:07 +1000125}
126
127var quoterunetests = []quoteRuneTest{
Rob Pike74288f02015-09-02 15:08:24 -0700128 {'a', `'a'`, `'a'`, `'a'`},
129 {'\a', `'\a'`, `'\a'`, `'\a'`},
130 {'\\', `'\\'`, `'\\'`, `'\\'`},
131 {0xFF, `'ÿ'`, `'\u00ff'`, `'ÿ'`},
132 {0x263a, `'☺'`, `'\u263a'`, `'☺'`},
133 {0xfffd, `'�'`, `'\ufffd'`, `'�'`},
134 {0x0010ffff, `'\U0010ffff'`, `'\U0010ffff'`, `'\U0010ffff'`},
135 {0x0010ffff + 1, `'�'`, `'\ufffd'`, `'�'`},
136 {0x04, `'\x04'`, `'\x04'`, `'\x04'`},
137 // Some differences between graphic and printable. Note the last column is double-quoted.
138 {'\u00a0', `'\u00a0'`, `'\u00a0'`, "'\u00a0'"},
139 {'\u2000', `'\u2000'`, `'\u2000'`, "'\u2000'"},
140 {'\u3000', `'\u3000'`, `'\u3000'`, "'\u3000'"},
Rob Pikec4918db2011-05-25 15:04:07 +1000141}
142
143func TestQuoteRune(t *testing.T) {
144 for _, tt := range quoterunetests {
145 if out := QuoteRune(tt.in); out != tt.out {
146 t.Errorf("QuoteRune(%U) = %s, want %s", tt.in, out, tt.out)
147 }
Russ Coxefbeaed2011-12-05 15:48:21 -0500148 if out := AppendQuoteRune([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
149 t.Errorf("AppendQuoteRune(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
150 }
Rob Pikec4918db2011-05-25 15:04:07 +1000151 }
152}
153
Rob Pikef2f3b8f2011-06-07 12:23:08 +0000154func TestQuoteRuneToASCII(t *testing.T) {
155 for _, tt := range quoterunetests {
156 if out := QuoteRuneToASCII(tt.in); out != tt.ascii {
157 t.Errorf("QuoteRuneToASCII(%U) = %s, want %s", tt.in, out, tt.ascii)
158 }
Russ Coxefbeaed2011-12-05 15:48:21 -0500159 if out := AppendQuoteRuneToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
160 t.Errorf("AppendQuoteRuneToASCII(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
161 }
Rob Pikef2f3b8f2011-06-07 12:23:08 +0000162 }
163}
164
Rob Pike74288f02015-09-02 15:08:24 -0700165func TestQuoteRuneToGraphic(t *testing.T) {
166 for _, tt := range quoterunetests {
167 if out := QuoteRuneToGraphic(tt.in); out != tt.graphic {
168 t.Errorf("QuoteRuneToGraphic(%U) = %s, want %s", tt.in, out, tt.graphic)
169 }
170 if out := AppendQuoteRuneToGraphic([]byte("abc"), tt.in); string(out) != "abc"+tt.graphic {
171 t.Errorf("AppendQuoteRuneToGraphic(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.graphic)
172 }
173 }
174}
175
Russ Cox8a7cbad2009-01-15 17:22:17 -0800176type canBackquoteTest struct {
Robert Griesemerd65a5cc2009-12-15 15:40:16 -0800177 in string
178 out bool
Russ Cox387df5e2008-11-24 14:51:33 -0800179}
180
Russ Cox91549432009-10-07 11:55:06 -0700181var canbackquotetests = []canBackquoteTest{
Robert Griesemer34788912010-10-22 10:06:33 -0700182 {"`", false},
183 {string(0), false},
184 {string(1), false},
185 {string(2), false},
186 {string(3), false},
187 {string(4), false},
188 {string(5), false},
189 {string(6), false},
190 {string(7), false},
191 {string(8), false},
192 {string(9), true}, // \t
193 {string(10), false},
194 {string(11), false},
195 {string(12), false},
196 {string(13), false},
197 {string(14), false},
198 {string(15), false},
199 {string(16), false},
200 {string(17), false},
201 {string(18), false},
202 {string(19), false},
203 {string(20), false},
204 {string(21), false},
205 {string(22), false},
206 {string(23), false},
207 {string(24), false},
208 {string(25), false},
209 {string(26), false},
210 {string(27), false},
211 {string(28), false},
212 {string(29), false},
213 {string(30), false},
214 {string(31), false},
Rob Pikef34251a2014-03-19 10:16:48 +1100215 {string(0x7F), false},
Robert Griesemer34788912010-10-22 10:06:33 -0700216 {`' !"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, true},
217 {`0123456789`, true},
218 {`ABCDEFGHIJKLMNOPQRSTUVWXYZ`, true},
219 {`abcdefghijklmnopqrstuvwxyz`, true},
220 {`☺`, true},
Volker Doblerc0a824a2014-07-14 19:49:26 -0700221 {"\x80", false},
222 {"a\xe0\xa0z", false},
Volker Dobler3b1b8402014-07-16 13:06:11 -0700223 {"\ufeffabc", false},
224 {"a\ufeffz", false},
Russ Coxbe2edb52009-03-03 08:39:12 -0800225}
Russ Cox387df5e2008-11-24 14:51:33 -0800226
Russ Cox839a6842009-01-20 14:40:40 -0800227func TestCanBackquote(t *testing.T) {
Rob Pikec4918db2011-05-25 15:04:07 +1000228 for _, tt := range canbackquotetests {
Russ Cox387df5e2008-11-24 14:51:33 -0800229 if out := CanBackquote(tt.in); out != tt.out {
Robert Griesemer40621d52009-11-09 12:07:39 -0800230 t.Errorf("CanBackquote(%q) = %v, want %v", tt.in, out, tt.out)
Russ Cox387df5e2008-11-24 14:51:33 -0800231 }
232 }
233}
Russ Cox73aadff2009-04-13 13:27:39 -0700234
Rob Pikef2f3b8f2011-06-07 12:23:08 +0000235type unQuoteTest struct {
236 in string
237 out string
238}
239
240var unquotetests = []unQuoteTest{
Robert Griesemer34788912010-10-22 10:06:33 -0700241 {`""`, ""},
242 {`"a"`, "a"},
243 {`"abc"`, "abc"},
244 {`"☺"`, "☺"},
245 {`"hello world"`, "hello world"},
246 {`"\xFF"`, "\xFF"},
247 {`"\377"`, "\377"},
248 {`"\u1234"`, "\u1234"},
249 {`"\U00010111"`, "\U00010111"},
250 {`"\U0001011111"`, "\U0001011111"},
251 {`"\a\b\f\n\r\t\v\\\""`, "\a\b\f\n\r\t\v\\\""},
252 {`"'"`, "'"},
Russ Cox73aadff2009-04-13 13:27:39 -0700253
Robert Griesemer34788912010-10-22 10:06:33 -0700254 {`'a'`, "a"},
255 {`'☹'`, "☹"},
256 {`'\a'`, "\a"},
257 {`'\x10'`, "\x10"},
258 {`'\377'`, "\377"},
259 {`'\u1234'`, "\u1234"},
260 {`'\U00010111'`, "\U00010111"},
261 {`'\t'`, "\t"},
262 {`' '`, " "},
263 {`'\''`, "'"},
264 {`'"'`, "\""},
Russ Cox73aadff2009-04-13 13:27:39 -0700265
Robert Griesemer34788912010-10-22 10:06:33 -0700266 {"``", ``},
267 {"`a`", `a`},
268 {"`abc`", `abc`},
269 {"`☺`", `☺`},
270 {"`hello world`", `hello world`},
271 {"`\\xFF`", `\xFF`},
272 {"`\\377`", `\377`},
273 {"`\\`", `\`},
Russ Coxba444d82011-09-26 13:59:12 -0400274 {"`\n`", "\n"},
Robert Griesemer34788912010-10-22 10:06:33 -0700275 {"` `", ` `},
276 {"` `", ` `},
Quentin Smith7c46f032016-10-14 15:13:30 -0400277 {"`a\rb`", "ab"},
Russ Cox73aadff2009-04-13 13:27:39 -0700278}
279
Russ Cox91549432009-10-07 11:55:06 -0700280var misquoted = []string{
Russ Cox73aadff2009-04-13 13:27:39 -0700281 ``,
282 `"`,
283 `"a`,
284 `"'`,
285 `b"`,
286 `"\"`,
Sameer Ajmanicbf4f4b2012-01-09 19:55:18 -0500287 `"\9"`,
288 `"\19"`,
289 `"\129"`,
Russ Cox73aadff2009-04-13 13:27:39 -0700290 `'\'`,
Sameer Ajmanicbf4f4b2012-01-09 19:55:18 -0500291 `'\9'`,
292 `'\19'`,
293 `'\129'`,
Russ Cox73aadff2009-04-13 13:27:39 -0700294 `'ab'`,
295 `"\x1!"`,
296 `"\U12345678"`,
297 `"\z"`,
298 "`",
299 "`xxx",
300 "`\"",
301 `"\'"`,
302 `'\"'`,
Russ Coxba444d82011-09-26 13:59:12 -0400303 "\"\n\"",
304 "\"\\n\n\"",
305 "'\n'",
Russ Cox73aadff2009-04-13 13:27:39 -0700306}
307
308func TestUnquote(t *testing.T) {
Rob Pikec4918db2011-05-25 15:04:07 +1000309 for _, tt := range unquotetests {
Quentin Smith7c46f032016-10-14 15:13:30 -0400310 if out, err := Unquote(tt.in); err != nil || out != tt.out {
Robert Griesemer40621d52009-11-09 12:07:39 -0800311 t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out)
Russ Cox73aadff2009-04-13 13:27:39 -0700312 }
313 }
314
315 // run the quote tests too, backward
Rob Pikec4918db2011-05-25 15:04:07 +1000316 for _, tt := range quotetests {
Russ Cox73aadff2009-04-13 13:27:39 -0700317 if in, err := Unquote(tt.out); in != tt.in {
Robert Griesemer40621d52009-11-09 12:07:39 -0800318 t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in)
Russ Cox73aadff2009-04-13 13:27:39 -0700319 }
320 }
321
Rob Pikec4918db2011-05-25 15:04:07 +1000322 for _, s := range misquoted {
Russ Coxc1178aa2011-10-27 19:46:31 -0700323 if out, err := Unquote(s); out != "" || err != ErrSyntax {
324 t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", ErrSyntax)
Russ Cox73aadff2009-04-13 13:27:39 -0700325 }
326 }
327}
Russ Coxba444d82011-09-26 13:59:12 -0400328
329func BenchmarkUnquoteEasy(b *testing.B) {
330 for i := 0; i < b.N; i++ {
331 Unquote(`"Give me a rock, paper and scissors and I will move the world."`)
332 }
333}
334
335func BenchmarkUnquoteHard(b *testing.B) {
336 for i := 0; i < b.N; i++ {
337 Unquote(`"\x47ive me a \x72ock, \x70aper and \x73cissors and \x49 will move the world."`)
338 }
339}