Home | History | Annotate | Download | only in strconv
      1 // 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 
      5 package strconv_test
      6 
      7 import (
      8 	. "strconv"
      9 	"testing"
     10 	"unicode"
     11 )
     12 
     13 // Verify that our isPrint agrees with unicode.IsPrint
     14 func 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 
     27 type quoteTest struct {
     28 	in    string
     29 	out   string
     30 	ascii string
     31 }
     32 
     33 var quotetests = []quoteTest{
     34 	{"\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`},
     35 	{"\\", `"\\"`, `"\\"`},
     36 	{"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`},
     37 	{"\u263a", `""`, `"\u263a"`},
     38 	{"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`},
     39 	{"\x04", `"\x04"`, `"\x04"`},
     40 }
     41 
     42 func TestQuote(t *testing.T) {
     43 	for _, tt := range quotetests {
     44 		if out := Quote(tt.in); out != tt.out {
     45 			t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out)
     46 		}
     47 		if out := AppendQuote([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
     48 			t.Errorf("AppendQuote(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
     49 		}
     50 	}
     51 }
     52 
     53 func TestQuoteToASCII(t *testing.T) {
     54 	for _, tt := range quotetests {
     55 		if out := QuoteToASCII(tt.in); out != tt.ascii {
     56 			t.Errorf("QuoteToASCII(%s) = %s, want %s", tt.in, out, tt.ascii)
     57 		}
     58 		if out := AppendQuoteToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
     59 			t.Errorf("AppendQuoteToASCII(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
     60 		}
     61 	}
     62 }
     63 
     64 type quoteRuneTest struct {
     65 	in    rune
     66 	out   string
     67 	ascii string
     68 }
     69 
     70 var quoterunetests = []quoteRuneTest{
     71 	{'a', `'a'`, `'a'`},
     72 	{'\a', `'\a'`, `'\a'`},
     73 	{'\\', `'\\'`, `'\\'`},
     74 	{0xFF, `''`, `'\u00ff'`},
     75 	{0x263a, `''`, `'\u263a'`},
     76 	{0xfffd, `''`, `'\ufffd'`},
     77 	{0x0010ffff, `'\U0010ffff'`, `'\U0010ffff'`},
     78 	{0x0010ffff + 1, `''`, `'\ufffd'`},
     79 	{0x04, `'\x04'`, `'\x04'`},
     80 }
     81 
     82 func TestQuoteRune(t *testing.T) {
     83 	for _, tt := range quoterunetests {
     84 		if out := QuoteRune(tt.in); out != tt.out {
     85 			t.Errorf("QuoteRune(%U) = %s, want %s", tt.in, out, tt.out)
     86 		}
     87 		if out := AppendQuoteRune([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
     88 			t.Errorf("AppendQuoteRune(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
     89 		}
     90 	}
     91 }
     92 
     93 func TestQuoteRuneToASCII(t *testing.T) {
     94 	for _, tt := range quoterunetests {
     95 		if out := QuoteRuneToASCII(tt.in); out != tt.ascii {
     96 			t.Errorf("QuoteRuneToASCII(%U) = %s, want %s", tt.in, out, tt.ascii)
     97 		}
     98 		if out := AppendQuoteRuneToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
     99 			t.Errorf("AppendQuoteRuneToASCII(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
    100 		}
    101 	}
    102 }
    103 
    104 type canBackquoteTest struct {
    105 	in  string
    106 	out bool
    107 }
    108 
    109 var canbackquotetests = []canBackquoteTest{
    110 	{"`", false},
    111 	{string(0), false},
    112 	{string(1), false},
    113 	{string(2), false},
    114 	{string(3), false},
    115 	{string(4), false},
    116 	{string(5), false},
    117 	{string(6), false},
    118 	{string(7), false},
    119 	{string(8), false},
    120 	{string(9), true}, // \t
    121 	{string(10), false},
    122 	{string(11), false},
    123 	{string(12), false},
    124 	{string(13), false},
    125 	{string(14), false},
    126 	{string(15), false},
    127 	{string(16), false},
    128 	{string(17), false},
    129 	{string(18), false},
    130 	{string(19), false},
    131 	{string(20), false},
    132 	{string(21), false},
    133 	{string(22), false},
    134 	{string(23), false},
    135 	{string(24), false},
    136 	{string(25), false},
    137 	{string(26), false},
    138 	{string(27), false},
    139 	{string(28), false},
    140 	{string(29), false},
    141 	{string(30), false},
    142 	{string(31), false},
    143 	{string(0x7F), false},
    144 	{`' !"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, true},
    145 	{`0123456789`, true},
    146 	{`ABCDEFGHIJKLMNOPQRSTUVWXYZ`, true},
    147 	{`abcdefghijklmnopqrstuvwxyz`, true},
    148 	{``, true},
    149 	{"\x80", false},
    150 	{"a\xe0\xa0z", false},
    151 	{"\ufeffabc", false},
    152 	{"a\ufeffz", false},
    153 }
    154 
    155 func TestCanBackquote(t *testing.T) {
    156 	for _, tt := range canbackquotetests {
    157 		if out := CanBackquote(tt.in); out != tt.out {
    158 			t.Errorf("CanBackquote(%q) = %v, want %v", tt.in, out, tt.out)
    159 		}
    160 	}
    161 }
    162 
    163 type unQuoteTest struct {
    164 	in  string
    165 	out string
    166 }
    167 
    168 var unquotetests = []unQuoteTest{
    169 	{`""`, ""},
    170 	{`"a"`, "a"},
    171 	{`"abc"`, "abc"},
    172 	{`""`, ""},
    173 	{`"hello world"`, "hello world"},
    174 	{`"\xFF"`, "\xFF"},
    175 	{`"\377"`, "\377"},
    176 	{`"\u1234"`, "\u1234"},
    177 	{`"\U00010111"`, "\U00010111"},
    178 	{`"\U0001011111"`, "\U0001011111"},
    179 	{`"\a\b\f\n\r\t\v\\\""`, "\a\b\f\n\r\t\v\\\""},
    180 	{`"'"`, "'"},
    181 
    182 	{`'a'`, "a"},
    183 	{`''`, ""},
    184 	{`'\a'`, "\a"},
    185 	{`'\x10'`, "\x10"},
    186 	{`'\377'`, "\377"},
    187 	{`'\u1234'`, "\u1234"},
    188 	{`'\U00010111'`, "\U00010111"},
    189 	{`'\t'`, "\t"},
    190 	{`' '`, " "},
    191 	{`'\''`, "'"},
    192 	{`'"'`, "\""},
    193 
    194 	{"``", ``},
    195 	{"`a`", `a`},
    196 	{"`abc`", `abc`},
    197 	{"``", ``},
    198 	{"`hello world`", `hello world`},
    199 	{"`\\xFF`", `\xFF`},
    200 	{"`\\377`", `\377`},
    201 	{"`\\`", `\`},
    202 	{"`\n`", "\n"},
    203 	{"`	`", `	`},
    204 	{"` `", ` `},
    205 }
    206 
    207 var misquoted = []string{
    208 	``,
    209 	`"`,
    210 	`"a`,
    211 	`"'`,
    212 	`b"`,
    213 	`"\"`,
    214 	`"\9"`,
    215 	`"\19"`,
    216 	`"\129"`,
    217 	`'\'`,
    218 	`'\9'`,
    219 	`'\19'`,
    220 	`'\129'`,
    221 	`'ab'`,
    222 	`"\x1!"`,
    223 	`"\U12345678"`,
    224 	`"\z"`,
    225 	"`",
    226 	"`xxx",
    227 	"`\"",
    228 	`"\'"`,
    229 	`'\"'`,
    230 	"\"\n\"",
    231 	"\"\\n\n\"",
    232 	"'\n'",
    233 }
    234 
    235 func TestUnquote(t *testing.T) {
    236 	for _, tt := range unquotetests {
    237 		if out, err := Unquote(tt.in); err != nil && out != tt.out {
    238 			t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out)
    239 		}
    240 	}
    241 
    242 	// run the quote tests too, backward
    243 	for _, tt := range quotetests {
    244 		if in, err := Unquote(tt.out); in != tt.in {
    245 			t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in)
    246 		}
    247 	}
    248 
    249 	for _, s := range misquoted {
    250 		if out, err := Unquote(s); out != "" || err != ErrSyntax {
    251 			t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", ErrSyntax)
    252 		}
    253 	}
    254 }
    255 
    256 func BenchmarkUnquoteEasy(b *testing.B) {
    257 	for i := 0; i < b.N; i++ {
    258 		Unquote(`"Give me a rock, paper and scissors and I will move the world."`)
    259 	}
    260 }
    261 
    262 func BenchmarkUnquoteHard(b *testing.B) {
    263 	for i := 0; i < b.N; i++ {
    264 		Unquote(`"\x47ive me a \x72ock, \x70aper and \x73cissors and \x49 will move the world."`)
    265 	}
    266 }
    267