github.com/peggyl/go@v0.0.0-20151008231540-ae315999c2d5/src/strconv/quote_test.go (about)

     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  // Verify that our IsGraphic agrees with unicode.IsGraphic.
    28  func 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  
    41  type quoteTest struct {
    42  	in      string
    43  	out     string
    44  	ascii   string
    45  	graphic string
    46  }
    47  
    48  var quotetests = []quoteTest{
    49  	{"\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!\""},
    57  }
    58  
    59  func TestQuote(t *testing.T) {
    60  	for _, tt := range quotetests {
    61  		if out := Quote(tt.in); out != tt.out {
    62  			t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out)
    63  		}
    64  		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  		}
    67  	}
    68  }
    69  
    70  func 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  		}
    75  		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  		}
    78  	}
    79  }
    80  
    81  func 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  
    92  type quoteRuneTest struct {
    93  	in      rune
    94  	out     string
    95  	ascii   string
    96  	graphic string
    97  }
    98  
    99  var quoterunetests = []quoteRuneTest{
   100  	{'a', `'a'`, `'a'`, `'a'`},
   101  	{'\a', `'\a'`, `'\a'`, `'\a'`},
   102  	{'\\', `'\\'`, `'\\'`, `'\\'`},
   103  	{0xFF, `'ÿ'`, `'\u00ff'`, `'ÿ'`},
   104  	{0x263a, `'☺'`, `'\u263a'`, `'☺'`},
   105  	{0xfffd, `'�'`, `'\ufffd'`, `'�'`},
   106  	{0x0010ffff, `'\U0010ffff'`, `'\U0010ffff'`, `'\U0010ffff'`},
   107  	{0x0010ffff + 1, `'�'`, `'\ufffd'`, `'�'`},
   108  	{0x04, `'\x04'`, `'\x04'`, `'\x04'`},
   109  	// Some differences between graphic and printable. Note the last column is double-quoted.
   110  	{'\u00a0', `'\u00a0'`, `'\u00a0'`, "'\u00a0'"},
   111  	{'\u2000', `'\u2000'`, `'\u2000'`, "'\u2000'"},
   112  	{'\u3000', `'\u3000'`, `'\u3000'`, "'\u3000'"},
   113  }
   114  
   115  func TestQuoteRune(t *testing.T) {
   116  	for _, tt := range quoterunetests {
   117  		if out := QuoteRune(tt.in); out != tt.out {
   118  			t.Errorf("QuoteRune(%U) = %s, want %s", tt.in, out, tt.out)
   119  		}
   120  		if out := AppendQuoteRune([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
   121  			t.Errorf("AppendQuoteRune(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
   122  		}
   123  	}
   124  }
   125  
   126  func TestQuoteRuneToASCII(t *testing.T) {
   127  	for _, tt := range quoterunetests {
   128  		if out := QuoteRuneToASCII(tt.in); out != tt.ascii {
   129  			t.Errorf("QuoteRuneToASCII(%U) = %s, want %s", tt.in, out, tt.ascii)
   130  		}
   131  		if out := AppendQuoteRuneToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
   132  			t.Errorf("AppendQuoteRuneToASCII(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
   133  		}
   134  	}
   135  }
   136  
   137  func TestQuoteRuneToGraphic(t *testing.T) {
   138  	for _, tt := range quoterunetests {
   139  		if out := QuoteRuneToGraphic(tt.in); out != tt.graphic {
   140  			t.Errorf("QuoteRuneToGraphic(%U) = %s, want %s", tt.in, out, tt.graphic)
   141  		}
   142  		if out := AppendQuoteRuneToGraphic([]byte("abc"), tt.in); string(out) != "abc"+tt.graphic {
   143  			t.Errorf("AppendQuoteRuneToGraphic(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.graphic)
   144  		}
   145  	}
   146  }
   147  
   148  type canBackquoteTest struct {
   149  	in  string
   150  	out bool
   151  }
   152  
   153  var canbackquotetests = []canBackquoteTest{
   154  	{"`", false},
   155  	{string(0), false},
   156  	{string(1), false},
   157  	{string(2), false},
   158  	{string(3), false},
   159  	{string(4), false},
   160  	{string(5), false},
   161  	{string(6), false},
   162  	{string(7), false},
   163  	{string(8), false},
   164  	{string(9), true}, // \t
   165  	{string(10), false},
   166  	{string(11), false},
   167  	{string(12), false},
   168  	{string(13), false},
   169  	{string(14), false},
   170  	{string(15), false},
   171  	{string(16), false},
   172  	{string(17), false},
   173  	{string(18), false},
   174  	{string(19), false},
   175  	{string(20), false},
   176  	{string(21), false},
   177  	{string(22), false},
   178  	{string(23), false},
   179  	{string(24), false},
   180  	{string(25), false},
   181  	{string(26), false},
   182  	{string(27), false},
   183  	{string(28), false},
   184  	{string(29), false},
   185  	{string(30), false},
   186  	{string(31), false},
   187  	{string(0x7F), false},
   188  	{`' !"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, true},
   189  	{`0123456789`, true},
   190  	{`ABCDEFGHIJKLMNOPQRSTUVWXYZ`, true},
   191  	{`abcdefghijklmnopqrstuvwxyz`, true},
   192  	{`☺`, true},
   193  	{"\x80", false},
   194  	{"a\xe0\xa0z", false},
   195  	{"\ufeffabc", false},
   196  	{"a\ufeffz", false},
   197  }
   198  
   199  func TestCanBackquote(t *testing.T) {
   200  	for _, tt := range canbackquotetests {
   201  		if out := CanBackquote(tt.in); out != tt.out {
   202  			t.Errorf("CanBackquote(%q) = %v, want %v", tt.in, out, tt.out)
   203  		}
   204  	}
   205  }
   206  
   207  type unQuoteTest struct {
   208  	in  string
   209  	out string
   210  }
   211  
   212  var unquotetests = []unQuoteTest{
   213  	{`""`, ""},
   214  	{`"a"`, "a"},
   215  	{`"abc"`, "abc"},
   216  	{`"☺"`, "☺"},
   217  	{`"hello world"`, "hello world"},
   218  	{`"\xFF"`, "\xFF"},
   219  	{`"\377"`, "\377"},
   220  	{`"\u1234"`, "\u1234"},
   221  	{`"\U00010111"`, "\U00010111"},
   222  	{`"\U0001011111"`, "\U0001011111"},
   223  	{`"\a\b\f\n\r\t\v\\\""`, "\a\b\f\n\r\t\v\\\""},
   224  	{`"'"`, "'"},
   225  
   226  	{`'a'`, "a"},
   227  	{`'☹'`, "☹"},
   228  	{`'\a'`, "\a"},
   229  	{`'\x10'`, "\x10"},
   230  	{`'\377'`, "\377"},
   231  	{`'\u1234'`, "\u1234"},
   232  	{`'\U00010111'`, "\U00010111"},
   233  	{`'\t'`, "\t"},
   234  	{`' '`, " "},
   235  	{`'\''`, "'"},
   236  	{`'"'`, "\""},
   237  
   238  	{"``", ``},
   239  	{"`a`", `a`},
   240  	{"`abc`", `abc`},
   241  	{"`☺`", `☺`},
   242  	{"`hello world`", `hello world`},
   243  	{"`\\xFF`", `\xFF`},
   244  	{"`\\377`", `\377`},
   245  	{"`\\`", `\`},
   246  	{"`\n`", "\n"},
   247  	{"`	`", `	`},
   248  	{"` `", ` `},
   249  }
   250  
   251  var misquoted = []string{
   252  	``,
   253  	`"`,
   254  	`"a`,
   255  	`"'`,
   256  	`b"`,
   257  	`"\"`,
   258  	`"\9"`,
   259  	`"\19"`,
   260  	`"\129"`,
   261  	`'\'`,
   262  	`'\9'`,
   263  	`'\19'`,
   264  	`'\129'`,
   265  	`'ab'`,
   266  	`"\x1!"`,
   267  	`"\U12345678"`,
   268  	`"\z"`,
   269  	"`",
   270  	"`xxx",
   271  	"`\"",
   272  	`"\'"`,
   273  	`'\"'`,
   274  	"\"\n\"",
   275  	"\"\\n\n\"",
   276  	"'\n'",
   277  }
   278  
   279  func TestUnquote(t *testing.T) {
   280  	for _, tt := range unquotetests {
   281  		if out, err := Unquote(tt.in); err != nil && out != tt.out {
   282  			t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out)
   283  		}
   284  	}
   285  
   286  	// run the quote tests too, backward
   287  	for _, tt := range quotetests {
   288  		if in, err := Unquote(tt.out); in != tt.in {
   289  			t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in)
   290  		}
   291  	}
   292  
   293  	for _, s := range misquoted {
   294  		if out, err := Unquote(s); out != "" || err != ErrSyntax {
   295  			t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", ErrSyntax)
   296  		}
   297  	}
   298  }
   299  
   300  func BenchmarkUnquoteEasy(b *testing.B) {
   301  	for i := 0; i < b.N; i++ {
   302  		Unquote(`"Give me a rock, paper and scissors and I will move the world."`)
   303  	}
   304  }
   305  
   306  func BenchmarkUnquoteHard(b *testing.B) {
   307  	for i := 0; i < b.N; i++ {
   308  		Unquote(`"\x47ive me a \x72ock, \x70aper and \x73cissors and \x49 will move the world."`)
   309  	}
   310  }