Home | History | Annotate | Download | only in strings
      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 strings_test
      6 
      7 import (
      8 	"bytes"
      9 	"io"
     10 	"math/rand"
     11 	"reflect"
     12 	. "strings"
     13 	"testing"
     14 	"unicode"
     15 	"unicode/utf8"
     16 	"unsafe"
     17 )
     18 
     19 func eq(a, b []string) bool {
     20 	if len(a) != len(b) {
     21 		return false
     22 	}
     23 	for i := 0; i < len(a); i++ {
     24 		if a[i] != b[i] {
     25 			return false
     26 		}
     27 	}
     28 	return true
     29 }
     30 
     31 var abcd = "abcd"
     32 var faces = ""
     33 var commas = "1,2,3,4"
     34 var dots = "1....2....3....4"
     35 
     36 type IndexTest struct {
     37 	s   string
     38 	sep string
     39 	out int
     40 }
     41 
     42 var indexTests = []IndexTest{
     43 	{"", "", 0},
     44 	{"", "a", -1},
     45 	{"", "foo", -1},
     46 	{"fo", "foo", -1},
     47 	{"foo", "foo", 0},
     48 	{"oofofoofooo", "f", 2},
     49 	{"oofofoofooo", "foo", 4},
     50 	{"barfoobarfoo", "foo", 3},
     51 	{"foo", "", 0},
     52 	{"foo", "o", 1},
     53 	{"abcABCabc", "A", 3},
     54 	// cases with one byte strings - test special case in Index()
     55 	{"", "a", -1},
     56 	{"x", "a", -1},
     57 	{"x", "x", 0},
     58 	{"abc", "a", 0},
     59 	{"abc", "b", 1},
     60 	{"abc", "c", 2},
     61 	{"abc", "x", -1},
     62 }
     63 
     64 var lastIndexTests = []IndexTest{
     65 	{"", "", 0},
     66 	{"", "a", -1},
     67 	{"", "foo", -1},
     68 	{"fo", "foo", -1},
     69 	{"foo", "foo", 0},
     70 	{"foo", "f", 0},
     71 	{"oofofoofooo", "f", 7},
     72 	{"oofofoofooo", "foo", 7},
     73 	{"barfoobarfoo", "foo", 9},
     74 	{"foo", "", 3},
     75 	{"foo", "o", 2},
     76 	{"abcABCabc", "A", 3},
     77 	{"abcABCabc", "a", 6},
     78 }
     79 
     80 var indexAnyTests = []IndexTest{
     81 	{"", "", -1},
     82 	{"", "a", -1},
     83 	{"", "abc", -1},
     84 	{"a", "", -1},
     85 	{"a", "a", 0},
     86 	{"aaa", "a", 0},
     87 	{"abc", "xyz", -1},
     88 	{"abc", "xcz", 2},
     89 	{"abcd", "uvwxyz", 2 + len("")},
     90 	{"aRegExp*", ".(|)*+?^$[]", 7},
     91 	{dots + dots + dots, " ", -1},
     92 }
     93 var lastIndexAnyTests = []IndexTest{
     94 	{"", "", -1},
     95 	{"", "a", -1},
     96 	{"", "abc", -1},
     97 	{"a", "", -1},
     98 	{"a", "a", 0},
     99 	{"aaa", "a", 2},
    100 	{"abc", "xyz", -1},
    101 	{"abc", "ab", 1},
    102 	{"abcd", "uvwxyz", 2 + len("")},
    103 	{"a.RegExp*", ".(|)*+?^$[]", 8},
    104 	{dots + dots + dots, " ", -1},
    105 }
    106 
    107 // Execute f on each test case.  funcName should be the name of f; it's used
    108 // in failure reports.
    109 func runIndexTests(t *testing.T, f func(s, sep string) int, funcName string, testCases []IndexTest) {
    110 	for _, test := range testCases {
    111 		actual := f(test.s, test.sep)
    112 		if actual != test.out {
    113 			t.Errorf("%s(%q,%q) = %v; want %v", funcName, test.s, test.sep, actual, test.out)
    114 		}
    115 	}
    116 }
    117 
    118 func TestIndex(t *testing.T)        { runIndexTests(t, Index, "Index", indexTests) }
    119 func TestLastIndex(t *testing.T)    { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
    120 func TestIndexAny(t *testing.T)     { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) }
    121 func TestLastIndexAny(t *testing.T) { runIndexTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests) }
    122 
    123 func TestLastIndexByte(t *testing.T) {
    124 	testCases := []IndexTest{
    125 		{"", "q", -1},
    126 		{"abcdef", "q", -1},
    127 		{"abcdefabcdef", "a", len("abcdef")},      // something in the middle
    128 		{"abcdefabcdef", "f", len("abcdefabcde")}, // last byte
    129 		{"zabcdefabcdef", "z", 0},                 // first byte
    130 		{"abcd", "b", len("a")},               // non-ascii
    131 	}
    132 	for _, test := range testCases {
    133 		actual := LastIndexByte(test.s, test.sep[0])
    134 		if actual != test.out {
    135 			t.Errorf("LastIndexByte(%q,%c) = %v; want %v", test.s, test.sep[0], actual, test.out)
    136 		}
    137 	}
    138 }
    139 
    140 var indexRuneTests = []struct {
    141 	s    string
    142 	rune rune
    143 	out  int
    144 }{
    145 	{"a A x", 'A', 2},
    146 	{"some_text=some_value", '=', 9},
    147 	{"a", 'a', 3},
    148 	{"ab", '', 4},
    149 }
    150 
    151 func TestIndexRune(t *testing.T) {
    152 	for _, test := range indexRuneTests {
    153 		if actual := IndexRune(test.s, test.rune); actual != test.out {
    154 			t.Errorf("IndexRune(%q,%d)= %v; want %v", test.s, test.rune, actual, test.out)
    155 		}
    156 	}
    157 }
    158 
    159 const benchmarkString = "some_text=somevalue"
    160 
    161 func BenchmarkIndexRune(b *testing.B) {
    162 	if got := IndexRune(benchmarkString, ''); got != 14 {
    163 		b.Fatalf("wrong index: expected 14, got=%d", got)
    164 	}
    165 	for i := 0; i < b.N; i++ {
    166 		IndexRune(benchmarkString, '')
    167 	}
    168 }
    169 
    170 func BenchmarkIndexRuneFastPath(b *testing.B) {
    171 	if got := IndexRune(benchmarkString, 'v'); got != 17 {
    172 		b.Fatalf("wrong index: expected 17, got=%d", got)
    173 	}
    174 	for i := 0; i < b.N; i++ {
    175 		IndexRune(benchmarkString, 'v')
    176 	}
    177 }
    178 
    179 func BenchmarkIndex(b *testing.B) {
    180 	if got := Index(benchmarkString, "v"); got != 17 {
    181 		b.Fatalf("wrong index: expected 17, got=%d", got)
    182 	}
    183 	for i := 0; i < b.N; i++ {
    184 		Index(benchmarkString, "v")
    185 	}
    186 }
    187 
    188 func BenchmarkLastIndex(b *testing.B) {
    189 	if got := Index(benchmarkString, "v"); got != 17 {
    190 		b.Fatalf("wrong index: expected 17, got=%d", got)
    191 	}
    192 	for i := 0; i < b.N; i++ {
    193 		LastIndex(benchmarkString, "v")
    194 	}
    195 }
    196 
    197 func BenchmarkIndexByte(b *testing.B) {
    198 	if got := IndexByte(benchmarkString, 'v'); got != 17 {
    199 		b.Fatalf("wrong index: expected 17, got=%d", got)
    200 	}
    201 	for i := 0; i < b.N; i++ {
    202 		IndexByte(benchmarkString, 'v')
    203 	}
    204 }
    205 
    206 var explodetests = []struct {
    207 	s string
    208 	n int
    209 	a []string
    210 }{
    211 	{"", -1, []string{}},
    212 	{abcd, 4, []string{"a", "b", "c", "d"}},
    213 	{faces, 3, []string{"", "", ""}},
    214 	{abcd, 2, []string{"a", "bcd"}},
    215 }
    216 
    217 func TestExplode(t *testing.T) {
    218 	for _, tt := range explodetests {
    219 		a := SplitN(tt.s, "", tt.n)
    220 		if !eq(a, tt.a) {
    221 			t.Errorf("explode(%q, %d) = %v; want %v", tt.s, tt.n, a, tt.a)
    222 			continue
    223 		}
    224 		s := Join(a, "")
    225 		if s != tt.s {
    226 			t.Errorf(`Join(explode(%q, %d), "") = %q`, tt.s, tt.n, s)
    227 		}
    228 	}
    229 }
    230 
    231 type SplitTest struct {
    232 	s   string
    233 	sep string
    234 	n   int
    235 	a   []string
    236 }
    237 
    238 var splittests = []SplitTest{
    239 	{abcd, "a", 0, nil},
    240 	{abcd, "a", -1, []string{"", "bcd"}},
    241 	{abcd, "z", -1, []string{"abcd"}},
    242 	{abcd, "", -1, []string{"a", "b", "c", "d"}},
    243 	{commas, ",", -1, []string{"1", "2", "3", "4"}},
    244 	{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
    245 	{faces, "", -1, []string{"", ""}},
    246 	{faces, "~", -1, []string{faces}},
    247 	{faces, "", -1, []string{"", "", ""}},
    248 	{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
    249 	{"1 2", " ", 3, []string{"1", "2"}},
    250 	{"123", "", 2, []string{"1", "23"}},
    251 	{"123", "", 17, []string{"1", "2", "3"}},
    252 }
    253 
    254 func TestSplit(t *testing.T) {
    255 	for _, tt := range splittests {
    256 		a := SplitN(tt.s, tt.sep, tt.n)
    257 		if !eq(a, tt.a) {
    258 			t.Errorf("Split(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, a, tt.a)
    259 			continue
    260 		}
    261 		if tt.n == 0 {
    262 			continue
    263 		}
    264 		s := Join(a, tt.sep)
    265 		if s != tt.s {
    266 			t.Errorf("Join(Split(%q, %q, %d), %q) = %q", tt.s, tt.sep, tt.n, tt.sep, s)
    267 		}
    268 		if tt.n < 0 {
    269 			b := Split(tt.s, tt.sep)
    270 			if !reflect.DeepEqual(a, b) {
    271 				t.Errorf("Split disagrees with SplitN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
    272 			}
    273 		}
    274 	}
    275 }
    276 
    277 var splitaftertests = []SplitTest{
    278 	{abcd, "a", -1, []string{"a", "bcd"}},
    279 	{abcd, "z", -1, []string{"abcd"}},
    280 	{abcd, "", -1, []string{"a", "b", "c", "d"}},
    281 	{commas, ",", -1, []string{"1,", "2,", "3,", "4"}},
    282 	{dots, "...", -1, []string{"1...", ".2...", ".3...", ".4"}},
    283 	{faces, "", -1, []string{"", ""}},
    284 	{faces, "~", -1, []string{faces}},
    285 	{faces, "", -1, []string{"", "", ""}},
    286 	{"1 2 3 4", " ", 3, []string{"1 ", "2 ", "3 4"}},
    287 	{"1 2 3", " ", 3, []string{"1 ", "2 ", "3"}},
    288 	{"1 2", " ", 3, []string{"1 ", "2"}},
    289 	{"123", "", 2, []string{"1", "23"}},
    290 	{"123", "", 17, []string{"1", "2", "3"}},
    291 }
    292 
    293 func TestSplitAfter(t *testing.T) {
    294 	for _, tt := range splitaftertests {
    295 		a := SplitAfterN(tt.s, tt.sep, tt.n)
    296 		if !eq(a, tt.a) {
    297 			t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, a, tt.a)
    298 			continue
    299 		}
    300 		s := Join(a, "")
    301 		if s != tt.s {
    302 			t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
    303 		}
    304 		if tt.n < 0 {
    305 			b := SplitAfter(tt.s, tt.sep)
    306 			if !reflect.DeepEqual(a, b) {
    307 				t.Errorf("SplitAfter disagrees with SplitAfterN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
    308 			}
    309 		}
    310 	}
    311 }
    312 
    313 type FieldsTest struct {
    314 	s string
    315 	a []string
    316 }
    317 
    318 var fieldstests = []FieldsTest{
    319 	{"", []string{}},
    320 	{" ", []string{}},
    321 	{" \t ", []string{}},
    322 	{"  abc  ", []string{"abc"}},
    323 	{"1 2 3 4", []string{"1", "2", "3", "4"}},
    324 	{"1  2  3  4", []string{"1", "2", "3", "4"}},
    325 	{"1\t\t2\t\t3\t4", []string{"1", "2", "3", "4"}},
    326 	{"1\u20002\u20013\u20024", []string{"1", "2", "3", "4"}},
    327 	{"\u2000\u2001\u2002", []string{}},
    328 	{"\n\t\n", []string{"", ""}},
    329 	{faces, []string{faces}},
    330 }
    331 
    332 func TestFields(t *testing.T) {
    333 	for _, tt := range fieldstests {
    334 		a := Fields(tt.s)
    335 		if !eq(a, tt.a) {
    336 			t.Errorf("Fields(%q) = %v; want %v", tt.s, a, tt.a)
    337 			continue
    338 		}
    339 	}
    340 }
    341 
    342 var FieldsFuncTests = []FieldsTest{
    343 	{"", []string{}},
    344 	{"XX", []string{}},
    345 	{"XXhiXXX", []string{"hi"}},
    346 	{"aXXbXXXcX", []string{"a", "b", "c"}},
    347 }
    348 
    349 func TestFieldsFunc(t *testing.T) {
    350 	for _, tt := range fieldstests {
    351 		a := FieldsFunc(tt.s, unicode.IsSpace)
    352 		if !eq(a, tt.a) {
    353 			t.Errorf("FieldsFunc(%q, unicode.IsSpace) = %v; want %v", tt.s, a, tt.a)
    354 			continue
    355 		}
    356 	}
    357 	pred := func(c rune) bool { return c == 'X' }
    358 	for _, tt := range FieldsFuncTests {
    359 		a := FieldsFunc(tt.s, pred)
    360 		if !eq(a, tt.a) {
    361 			t.Errorf("FieldsFunc(%q) = %v, want %v", tt.s, a, tt.a)
    362 		}
    363 	}
    364 }
    365 
    366 // Test case for any function which accepts and returns a single string.
    367 type StringTest struct {
    368 	in, out string
    369 }
    370 
    371 // Execute f on each test case.  funcName should be the name of f; it's used
    372 // in failure reports.
    373 func runStringTests(t *testing.T, f func(string) string, funcName string, testCases []StringTest) {
    374 	for _, tc := range testCases {
    375 		actual := f(tc.in)
    376 		if actual != tc.out {
    377 			t.Errorf("%s(%q) = %q; want %q", funcName, tc.in, actual, tc.out)
    378 		}
    379 	}
    380 }
    381 
    382 var upperTests = []StringTest{
    383 	{"", ""},
    384 	{"abc", "ABC"},
    385 	{"AbC123", "ABC123"},
    386 	{"azAZ09_", "AZAZ09_"},
    387 	{"\u0250\u0250\u0250\u0250\u0250", "\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F"}, // grows one byte per char
    388 }
    389 
    390 var lowerTests = []StringTest{
    391 	{"", ""},
    392 	{"abc", "abc"},
    393 	{"AbC123", "abc123"},
    394 	{"azAZ09_", "azaz09_"},
    395 	{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", "\u0251\u0251\u0251\u0251\u0251"}, // shrinks one byte per char
    396 }
    397 
    398 const space = "\t\v\r\f\n\u0085\u00a0\u2000\u3000"
    399 
    400 var trimSpaceTests = []StringTest{
    401 	{"", ""},
    402 	{"abc", "abc"},
    403 	{space + "abc" + space, "abc"},
    404 	{" ", ""},
    405 	{" \t\r\n \t\t\r\r\n\n ", ""},
    406 	{" \t\r\n x\t\t\r\r\n\n ", "x"},
    407 	{" \u2000\t\r\n x\t\t\r\r\ny\n \u3000", "x\t\t\r\r\ny"},
    408 	{"1 \t\r\n2", "1 \t\r\n2"},
    409 	{" x\x80", "x\x80"},
    410 	{" x\xc0", "x\xc0"},
    411 	{"x \xc0\xc0 ", "x \xc0\xc0"},
    412 	{"x \xc0", "x \xc0"},
    413 	{"x \xc0 ", "x \xc0"},
    414 	{"x \xc0\xc0 ", "x \xc0\xc0"},
    415 	{"x \xc0\xc0 ", "x \xc0\xc0"},
    416 	{"x  ", "x "},
    417 }
    418 
    419 func tenRunes(ch rune) string {
    420 	r := make([]rune, 10)
    421 	for i := range r {
    422 		r[i] = ch
    423 	}
    424 	return string(r)
    425 }
    426 
    427 // User-defined self-inverse mapping function
    428 func rot13(r rune) rune {
    429 	step := rune(13)
    430 	if r >= 'a' && r <= 'z' {
    431 		return ((r - 'a' + step) % 26) + 'a'
    432 	}
    433 	if r >= 'A' && r <= 'Z' {
    434 		return ((r - 'A' + step) % 26) + 'A'
    435 	}
    436 	return r
    437 }
    438 
    439 func TestMap(t *testing.T) {
    440 	// Run a couple of awful growth/shrinkage tests
    441 	a := tenRunes('a')
    442 	// 1.  Grow.  This triggers two reallocations in Map.
    443 	maxRune := func(rune) rune { return unicode.MaxRune }
    444 	m := Map(maxRune, a)
    445 	expect := tenRunes(unicode.MaxRune)
    446 	if m != expect {
    447 		t.Errorf("growing: expected %q got %q", expect, m)
    448 	}
    449 
    450 	// 2. Shrink
    451 	minRune := func(rune) rune { return 'a' }
    452 	m = Map(minRune, tenRunes(unicode.MaxRune))
    453 	expect = a
    454 	if m != expect {
    455 		t.Errorf("shrinking: expected %q got %q", expect, m)
    456 	}
    457 
    458 	// 3. Rot13
    459 	m = Map(rot13, "a to zed")
    460 	expect = "n gb mrq"
    461 	if m != expect {
    462 		t.Errorf("rot13: expected %q got %q", expect, m)
    463 	}
    464 
    465 	// 4. Rot13^2
    466 	m = Map(rot13, Map(rot13, "a to zed"))
    467 	expect = "a to zed"
    468 	if m != expect {
    469 		t.Errorf("rot13: expected %q got %q", expect, m)
    470 	}
    471 
    472 	// 5. Drop
    473 	dropNotLatin := func(r rune) rune {
    474 		if unicode.Is(unicode.Latin, r) {
    475 			return r
    476 		}
    477 		return -1
    478 	}
    479 	m = Map(dropNotLatin, "Hello, ")
    480 	expect = "Hello"
    481 	if m != expect {
    482 		t.Errorf("drop: expected %q got %q", expect, m)
    483 	}
    484 
    485 	// 6. Identity
    486 	identity := func(r rune) rune {
    487 		return r
    488 	}
    489 	orig := "Input string that we expect not to be copied."
    490 	m = Map(identity, orig)
    491 	if (*reflect.StringHeader)(unsafe.Pointer(&orig)).Data !=
    492 		(*reflect.StringHeader)(unsafe.Pointer(&m)).Data {
    493 		t.Error("unexpected copy during identity map")
    494 	}
    495 }
    496 
    497 func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
    498 
    499 func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
    500 
    501 func BenchmarkMapNoChanges(b *testing.B) {
    502 	identity := func(r rune) rune {
    503 		return r
    504 	}
    505 	for i := 0; i < b.N; i++ {
    506 		Map(identity, "Some string that won't be modified.")
    507 	}
    508 }
    509 
    510 func TestSpecialCase(t *testing.T) {
    511 	lower := "abcdefghijklmnoprstuvyz"
    512 	upper := "ABCDEFGHIJKLMNOPRSTUVYZ"
    513 	u := ToUpperSpecial(unicode.TurkishCase, upper)
    514 	if u != upper {
    515 		t.Errorf("Upper(upper) is %s not %s", u, upper)
    516 	}
    517 	u = ToUpperSpecial(unicode.TurkishCase, lower)
    518 	if u != upper {
    519 		t.Errorf("Upper(lower) is %s not %s", u, upper)
    520 	}
    521 	l := ToLowerSpecial(unicode.TurkishCase, lower)
    522 	if l != lower {
    523 		t.Errorf("Lower(lower) is %s not %s", l, lower)
    524 	}
    525 	l = ToLowerSpecial(unicode.TurkishCase, upper)
    526 	if l != lower {
    527 		t.Errorf("Lower(upper) is %s not %s", l, lower)
    528 	}
    529 }
    530 
    531 func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) }
    532 
    533 var trimTests = []struct {
    534 	f            string
    535 	in, arg, out string
    536 }{
    537 	{"Trim", "abba", "a", "bb"},
    538 	{"Trim", "abba", "ab", ""},
    539 	{"TrimLeft", "abba", "ab", ""},
    540 	{"TrimRight", "abba", "ab", ""},
    541 	{"TrimLeft", "abba", "a", "bba"},
    542 	{"TrimRight", "abba", "a", "abb"},
    543 	{"Trim", "<tag>", "<>", "tag"},
    544 	{"Trim", "* listitem", " *", "listitem"},
    545 	{"Trim", `"quote"`, `"`, "quote"},
    546 	{"Trim", "\u2C6F\u2C6F\u0250\u0250\u2C6F\u2C6F", "\u2C6F", "\u0250\u0250"},
    547 	//empty string tests
    548 	{"Trim", "abba", "", "abba"},
    549 	{"Trim", "", "123", ""},
    550 	{"Trim", "", "", ""},
    551 	{"TrimLeft", "abba", "", "abba"},
    552 	{"TrimLeft", "", "123", ""},
    553 	{"TrimLeft", "", "", ""},
    554 	{"TrimRight", "abba", "", "abba"},
    555 	{"TrimRight", "", "123", ""},
    556 	{"TrimRight", "", "", ""},
    557 	{"TrimRight", "\xc0", "", "\xc0"},
    558 	{"TrimPrefix", "aabb", "a", "abb"},
    559 	{"TrimPrefix", "aabb", "b", "aabb"},
    560 	{"TrimSuffix", "aabb", "a", "aabb"},
    561 	{"TrimSuffix", "aabb", "b", "aab"},
    562 }
    563 
    564 func TestTrim(t *testing.T) {
    565 	for _, tc := range trimTests {
    566 		name := tc.f
    567 		var f func(string, string) string
    568 		switch name {
    569 		case "Trim":
    570 			f = Trim
    571 		case "TrimLeft":
    572 			f = TrimLeft
    573 		case "TrimRight":
    574 			f = TrimRight
    575 		case "TrimPrefix":
    576 			f = TrimPrefix
    577 		case "TrimSuffix":
    578 			f = TrimSuffix
    579 		default:
    580 			t.Errorf("Undefined trim function %s", name)
    581 		}
    582 		actual := f(tc.in, tc.arg)
    583 		if actual != tc.out {
    584 			t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out)
    585 		}
    586 	}
    587 }
    588 
    589 func BenchmarkTrim(b *testing.B) {
    590 	b.ReportAllocs()
    591 
    592 	for i := 0; i < b.N; i++ {
    593 		for _, tc := range trimTests {
    594 			name := tc.f
    595 			var f func(string, string) string
    596 			switch name {
    597 			case "Trim":
    598 				f = Trim
    599 			case "TrimLeft":
    600 				f = TrimLeft
    601 			case "TrimRight":
    602 				f = TrimRight
    603 			case "TrimPrefix":
    604 				f = TrimPrefix
    605 			case "TrimSuffix":
    606 				f = TrimSuffix
    607 			default:
    608 				b.Errorf("Undefined trim function %s", name)
    609 			}
    610 			actual := f(tc.in, tc.arg)
    611 			if actual != tc.out {
    612 				b.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out)
    613 			}
    614 		}
    615 	}
    616 }
    617 
    618 type predicate struct {
    619 	f    func(rune) bool
    620 	name string
    621 }
    622 
    623 var isSpace = predicate{unicode.IsSpace, "IsSpace"}
    624 var isDigit = predicate{unicode.IsDigit, "IsDigit"}
    625 var isUpper = predicate{unicode.IsUpper, "IsUpper"}
    626 var isValidRune = predicate{
    627 	func(r rune) bool {
    628 		return r != utf8.RuneError
    629 	},
    630 	"IsValidRune",
    631 }
    632 
    633 func not(p predicate) predicate {
    634 	return predicate{
    635 		func(r rune) bool {
    636 			return !p.f(r)
    637 		},
    638 		"not " + p.name,
    639 	}
    640 }
    641 
    642 var trimFuncTests = []struct {
    643 	f       predicate
    644 	in, out string
    645 }{
    646 	{isSpace, space + " hello " + space, "hello"},
    647 	{isDigit, "\u0e50\u0e5212hello34\u0e50\u0e51", "hello"},
    648 	{isUpper, "\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", "hello"},
    649 	{not(isSpace), "hello" + space + "hello", space},
    650 	{not(isDigit), "hello\u0e50\u0e521234\u0e50\u0e51helo", "\u0e50\u0e521234\u0e50\u0e51"},
    651 	{isValidRune, "ab\xc0a\xc0cd", "\xc0a\xc0"},
    652 	{not(isValidRune), "\xc0a\xc0", "a"},
    653 }
    654 
    655 func TestTrimFunc(t *testing.T) {
    656 	for _, tc := range trimFuncTests {
    657 		actual := TrimFunc(tc.in, tc.f.f)
    658 		if actual != tc.out {
    659 			t.Errorf("TrimFunc(%q, %q) = %q; want %q", tc.in, tc.f.name, actual, tc.out)
    660 		}
    661 	}
    662 }
    663 
    664 var indexFuncTests = []struct {
    665 	in          string
    666 	f           predicate
    667 	first, last int
    668 }{
    669 	{"", isValidRune, -1, -1},
    670 	{"abc", isDigit, -1, -1},
    671 	{"0123", isDigit, 0, 3},
    672 	{"a1b", isDigit, 1, 1},
    673 	{space, isSpace, 0, len(space) - 3}, // last rune in space is 3 bytes
    674 	{"\u0e50\u0e5212hello34\u0e50\u0e51", isDigit, 0, 18},
    675 	{"\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", isUpper, 0, 34},
    676 	{"12\u0e50\u0e52hello34\u0e50\u0e51", not(isDigit), 8, 12},
    677 
    678 	// tests of invalid UTF-8
    679 	{"\x801", isDigit, 1, 1},
    680 	{"\x80abc", isDigit, -1, -1},
    681 	{"\xc0a\xc0", isValidRune, 1, 1},
    682 	{"\xc0a\xc0", not(isValidRune), 0, 2},
    683 	{"\xc0\xc0", not(isValidRune), 0, 4},
    684 	{"\xc0\xc0\xc0", not(isValidRune), 0, 5},
    685 	{"ab\xc0a\xc0cd", not(isValidRune), 2, 4},
    686 	{"a\xe0\x80cd", not(isValidRune), 1, 2},
    687 	{"\x80\x80\x80\x80", not(isValidRune), 0, 3},
    688 }
    689 
    690 func TestIndexFunc(t *testing.T) {
    691 	for _, tc := range indexFuncTests {
    692 		first := IndexFunc(tc.in, tc.f.f)
    693 		if first != tc.first {
    694 			t.Errorf("IndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, first, tc.first)
    695 		}
    696 		last := LastIndexFunc(tc.in, tc.f.f)
    697 		if last != tc.last {
    698 			t.Errorf("LastIndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, last, tc.last)
    699 		}
    700 	}
    701 }
    702 
    703 func equal(m string, s1, s2 string, t *testing.T) bool {
    704 	if s1 == s2 {
    705 		return true
    706 	}
    707 	e1 := Split(s1, "")
    708 	e2 := Split(s2, "")
    709 	for i, c1 := range e1 {
    710 		if i >= len(e2) {
    711 			break
    712 		}
    713 		r1, _ := utf8.DecodeRuneInString(c1)
    714 		r2, _ := utf8.DecodeRuneInString(e2[i])
    715 		if r1 != r2 {
    716 			t.Errorf("%s diff at %d: U+%04X U+%04X", m, i, r1, r2)
    717 		}
    718 	}
    719 	return false
    720 }
    721 
    722 func TestCaseConsistency(t *testing.T) {
    723 	// Make a string of all the runes.
    724 	numRunes := int(unicode.MaxRune + 1)
    725 	if testing.Short() {
    726 		numRunes = 1000
    727 	}
    728 	a := make([]rune, numRunes)
    729 	for i := range a {
    730 		a[i] = rune(i)
    731 	}
    732 	s := string(a)
    733 	// convert the cases.
    734 	upper := ToUpper(s)
    735 	lower := ToLower(s)
    736 
    737 	// Consistency checks
    738 	if n := utf8.RuneCountInString(upper); n != numRunes {
    739 		t.Error("rune count wrong in upper:", n)
    740 	}
    741 	if n := utf8.RuneCountInString(lower); n != numRunes {
    742 		t.Error("rune count wrong in lower:", n)
    743 	}
    744 	if !equal("ToUpper(upper)", ToUpper(upper), upper, t) {
    745 		t.Error("ToUpper(upper) consistency fail")
    746 	}
    747 	if !equal("ToLower(lower)", ToLower(lower), lower, t) {
    748 		t.Error("ToLower(lower) consistency fail")
    749 	}
    750 	/*
    751 		  These fail because of non-one-to-oneness of the data, such as multiple
    752 		  upper case 'I' mapping to 'i'.  We comment them out but keep them for
    753 		  interest.
    754 		  For instance: CAPITAL LETTER I WITH DOT ABOVE:
    755 			unicode.ToUpper(unicode.ToLower('\u0130')) != '\u0130'
    756 
    757 		if !equal("ToUpper(lower)", ToUpper(lower), upper, t) {
    758 			t.Error("ToUpper(lower) consistency fail");
    759 		}
    760 		if !equal("ToLower(upper)", ToLower(upper), lower, t) {
    761 			t.Error("ToLower(upper) consistency fail");
    762 		}
    763 	*/
    764 }
    765 
    766 var RepeatTests = []struct {
    767 	in, out string
    768 	count   int
    769 }{
    770 	{"", "", 0},
    771 	{"", "", 1},
    772 	{"", "", 2},
    773 	{"-", "", 0},
    774 	{"-", "-", 1},
    775 	{"-", "----------", 10},
    776 	{"abc ", "abc abc abc ", 3},
    777 }
    778 
    779 func TestRepeat(t *testing.T) {
    780 	for _, tt := range RepeatTests {
    781 		a := Repeat(tt.in, tt.count)
    782 		if !equal("Repeat(s)", a, tt.out, t) {
    783 			t.Errorf("Repeat(%v, %d) = %v; want %v", tt.in, tt.count, a, tt.out)
    784 			continue
    785 		}
    786 	}
    787 }
    788 
    789 func runesEqual(a, b []rune) bool {
    790 	if len(a) != len(b) {
    791 		return false
    792 	}
    793 	for i, r := range a {
    794 		if r != b[i] {
    795 			return false
    796 		}
    797 	}
    798 	return true
    799 }
    800 
    801 var RunesTests = []struct {
    802 	in    string
    803 	out   []rune
    804 	lossy bool
    805 }{
    806 	{"", []rune{}, false},
    807 	{" ", []rune{32}, false},
    808 	{"ABC", []rune{65, 66, 67}, false},
    809 	{"abc", []rune{97, 98, 99}, false},
    810 	{"\u65e5\u672c\u8a9e", []rune{26085, 26412, 35486}, false},
    811 	{"ab\x80c", []rune{97, 98, 0xFFFD, 99}, true},
    812 	{"ab\xc0c", []rune{97, 98, 0xFFFD, 99}, true},
    813 }
    814 
    815 func TestRunes(t *testing.T) {
    816 	for _, tt := range RunesTests {
    817 		a := []rune(tt.in)
    818 		if !runesEqual(a, tt.out) {
    819 			t.Errorf("[]rune(%q) = %v; want %v", tt.in, a, tt.out)
    820 			continue
    821 		}
    822 		if !tt.lossy {
    823 			// can only test reassembly if we didn't lose information
    824 			s := string(a)
    825 			if s != tt.in {
    826 				t.Errorf("string([]rune(%q)) = %x; want %x", tt.in, s, tt.in)
    827 			}
    828 		}
    829 	}
    830 }
    831 
    832 func TestReadByte(t *testing.T) {
    833 	testStrings := []string{"", abcd, faces, commas}
    834 	for _, s := range testStrings {
    835 		reader := NewReader(s)
    836 		if e := reader.UnreadByte(); e == nil {
    837 			t.Errorf("Unreading %q at beginning: expected error", s)
    838 		}
    839 		var res bytes.Buffer
    840 		for {
    841 			b, e := reader.ReadByte()
    842 			if e == io.EOF {
    843 				break
    844 			}
    845 			if e != nil {
    846 				t.Errorf("Reading %q: %s", s, e)
    847 				break
    848 			}
    849 			res.WriteByte(b)
    850 			// unread and read again
    851 			e = reader.UnreadByte()
    852 			if e != nil {
    853 				t.Errorf("Unreading %q: %s", s, e)
    854 				break
    855 			}
    856 			b1, e := reader.ReadByte()
    857 			if e != nil {
    858 				t.Errorf("Reading %q after unreading: %s", s, e)
    859 				break
    860 			}
    861 			if b1 != b {
    862 				t.Errorf("Reading %q after unreading: want byte %q, got %q", s, b, b1)
    863 				break
    864 			}
    865 		}
    866 		if res.String() != s {
    867 			t.Errorf("Reader(%q).ReadByte() produced %q", s, res.String())
    868 		}
    869 	}
    870 }
    871 
    872 func TestReadRune(t *testing.T) {
    873 	testStrings := []string{"", abcd, faces, commas}
    874 	for _, s := range testStrings {
    875 		reader := NewReader(s)
    876 		if e := reader.UnreadRune(); e == nil {
    877 			t.Errorf("Unreading %q at beginning: expected error", s)
    878 		}
    879 		res := ""
    880 		for {
    881 			r, z, e := reader.ReadRune()
    882 			if e == io.EOF {
    883 				break
    884 			}
    885 			if e != nil {
    886 				t.Errorf("Reading %q: %s", s, e)
    887 				break
    888 			}
    889 			res += string(r)
    890 			// unread and read again
    891 			e = reader.UnreadRune()
    892 			if e != nil {
    893 				t.Errorf("Unreading %q: %s", s, e)
    894 				break
    895 			}
    896 			r1, z1, e := reader.ReadRune()
    897 			if e != nil {
    898 				t.Errorf("Reading %q after unreading: %s", s, e)
    899 				break
    900 			}
    901 			if r1 != r {
    902 				t.Errorf("Reading %q after unreading: want rune %q, got %q", s, r, r1)
    903 				break
    904 			}
    905 			if z1 != z {
    906 				t.Errorf("Reading %q after unreading: want size %d, got %d", s, z, z1)
    907 				break
    908 			}
    909 		}
    910 		if res != s {
    911 			t.Errorf("Reader(%q).ReadRune() produced %q", s, res)
    912 		}
    913 	}
    914 }
    915 
    916 var UnreadRuneErrorTests = []struct {
    917 	name string
    918 	f    func(*Reader)
    919 }{
    920 	{"Read", func(r *Reader) { r.Read([]byte{0}) }},
    921 	{"ReadByte", func(r *Reader) { r.ReadByte() }},
    922 	{"UnreadRune", func(r *Reader) { r.UnreadRune() }},
    923 	{"Seek", func(r *Reader) { r.Seek(0, 1) }},
    924 	{"WriteTo", func(r *Reader) { r.WriteTo(&bytes.Buffer{}) }},
    925 }
    926 
    927 func TestUnreadRuneError(t *testing.T) {
    928 	for _, tt := range UnreadRuneErrorTests {
    929 		reader := NewReader("0123456789")
    930 		if _, _, err := reader.ReadRune(); err != nil {
    931 			// should not happen
    932 			t.Fatal(err)
    933 		}
    934 		tt.f(reader)
    935 		err := reader.UnreadRune()
    936 		if err == nil {
    937 			t.Errorf("Unreading after %s: expected error", tt.name)
    938 		}
    939 	}
    940 }
    941 
    942 var ReplaceTests = []struct {
    943 	in       string
    944 	old, new string
    945 	n        int
    946 	out      string
    947 }{
    948 	{"hello", "l", "L", 0, "hello"},
    949 	{"hello", "l", "L", -1, "heLLo"},
    950 	{"hello", "x", "X", -1, "hello"},
    951 	{"", "x", "X", -1, ""},
    952 	{"radar", "r", "<r>", -1, "<r>ada<r>"},
    953 	{"", "", "<>", -1, "<>"},
    954 	{"banana", "a", "<>", -1, "b<>n<>n<>"},
    955 	{"banana", "a", "<>", 1, "b<>nana"},
    956 	{"banana", "a", "<>", 1000, "b<>n<>n<>"},
    957 	{"banana", "an", "<>", -1, "b<><>a"},
    958 	{"banana", "ana", "<>", -1, "b<>na"},
    959 	{"banana", "", "<>", -1, "<>b<>a<>n<>a<>n<>a<>"},
    960 	{"banana", "", "<>", 10, "<>b<>a<>n<>a<>n<>a<>"},
    961 	{"banana", "", "<>", 6, "<>b<>a<>n<>a<>n<>a"},
    962 	{"banana", "", "<>", 5, "<>b<>a<>n<>a<>na"},
    963 	{"banana", "", "<>", 1, "<>banana"},
    964 	{"banana", "a", "a", -1, "banana"},
    965 	{"banana", "a", "a", 1, "banana"},
    966 	{"", "", "<>", -1, "<><><><>"},
    967 }
    968 
    969 func TestReplace(t *testing.T) {
    970 	for _, tt := range ReplaceTests {
    971 		if s := Replace(tt.in, tt.old, tt.new, tt.n); s != tt.out {
    972 			t.Errorf("Replace(%q, %q, %q, %d) = %q, want %q", tt.in, tt.old, tt.new, tt.n, s, tt.out)
    973 		}
    974 	}
    975 }
    976 
    977 var TitleTests = []struct {
    978 	in, out string
    979 }{
    980 	{"", ""},
    981 	{"a", "A"},
    982 	{" aaa aaa aaa ", " Aaa Aaa Aaa "},
    983 	{" Aaa Aaa Aaa ", " Aaa Aaa Aaa "},
    984 	{"123a456", "123a456"},
    985 	{"double-blind", "Double-Blind"},
    986 	{"", ""},
    987 	{"with_underscore", "With_underscore"},
    988 	{"unicode \xe2\x80\xa8 line separator", "Unicode \xe2\x80\xa8 Line Separator"},
    989 }
    990 
    991 func TestTitle(t *testing.T) {
    992 	for _, tt := range TitleTests {
    993 		if s := Title(tt.in); s != tt.out {
    994 			t.Errorf("Title(%q) = %q, want %q", tt.in, s, tt.out)
    995 		}
    996 	}
    997 }
    998 
    999 var ContainsTests = []struct {
   1000 	str, substr string
   1001 	expected    bool
   1002 }{
   1003 	{"abc", "bc", true},
   1004 	{"abc", "bcd", false},
   1005 	{"abc", "", true},
   1006 	{"", "a", false},
   1007 }
   1008 
   1009 func TestContains(t *testing.T) {
   1010 	for _, ct := range ContainsTests {
   1011 		if Contains(ct.str, ct.substr) != ct.expected {
   1012 			t.Errorf("Contains(%s, %s) = %v, want %v",
   1013 				ct.str, ct.substr, !ct.expected, ct.expected)
   1014 		}
   1015 	}
   1016 }
   1017 
   1018 var ContainsAnyTests = []struct {
   1019 	str, substr string
   1020 	expected    bool
   1021 }{
   1022 	{"", "", false},
   1023 	{"", "a", false},
   1024 	{"", "abc", false},
   1025 	{"a", "", false},
   1026 	{"a", "a", true},
   1027 	{"aaa", "a", true},
   1028 	{"abc", "xyz", false},
   1029 	{"abc", "xcz", true},
   1030 	{"abcd", "uvwxyz", true},
   1031 	{"aRegExp*", ".(|)*+?^$[]", true},
   1032 	{dots + dots + dots, " ", false},
   1033 }
   1034 
   1035 func TestContainsAny(t *testing.T) {
   1036 	for _, ct := range ContainsAnyTests {
   1037 		if ContainsAny(ct.str, ct.substr) != ct.expected {
   1038 			t.Errorf("ContainsAny(%s, %s) = %v, want %v",
   1039 				ct.str, ct.substr, !ct.expected, ct.expected)
   1040 		}
   1041 	}
   1042 }
   1043 
   1044 var ContainsRuneTests = []struct {
   1045 	str      string
   1046 	r        rune
   1047 	expected bool
   1048 }{
   1049 	{"", 'a', false},
   1050 	{"a", 'a', true},
   1051 	{"aaa", 'a', true},
   1052 	{"abc", 'y', false},
   1053 	{"abc", 'c', true},
   1054 	{"abcd", 'x', false},
   1055 	{"abcd", '', true},
   1056 	{"aRegExp*", '*', true},
   1057 }
   1058 
   1059 func TestContainsRune(t *testing.T) {
   1060 	for _, ct := range ContainsRuneTests {
   1061 		if ContainsRune(ct.str, ct.r) != ct.expected {
   1062 			t.Errorf("ContainsRune(%q, %q) = %v, want %v",
   1063 				ct.str, ct.r, !ct.expected, ct.expected)
   1064 		}
   1065 	}
   1066 }
   1067 
   1068 var EqualFoldTests = []struct {
   1069 	s, t string
   1070 	out  bool
   1071 }{
   1072 	{"abc", "abc", true},
   1073 	{"ABcd", "ABcd", true},
   1074 	{"123abc", "123ABC", true},
   1075 	{"", "", true},
   1076 	{"abc", "xyz", false},
   1077 	{"abc", "XYZ", false},
   1078 	{"abcdefghijk", "abcdefghijX", false},
   1079 	{"abcdefghijk", "abcdefghij\u212A", true},
   1080 	{"abcdefghijK", "abcdefghij\u212A", true},
   1081 	{"abcdefghijkz", "abcdefghij\u212Ay", false},
   1082 	{"abcdefghijKz", "abcdefghij\u212Ay", false},
   1083 }
   1084 
   1085 func TestEqualFold(t *testing.T) {
   1086 	for _, tt := range EqualFoldTests {
   1087 		if out := EqualFold(tt.s, tt.t); out != tt.out {
   1088 			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.s, tt.t, out, tt.out)
   1089 		}
   1090 		if out := EqualFold(tt.t, tt.s); out != tt.out {
   1091 			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.t, tt.s, out, tt.out)
   1092 		}
   1093 	}
   1094 }
   1095 
   1096 var CountTests = []struct {
   1097 	s, sep string
   1098 	num    int
   1099 }{
   1100 	{"", "", 1},
   1101 	{"", "notempty", 0},
   1102 	{"notempty", "", 9},
   1103 	{"smaller", "not smaller", 0},
   1104 	{"12345678987654321", "6", 2},
   1105 	{"611161116", "6", 3},
   1106 	{"notequal", "NotEqual", 0},
   1107 	{"equal", "equal", 1},
   1108 	{"abc1231231123q", "123", 3},
   1109 	{"11111", "11", 2},
   1110 }
   1111 
   1112 func TestCount(t *testing.T) {
   1113 	for _, tt := range CountTests {
   1114 		if num := Count(tt.s, tt.sep); num != tt.num {
   1115 			t.Errorf("Count(\"%s\", \"%s\") = %d, want %d", tt.s, tt.sep, num, tt.num)
   1116 		}
   1117 	}
   1118 }
   1119 
   1120 func makeBenchInputHard() string {
   1121 	tokens := [...]string{
   1122 		"<a>", "<p>", "<b>", "<strong>",
   1123 		"</a>", "</p>", "</b>", "</strong>",
   1124 		"hello", "world",
   1125 	}
   1126 	x := make([]byte, 0, 1<<20)
   1127 	for {
   1128 		i := rand.Intn(len(tokens))
   1129 		if len(x)+len(tokens[i]) >= 1<<20 {
   1130 			break
   1131 		}
   1132 		x = append(x, tokens[i]...)
   1133 	}
   1134 	return string(x)
   1135 }
   1136 
   1137 var benchInputHard = makeBenchInputHard()
   1138 
   1139 func benchmarkIndexHard(b *testing.B, sep string) {
   1140 	for i := 0; i < b.N; i++ {
   1141 		Index(benchInputHard, sep)
   1142 	}
   1143 }
   1144 
   1145 func benchmarkLastIndexHard(b *testing.B, sep string) {
   1146 	for i := 0; i < b.N; i++ {
   1147 		LastIndex(benchInputHard, sep)
   1148 	}
   1149 }
   1150 
   1151 func benchmarkCountHard(b *testing.B, sep string) {
   1152 	for i := 0; i < b.N; i++ {
   1153 		Count(benchInputHard, sep)
   1154 	}
   1155 }
   1156 
   1157 func BenchmarkIndexHard1(b *testing.B) { benchmarkIndexHard(b, "<>") }
   1158 func BenchmarkIndexHard2(b *testing.B) { benchmarkIndexHard(b, "</pre>") }
   1159 func BenchmarkIndexHard3(b *testing.B) { benchmarkIndexHard(b, "<b>hello world</b>") }
   1160 
   1161 func BenchmarkLastIndexHard1(b *testing.B) { benchmarkLastIndexHard(b, "<>") }
   1162 func BenchmarkLastIndexHard2(b *testing.B) { benchmarkLastIndexHard(b, "</pre>") }
   1163 func BenchmarkLastIndexHard3(b *testing.B) { benchmarkLastIndexHard(b, "<b>hello world</b>") }
   1164 
   1165 func BenchmarkCountHard1(b *testing.B) { benchmarkCountHard(b, "<>") }
   1166 func BenchmarkCountHard2(b *testing.B) { benchmarkCountHard(b, "</pre>") }
   1167 func BenchmarkCountHard3(b *testing.B) { benchmarkCountHard(b, "<b>hello world</b>") }
   1168 
   1169 var benchInputTorture = Repeat("ABC", 1<<10) + "123" + Repeat("ABC", 1<<10)
   1170 var benchNeedleTorture = Repeat("ABC", 1<<10+1)
   1171 
   1172 func BenchmarkIndexTorture(b *testing.B) {
   1173 	for i := 0; i < b.N; i++ {
   1174 		Index(benchInputTorture, benchNeedleTorture)
   1175 	}
   1176 }
   1177 
   1178 func BenchmarkCountTorture(b *testing.B) {
   1179 	for i := 0; i < b.N; i++ {
   1180 		Count(benchInputTorture, benchNeedleTorture)
   1181 	}
   1182 }
   1183 
   1184 func BenchmarkCountTortureOverlapping(b *testing.B) {
   1185 	A := Repeat("ABC", 1<<20)
   1186 	B := Repeat("ABC", 1<<10)
   1187 	for i := 0; i < b.N; i++ {
   1188 		Count(A, B)
   1189 	}
   1190 }
   1191 
   1192 var makeFieldsInput = func() string {
   1193 	x := make([]byte, 1<<20)
   1194 	// Input is ~10% space, ~10% 2-byte UTF-8, rest ASCII non-space.
   1195 	for i := range x {
   1196 		switch rand.Intn(10) {
   1197 		case 0:
   1198 			x[i] = ' '
   1199 		case 1:
   1200 			if i > 0 && x[i-1] == 'x' {
   1201 				copy(x[i-1:], "")
   1202 				break
   1203 			}
   1204 			fallthrough
   1205 		default:
   1206 			x[i] = 'x'
   1207 		}
   1208 	}
   1209 	return string(x)
   1210 }
   1211 
   1212 var fieldsInput = makeFieldsInput()
   1213 
   1214 func BenchmarkFields(b *testing.B) {
   1215 	b.SetBytes(int64(len(fieldsInput)))
   1216 	for i := 0; i < b.N; i++ {
   1217 		Fields(fieldsInput)
   1218 	}
   1219 }
   1220 
   1221 func BenchmarkFieldsFunc(b *testing.B) {
   1222 	b.SetBytes(int64(len(fieldsInput)))
   1223 	for i := 0; i < b.N; i++ {
   1224 		FieldsFunc(fieldsInput, unicode.IsSpace)
   1225 	}
   1226 }
   1227 
   1228 func BenchmarkSplit1(b *testing.B) {
   1229 	for i := 0; i < b.N; i++ {
   1230 		Split(benchInputHard, "")
   1231 	}
   1232 }
   1233 
   1234 func BenchmarkSplit2(b *testing.B) {
   1235 	for i := 0; i < b.N; i++ {
   1236 		Split(benchInputHard, "/")
   1237 	}
   1238 }
   1239 
   1240 func BenchmarkSplit3(b *testing.B) {
   1241 	for i := 0; i < b.N; i++ {
   1242 		Split(benchInputHard, "hello")
   1243 	}
   1244 }
   1245 
   1246 func BenchmarkRepeat(b *testing.B) {
   1247 	for i := 0; i < b.N; i++ {
   1248 		Repeat("-", 80)
   1249 	}
   1250 }
   1251