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
5package bytes_test
6
7import (
8	. "bytes"
9	"fmt"
10	"internal/testenv"
11	"math"
12	"math/rand"
13	"reflect"
14	"strings"
15	"testing"
16	"unicode"
17	"unicode/utf8"
18	"unsafe"
19)
20
21func eq(a, b []string) bool {
22	if len(a) != len(b) {
23		return false
24	}
25	for i := 0; i < len(a); i++ {
26		if a[i] != b[i] {
27			return false
28		}
29	}
30	return true
31}
32
33func sliceOfString(s [][]byte) []string {
34	result := make([]string, len(s))
35	for i, v := range s {
36		result[i] = string(v)
37	}
38	return result
39}
40
41// For ease of reading, the test cases use strings that are converted to byte
42// slices before invoking the functions.
43
44var abcd = "abcd"
45var faces = "☺☻☹"
46var commas = "1,2,3,4"
47var dots = "1....2....3....4"
48
49type BinOpTest struct {
50	a string
51	b string
52	i int
53}
54
55func TestEqual(t *testing.T) {
56	// Run the tests and check for allocation at the same time.
57	allocs := testing.AllocsPerRun(10, func() {
58		for _, tt := range compareTests {
59			eql := Equal(tt.a, tt.b)
60			if eql != (tt.i == 0) {
61				t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql)
62			}
63		}
64	})
65	if allocs > 0 {
66		t.Errorf("Equal allocated %v times", allocs)
67	}
68}
69
70func TestEqualExhaustive(t *testing.T) {
71	var size = 128
72	if testing.Short() {
73		size = 32
74	}
75	a := make([]byte, size)
76	b := make([]byte, size)
77	b_init := make([]byte, size)
78	// randomish but deterministic data
79	for i := 0; i < size; i++ {
80		a[i] = byte(17 * i)
81		b_init[i] = byte(23*i + 100)
82	}
83
84	for len := 0; len <= size; len++ {
85		for x := 0; x <= size-len; x++ {
86			for y := 0; y <= size-len; y++ {
87				copy(b, b_init)
88				copy(b[y:y+len], a[x:x+len])
89				if !Equal(a[x:x+len], b[y:y+len]) || !Equal(b[y:y+len], a[x:x+len]) {
90					t.Errorf("Equal(%d, %d, %d) = false", len, x, y)
91				}
92			}
93		}
94	}
95}
96
97// make sure Equal returns false for minimally different strings. The data
98// is all zeros except for a single one in one location.
99func TestNotEqual(t *testing.T) {
100	var size = 128
101	if testing.Short() {
102		size = 32
103	}
104	a := make([]byte, size)
105	b := make([]byte, size)
106
107	for len := 0; len <= size; len++ {
108		for x := 0; x <= size-len; x++ {
109			for y := 0; y <= size-len; y++ {
110				for diffpos := x; diffpos < x+len; diffpos++ {
111					a[diffpos] = 1
112					if Equal(a[x:x+len], b[y:y+len]) || Equal(b[y:y+len], a[x:x+len]) {
113						t.Errorf("NotEqual(%d, %d, %d, %d) = true", len, x, y, diffpos)
114					}
115					a[diffpos] = 0
116				}
117			}
118		}
119	}
120}
121
122var indexTests = []BinOpTest{
123	{"", "", 0},
124	{"", "a", -1},
125	{"", "foo", -1},
126	{"fo", "foo", -1},
127	{"foo", "baz", -1},
128	{"foo", "foo", 0},
129	{"oofofoofooo", "f", 2},
130	{"oofofoofooo", "foo", 4},
131	{"barfoobarfoo", "foo", 3},
132	{"foo", "", 0},
133	{"foo", "o", 1},
134	{"abcABCabc", "A", 3},
135	// cases with one byte strings - test IndexByte and special case in Index()
136	{"", "a", -1},
137	{"x", "a", -1},
138	{"x", "x", 0},
139	{"abc", "a", 0},
140	{"abc", "b", 1},
141	{"abc", "c", 2},
142	{"abc", "x", -1},
143	{"barfoobarfooyyyzzzyyyzzzyyyzzzyyyxxxzzzyyy", "x", 33},
144	{"fofofofooofoboo", "oo", 7},
145	{"fofofofofofoboo", "ob", 11},
146	{"fofofofofofoboo", "boo", 12},
147	{"fofofofofofoboo", "oboo", 11},
148	{"fofofofofoooboo", "fooo", 8},
149	{"fofofofofofoboo", "foboo", 10},
150	{"fofofofofofoboo", "fofob", 8},
151	{"fofofofofofofoffofoobarfoo", "foffof", 12},
152	{"fofofofofoofofoffofoobarfoo", "foffof", 13},
153	{"fofofofofofofoffofoobarfoo", "foffofo", 12},
154	{"fofofofofoofofoffofoobarfoo", "foffofo", 13},
155	{"fofofofofoofofoffofoobarfoo", "foffofoo", 13},
156	{"fofofofofofofoffofoobarfoo", "foffofoo", 12},
157	{"fofofofofoofofoffofoobarfoo", "foffofoob", 13},
158	{"fofofofofofofoffofoobarfoo", "foffofoob", 12},
159	{"fofofofofoofofoffofoobarfoo", "foffofooba", 13},
160	{"fofofofofofofoffofoobarfoo", "foffofooba", 12},
161	{"fofofofofoofofoffofoobarfoo", "foffofoobar", 13},
162	{"fofofofofofofoffofoobarfoo", "foffofoobar", 12},
163	{"fofofofofoofofoffofoobarfoo", "foffofoobarf", 13},
164	{"fofofofofofofoffofoobarfoo", "foffofoobarf", 12},
165	{"fofofofofoofofoffofoobarfoo", "foffofoobarfo", 13},
166	{"fofofofofofofoffofoobarfoo", "foffofoobarfo", 12},
167	{"fofofofofoofofoffofoobarfoo", "foffofoobarfoo", 13},
168	{"fofofofofofofoffofoobarfoo", "foffofoobarfoo", 12},
169	{"fofofofofoofofoffofoobarfoo", "ofoffofoobarfoo", 12},
170	{"fofofofofofofoffofoobarfoo", "ofoffofoobarfoo", 11},
171	{"fofofofofoofofoffofoobarfoo", "fofoffofoobarfoo", 11},
172	{"fofofofofofofoffofoobarfoo", "fofoffofoobarfoo", 10},
173	{"fofofofofoofofoffofoobarfoo", "foobars", -1},
174	{"foofyfoobarfoobar", "y", 4},
175	{"oooooooooooooooooooooo", "r", -1},
176	{"oxoxoxoxoxoxoxoxoxoxoxoy", "oy", 22},
177	{"oxoxoxoxoxoxoxoxoxoxoxox", "oy", -1},
178	// test fallback to Rabin-Karp.
179	{"000000000000000000000000000000000000000000000000000000000000000000000001", "0000000000000000000000000000000000000000000000000000000000000000001", 5},
180}
181
182var lastIndexTests = []BinOpTest{
183	{"", "", 0},
184	{"", "a", -1},
185	{"", "foo", -1},
186	{"fo", "foo", -1},
187	{"foo", "foo", 0},
188	{"foo", "f", 0},
189	{"oofofoofooo", "f", 7},
190	{"oofofoofooo", "foo", 7},
191	{"barfoobarfoo", "foo", 9},
192	{"foo", "", 3},
193	{"foo", "o", 2},
194	{"abcABCabc", "A", 3},
195	{"abcABCabc", "a", 6},
196}
197
198var indexAnyTests = []BinOpTest{
199	{"", "", -1},
200	{"", "a", -1},
201	{"", "abc", -1},
202	{"a", "", -1},
203	{"a", "a", 0},
204	{"\x80", "\xffb", 0},
205	{"aaa", "a", 0},
206	{"abc", "xyz", -1},
207	{"abc", "xcz", 2},
208	{"ab☺c", "x☺yz", 2},
209	{"a☺b☻c☹d", "cx", len("a☺b☻")},
210	{"a☺b☻c☹d", "uvw☻xyz", len("a☺b")},
211	{"aRegExp*", ".(|)*+?^$[]", 7},
212	{dots + dots + dots, " ", -1},
213	{"012abcba210", "\xffb", 4},
214	{"012\x80bcb\x80210", "\xffb", 3},
215	{"0123456\xcf\x80abc", "\xcfb\x80", 10},
216}
217
218var lastIndexAnyTests = []BinOpTest{
219	{"", "", -1},
220	{"", "a", -1},
221	{"", "abc", -1},
222	{"a", "", -1},
223	{"a", "a", 0},
224	{"\x80", "\xffb", 0},
225	{"aaa", "a", 2},
226	{"abc", "xyz", -1},
227	{"abc", "ab", 1},
228	{"ab☺c", "x☺yz", 2},
229	{"a☺b☻c☹d", "cx", len("a☺b☻")},
230	{"a☺b☻c☹d", "uvw☻xyz", len("a☺b")},
231	{"a.RegExp*", ".(|)*+?^$[]", 8},
232	{dots + dots + dots, " ", -1},
233	{"012abcba210", "\xffb", 6},
234	{"012\x80bcb\x80210", "\xffb", 7},
235	{"0123456\xcf\x80abc", "\xcfb\x80", 10},
236}
237
238// Execute f on each test case.  funcName should be the name of f; it's used
239// in failure reports.
240func runIndexTests(t *testing.T, f func(s, sep []byte) int, funcName string, testCases []BinOpTest) {
241	for _, test := range testCases {
242		a := []byte(test.a)
243		b := []byte(test.b)
244		actual := f(a, b)
245		if actual != test.i {
246			t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, b, actual, test.i)
247		}
248	}
249	var allocTests = []struct {
250		a []byte
251		b []byte
252		i int
253	}{
254		// case for function Index.
255		{[]byte("000000000000000000000000000000000000000000000000000000000000000000000001"), []byte("0000000000000000000000000000000000000000000000000000000000000000001"), 5},
256		// case for function LastIndex.
257		{[]byte("000000000000000000000000000000000000000000000000000000000000000010000"), []byte("00000000000000000000000000000000000000000000000000000000000001"), 3},
258	}
259	allocs := testing.AllocsPerRun(100, func() {
260		if i := Index(allocTests[1].a, allocTests[1].b); i != allocTests[1].i {
261			t.Errorf("Index([]byte(%q), []byte(%q)) = %v; want %v", allocTests[1].a, allocTests[1].b, i, allocTests[1].i)
262		}
263		if i := LastIndex(allocTests[0].a, allocTests[0].b); i != allocTests[0].i {
264			t.Errorf("LastIndex([]byte(%q), []byte(%q)) = %v; want %v", allocTests[0].a, allocTests[0].b, i, allocTests[0].i)
265		}
266	})
267	if allocs != 0 {
268		t.Errorf("expected no allocations, got %f", allocs)
269	}
270}
271
272func runIndexAnyTests(t *testing.T, f func(s []byte, chars string) int, funcName string, testCases []BinOpTest) {
273	for _, test := range testCases {
274		a := []byte(test.a)
275		actual := f(a, test.b)
276		if actual != test.i {
277			t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, test.b, actual, test.i)
278		}
279	}
280}
281
282func TestIndex(t *testing.T)     { runIndexTests(t, Index, "Index", indexTests) }
283func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
284func TestIndexAny(t *testing.T)  { runIndexAnyTests(t, IndexAny, "IndexAny", indexAnyTests) }
285func TestLastIndexAny(t *testing.T) {
286	runIndexAnyTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests)
287}
288
289func TestIndexByte(t *testing.T) {
290	for _, tt := range indexTests {
291		if len(tt.b) != 1 {
292			continue
293		}
294		a := []byte(tt.a)
295		b := tt.b[0]
296		pos := IndexByte(a, b)
297		if pos != tt.i {
298			t.Errorf(`IndexByte(%q, '%c') = %v`, tt.a, b, pos)
299		}
300		posp := IndexBytePortable(a, b)
301		if posp != tt.i {
302			t.Errorf(`indexBytePortable(%q, '%c') = %v`, tt.a, b, posp)
303		}
304	}
305}
306
307func TestLastIndexByte(t *testing.T) {
308	testCases := []BinOpTest{
309		{"", "q", -1},
310		{"abcdef", "q", -1},
311		{"abcdefabcdef", "a", len("abcdef")},      // something in the middle
312		{"abcdefabcdef", "f", len("abcdefabcde")}, // last byte
313		{"zabcdefabcdef", "z", 0},                 // first byte
314		{"a☺b☻c☹d", "b", len("a☺")},               // non-ascii
315	}
316	for _, test := range testCases {
317		actual := LastIndexByte([]byte(test.a), test.b[0])
318		if actual != test.i {
319			t.Errorf("LastIndexByte(%q,%c) = %v; want %v", test.a, test.b[0], actual, test.i)
320		}
321	}
322}
323
324// test a larger buffer with different sizes and alignments
325func TestIndexByteBig(t *testing.T) {
326	var n = 1024
327	if testing.Short() {
328		n = 128
329	}
330	b := make([]byte, n)
331	for i := 0; i < n; i++ {
332		// different start alignments
333		b1 := b[i:]
334		for j := 0; j < len(b1); j++ {
335			b1[j] = 'x'
336			pos := IndexByte(b1, 'x')
337			if pos != j {
338				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
339			}
340			b1[j] = 0
341			pos = IndexByte(b1, 'x')
342			if pos != -1 {
343				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
344			}
345		}
346		// different end alignments
347		b1 = b[:i]
348		for j := 0; j < len(b1); j++ {
349			b1[j] = 'x'
350			pos := IndexByte(b1, 'x')
351			if pos != j {
352				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
353			}
354			b1[j] = 0
355			pos = IndexByte(b1, 'x')
356			if pos != -1 {
357				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
358			}
359		}
360		// different start and end alignments
361		b1 = b[i/2 : n-(i+1)/2]
362		for j := 0; j < len(b1); j++ {
363			b1[j] = 'x'
364			pos := IndexByte(b1, 'x')
365			if pos != j {
366				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
367			}
368			b1[j] = 0
369			pos = IndexByte(b1, 'x')
370			if pos != -1 {
371				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
372			}
373		}
374	}
375}
376
377// test a small index across all page offsets
378func TestIndexByteSmall(t *testing.T) {
379	b := make([]byte, 5015) // bigger than a page
380	// Make sure we find the correct byte even when straddling a page.
381	for i := 0; i <= len(b)-15; i++ {
382		for j := 0; j < 15; j++ {
383			b[i+j] = byte(100 + j)
384		}
385		for j := 0; j < 15; j++ {
386			p := IndexByte(b[i:i+15], byte(100+j))
387			if p != j {
388				t.Errorf("IndexByte(%q, %d) = %d", b[i:i+15], 100+j, p)
389			}
390		}
391		for j := 0; j < 15; j++ {
392			b[i+j] = 0
393		}
394	}
395	// Make sure matches outside the slice never trigger.
396	for i := 0; i <= len(b)-15; i++ {
397		for j := 0; j < 15; j++ {
398			b[i+j] = 1
399		}
400		for j := 0; j < 15; j++ {
401			p := IndexByte(b[i:i+15], byte(0))
402			if p != -1 {
403				t.Errorf("IndexByte(%q, %d) = %d", b[i:i+15], 0, p)
404			}
405		}
406		for j := 0; j < 15; j++ {
407			b[i+j] = 0
408		}
409	}
410}
411
412func TestIndexRune(t *testing.T) {
413	tests := []struct {
414		in   string
415		rune rune
416		want int
417	}{
418		{"", 'a', -1},
419		{"", '☺', -1},
420		{"foo", '☹', -1},
421		{"foo", 'o', 1},
422		{"foo☺bar", '☺', 3},
423		{"foo☺☻☹bar", '☹', 9},
424		{"a A x", 'A', 2},
425		{"some_text=some_value", '=', 9},
426		{"☺a", 'a', 3},
427		{"a☻☺b", '☺', 4},
428
429		// RuneError should match any invalid UTF-8 byte sequence.
430		{"�", '�', 0},
431		{"\xff", '�', 0},
432		{"☻x�", '�', len("☻x")},
433		{"☻x\xe2\x98", '�', len("☻x")},
434		{"☻x\xe2\x98�", '�', len("☻x")},
435		{"☻x\xe2\x98x", '�', len("☻x")},
436
437		// Invalid rune values should never match.
438		{"a☺b☻c☹d\xe2\x98�\xff�\xed\xa0\x80", -1, -1},
439		{"a☺b☻c☹d\xe2\x98�\xff�\xed\xa0\x80", 0xD800, -1}, // Surrogate pair
440		{"a☺b☻c☹d\xe2\x98�\xff�\xed\xa0\x80", utf8.MaxRune + 1, -1},
441	}
442	for _, tt := range tests {
443		if got := IndexRune([]byte(tt.in), tt.rune); got != tt.want {
444			t.Errorf("IndexRune(%q, %d) = %v; want %v", tt.in, tt.rune, got, tt.want)
445		}
446	}
447
448	haystack := []byte("test世界")
449	allocs := testing.AllocsPerRun(1000, func() {
450		if i := IndexRune(haystack, 's'); i != 2 {
451			t.Fatalf("'s' at %d; want 2", i)
452		}
453		if i := IndexRune(haystack, '世'); i != 4 {
454			t.Fatalf("'世' at %d; want 4", i)
455		}
456	})
457	if allocs != 0 {
458		t.Errorf("expected no allocations, got %f", allocs)
459	}
460}
461
462// test count of a single byte across page offsets
463func TestCountByte(t *testing.T) {
464	b := make([]byte, 5015) // bigger than a page
465	windows := []int{1, 2, 3, 4, 15, 16, 17, 31, 32, 33, 63, 64, 65, 128}
466	testCountWindow := func(i, window int) {
467		for j := 0; j < window; j++ {
468			b[i+j] = byte(100)
469			p := Count(b[i:i+window], []byte{100})
470			if p != j+1 {
471				t.Errorf("TestCountByte.Count(%q, 100) = %d", b[i:i+window], p)
472			}
473		}
474	}
475
476	maxWnd := windows[len(windows)-1]
477
478	for i := 0; i <= 2*maxWnd; i++ {
479		for _, window := range windows {
480			if window > len(b[i:]) {
481				window = len(b[i:])
482			}
483			testCountWindow(i, window)
484			for j := 0; j < window; j++ {
485				b[i+j] = byte(0)
486			}
487		}
488	}
489	for i := 4096 - (maxWnd + 1); i < len(b); i++ {
490		for _, window := range windows {
491			if window > len(b[i:]) {
492				window = len(b[i:])
493			}
494			testCountWindow(i, window)
495			for j := 0; j < window; j++ {
496				b[i+j] = byte(0)
497			}
498		}
499	}
500}
501
502// Make sure we don't count bytes outside our window
503func TestCountByteNoMatch(t *testing.T) {
504	b := make([]byte, 5015)
505	windows := []int{1, 2, 3, 4, 15, 16, 17, 31, 32, 33, 63, 64, 65, 128}
506	for i := 0; i <= len(b); i++ {
507		for _, window := range windows {
508			if window > len(b[i:]) {
509				window = len(b[i:])
510			}
511			// Fill the window with non-match
512			for j := 0; j < window; j++ {
513				b[i+j] = byte(100)
514			}
515			// Try to find something that doesn't exist
516			p := Count(b[i:i+window], []byte{0})
517			if p != 0 {
518				t.Errorf("TestCountByteNoMatch(%q, 0) = %d", b[i:i+window], p)
519			}
520			for j := 0; j < window; j++ {
521				b[i+j] = byte(0)
522			}
523		}
524	}
525}
526
527var bmbuf []byte
528
529func valName(x int) string {
530	if s := x >> 20; s<<20 == x {
531		return fmt.Sprintf("%dM", s)
532	}
533	if s := x >> 10; s<<10 == x {
534		return fmt.Sprintf("%dK", s)
535	}
536	return fmt.Sprint(x)
537}
538
539func benchBytes(b *testing.B, sizes []int, f func(b *testing.B, n int)) {
540	for _, n := range sizes {
541		if isRaceBuilder && n > 4<<10 {
542			continue
543		}
544		b.Run(valName(n), func(b *testing.B) {
545			if len(bmbuf) < n {
546				bmbuf = make([]byte, n)
547			}
548			b.SetBytes(int64(n))
549			f(b, n)
550		})
551	}
552}
553
554var indexSizes = []int{10, 32, 4 << 10, 4 << 20, 64 << 20}
555
556var isRaceBuilder = strings.HasSuffix(testenv.Builder(), "-race")
557
558func BenchmarkIndexByte(b *testing.B) {
559	benchBytes(b, indexSizes, bmIndexByte(IndexByte))
560}
561
562func BenchmarkIndexBytePortable(b *testing.B) {
563	benchBytes(b, indexSizes, bmIndexByte(IndexBytePortable))
564}
565
566func bmIndexByte(index func([]byte, byte) int) func(b *testing.B, n int) {
567	return func(b *testing.B, n int) {
568		buf := bmbuf[0:n]
569		buf[n-1] = 'x'
570		for i := 0; i < b.N; i++ {
571			j := index(buf, 'x')
572			if j != n-1 {
573				b.Fatal("bad index", j)
574			}
575		}
576		buf[n-1] = '\x00'
577	}
578}
579
580func BenchmarkIndexRune(b *testing.B) {
581	benchBytes(b, indexSizes, bmIndexRune(IndexRune))
582}
583
584func BenchmarkIndexRuneASCII(b *testing.B) {
585	benchBytes(b, indexSizes, bmIndexRuneASCII(IndexRune))
586}
587
588func bmIndexRuneASCII(index func([]byte, rune) int) func(b *testing.B, n int) {
589	return func(b *testing.B, n int) {
590		buf := bmbuf[0:n]
591		buf[n-1] = 'x'
592		for i := 0; i < b.N; i++ {
593			j := index(buf, 'x')
594			if j != n-1 {
595				b.Fatal("bad index", j)
596			}
597		}
598		buf[n-1] = '\x00'
599	}
600}
601
602func bmIndexRune(index func([]byte, rune) int) func(b *testing.B, n int) {
603	return func(b *testing.B, n int) {
604		buf := bmbuf[0:n]
605		utf8.EncodeRune(buf[n-3:], '世')
606		for i := 0; i < b.N; i++ {
607			j := index(buf, '世')
608			if j != n-3 {
609				b.Fatal("bad index", j)
610			}
611		}
612		buf[n-3] = '\x00'
613		buf[n-2] = '\x00'
614		buf[n-1] = '\x00'
615	}
616}
617
618func BenchmarkEqual(b *testing.B) {
619	b.Run("0", func(b *testing.B) {
620		var buf [4]byte
621		buf1 := buf[0:0]
622		buf2 := buf[1:1]
623		for i := 0; i < b.N; i++ {
624			eq := Equal(buf1, buf2)
625			if !eq {
626				b.Fatal("bad equal")
627			}
628		}
629	})
630
631	sizes := []int{1, 6, 9, 15, 16, 20, 32, 4 << 10, 4 << 20, 64 << 20}
632
633	b.Run("same", func(b *testing.B) {
634		benchBytes(b, sizes, bmEqual(func(a, b []byte) bool { return Equal(a, a) }))
635	})
636
637	benchBytes(b, sizes, bmEqual(Equal))
638}
639
640func bmEqual(equal func([]byte, []byte) bool) func(b *testing.B, n int) {
641	return func(b *testing.B, n int) {
642		if len(bmbuf) < 2*n {
643			bmbuf = make([]byte, 2*n)
644		}
645		buf1 := bmbuf[0:n]
646		buf2 := bmbuf[n : 2*n]
647		buf1[n-1] = 'x'
648		buf2[n-1] = 'x'
649		for i := 0; i < b.N; i++ {
650			eq := equal(buf1, buf2)
651			if !eq {
652				b.Fatal("bad equal")
653			}
654		}
655		buf1[n-1] = '\x00'
656		buf2[n-1] = '\x00'
657	}
658}
659
660func BenchmarkEqualBothUnaligned(b *testing.B) {
661	sizes := []int{64, 4 << 10}
662	if !isRaceBuilder {
663		sizes = append(sizes, []int{4 << 20, 64 << 20}...)
664	}
665	maxSize := 2 * (sizes[len(sizes)-1] + 8)
666	if len(bmbuf) < maxSize {
667		bmbuf = make([]byte, maxSize)
668	}
669
670	for _, n := range sizes {
671		for _, off := range []int{0, 1, 4, 7} {
672			buf1 := bmbuf[off : off+n]
673			buf2Start := (len(bmbuf) / 2) + off
674			buf2 := bmbuf[buf2Start : buf2Start+n]
675			buf1[n-1] = 'x'
676			buf2[n-1] = 'x'
677			b.Run(fmt.Sprint(n, off), func(b *testing.B) {
678				b.SetBytes(int64(n))
679				for i := 0; i < b.N; i++ {
680					eq := Equal(buf1, buf2)
681					if !eq {
682						b.Fatal("bad equal")
683					}
684				}
685			})
686			buf1[n-1] = '\x00'
687			buf2[n-1] = '\x00'
688		}
689	}
690}
691
692func BenchmarkIndex(b *testing.B) {
693	benchBytes(b, indexSizes, func(b *testing.B, n int) {
694		buf := bmbuf[0:n]
695		buf[n-1] = 'x'
696		for i := 0; i < b.N; i++ {
697			j := Index(buf, buf[n-7:])
698			if j != n-7 {
699				b.Fatal("bad index", j)
700			}
701		}
702		buf[n-1] = '\x00'
703	})
704}
705
706func BenchmarkIndexEasy(b *testing.B) {
707	benchBytes(b, indexSizes, func(b *testing.B, n int) {
708		buf := bmbuf[0:n]
709		buf[n-1] = 'x'
710		buf[n-7] = 'x'
711		for i := 0; i < b.N; i++ {
712			j := Index(buf, buf[n-7:])
713			if j != n-7 {
714				b.Fatal("bad index", j)
715			}
716		}
717		buf[n-1] = '\x00'
718		buf[n-7] = '\x00'
719	})
720}
721
722func BenchmarkCount(b *testing.B) {
723	benchBytes(b, indexSizes, func(b *testing.B, n int) {
724		buf := bmbuf[0:n]
725		buf[n-1] = 'x'
726		for i := 0; i < b.N; i++ {
727			j := Count(buf, buf[n-7:])
728			if j != 1 {
729				b.Fatal("bad count", j)
730			}
731		}
732		buf[n-1] = '\x00'
733	})
734}
735
736func BenchmarkCountEasy(b *testing.B) {
737	benchBytes(b, indexSizes, func(b *testing.B, n int) {
738		buf := bmbuf[0:n]
739		buf[n-1] = 'x'
740		buf[n-7] = 'x'
741		for i := 0; i < b.N; i++ {
742			j := Count(buf, buf[n-7:])
743			if j != 1 {
744				b.Fatal("bad count", j)
745			}
746		}
747		buf[n-1] = '\x00'
748		buf[n-7] = '\x00'
749	})
750}
751
752func BenchmarkCountSingle(b *testing.B) {
753	benchBytes(b, indexSizes, func(b *testing.B, n int) {
754		buf := bmbuf[0:n]
755		step := 8
756		for i := 0; i < len(buf); i += step {
757			buf[i] = 1
758		}
759		expect := (len(buf) + (step - 1)) / step
760		for i := 0; i < b.N; i++ {
761			j := Count(buf, []byte{1})
762			if j != expect {
763				b.Fatal("bad count", j, expect)
764			}
765		}
766		for i := 0; i < len(buf); i++ {
767			buf[i] = 0
768		}
769	})
770}
771
772type SplitTest struct {
773	s   string
774	sep string
775	n   int
776	a   []string
777}
778
779var splittests = []SplitTest{
780	{"", "", -1, []string{}},
781	{abcd, "a", 0, nil},
782	{abcd, "", 2, []string{"a", "bcd"}},
783	{abcd, "a", -1, []string{"", "bcd"}},
784	{abcd, "z", -1, []string{"abcd"}},
785	{abcd, "", -1, []string{"a", "b", "c", "d"}},
786	{commas, ",", -1, []string{"1", "2", "3", "4"}},
787	{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
788	{faces, "☹", -1, []string{"☺☻", ""}},
789	{faces, "~", -1, []string{faces}},
790	{faces, "", -1, []string{"☺", "☻", "☹"}},
791	{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
792	{"1 2", " ", 3, []string{"1", "2"}},
793	{"123", "", 2, []string{"1", "23"}},
794	{"123", "", 17, []string{"1", "2", "3"}},
795	{"bT", "T", math.MaxInt / 4, []string{"b", ""}},
796	{"\xff-\xff", "", -1, []string{"\xff", "-", "\xff"}},
797	{"\xff-\xff", "-", -1, []string{"\xff", "\xff"}},
798}
799
800func TestSplit(t *testing.T) {
801	for _, tt := range splittests {
802		a := SplitN([]byte(tt.s), []byte(tt.sep), tt.n)
803
804		// Appending to the results should not change future results.
805		var x []byte
806		for _, v := range a {
807			x = append(v, 'z')
808		}
809
810		result := sliceOfString(a)
811		if !eq(result, tt.a) {
812			t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
813			continue
814		}
815		if tt.n == 0 || len(a) == 0 {
816			continue
817		}
818
819		if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
820			t.Errorf("last appended result was %s; want %s", x, want)
821		}
822
823		s := Join(a, []byte(tt.sep))
824		if string(s) != tt.s {
825			t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
826		}
827		if tt.n < 0 {
828			b := Split([]byte(tt.s), []byte(tt.sep))
829			if !reflect.DeepEqual(a, b) {
830				t.Errorf("Split disagrees withSplitN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
831			}
832		}
833		if len(a) > 0 {
834			in, out := a[0], s
835			if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] {
836				t.Errorf("Join(%#v, %q) didn't copy", a, tt.sep)
837			}
838		}
839	}
840}
841
842var splitaftertests = []SplitTest{
843	{abcd, "a", -1, []string{"a", "bcd"}},
844	{abcd, "z", -1, []string{"abcd"}},
845	{abcd, "", -1, []string{"a", "b", "c", "d"}},
846	{commas, ",", -1, []string{"1,", "2,", "3,", "4"}},
847	{dots, "...", -1, []string{"1...", ".2...", ".3...", ".4"}},
848	{faces, "☹", -1, []string{"☺☻☹", ""}},
849	{faces, "~", -1, []string{faces}},
850	{faces, "", -1, []string{"☺", "☻", "☹"}},
851	{"1 2 3 4", " ", 3, []string{"1 ", "2 ", "3 4"}},
852	{"1 2 3", " ", 3, []string{"1 ", "2 ", "3"}},
853	{"1 2", " ", 3, []string{"1 ", "2"}},
854	{"123", "", 2, []string{"1", "23"}},
855	{"123", "", 17, []string{"1", "2", "3"}},
856}
857
858func TestSplitAfter(t *testing.T) {
859	for _, tt := range splitaftertests {
860		a := SplitAfterN([]byte(tt.s), []byte(tt.sep), tt.n)
861
862		// Appending to the results should not change future results.
863		var x []byte
864		for _, v := range a {
865			x = append(v, 'z')
866		}
867
868		result := sliceOfString(a)
869		if !eq(result, tt.a) {
870			t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
871			continue
872		}
873
874		if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
875			t.Errorf("last appended result was %s; want %s", x, want)
876		}
877
878		s := Join(a, nil)
879		if string(s) != tt.s {
880			t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
881		}
882		if tt.n < 0 {
883			b := SplitAfter([]byte(tt.s), []byte(tt.sep))
884			if !reflect.DeepEqual(a, b) {
885				t.Errorf("SplitAfter disagrees withSplitAfterN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
886			}
887		}
888	}
889}
890
891type FieldsTest struct {
892	s string
893	a []string
894}
895
896var fieldstests = []FieldsTest{
897	{"", []string{}},
898	{" ", []string{}},
899	{" \t ", []string{}},
900	{"  abc  ", []string{"abc"}},
901	{"1 2 3 4", []string{"1", "2", "3", "4"}},
902	{"1  2  3  4", []string{"1", "2", "3", "4"}},
903	{"1\t\t2\t\t3\t4", []string{"1", "2", "3", "4"}},
904	{"1\u20002\u20013\u20024", []string{"1", "2", "3", "4"}},
905	{"\u2000\u2001\u2002", []string{}},
906	{"\n™\t™\n", []string{"™", "™"}},
907	{faces, []string{faces}},
908}
909
910func TestFields(t *testing.T) {
911	for _, tt := range fieldstests {
912		b := []byte(tt.s)
913		a := Fields(b)
914
915		// Appending to the results should not change future results.
916		var x []byte
917		for _, v := range a {
918			x = append(v, 'z')
919		}
920
921		result := sliceOfString(a)
922		if !eq(result, tt.a) {
923			t.Errorf("Fields(%q) = %v; want %v", tt.s, a, tt.a)
924			continue
925		}
926
927		if string(b) != tt.s {
928			t.Errorf("slice changed to %s; want %s", string(b), tt.s)
929		}
930		if len(tt.a) > 0 {
931			if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
932				t.Errorf("last appended result was %s; want %s", x, want)
933			}
934		}
935	}
936}
937
938func TestFieldsFunc(t *testing.T) {
939	for _, tt := range fieldstests {
940		a := FieldsFunc([]byte(tt.s), unicode.IsSpace)
941		result := sliceOfString(a)
942		if !eq(result, tt.a) {
943			t.Errorf("FieldsFunc(%q, unicode.IsSpace) = %v; want %v", tt.s, a, tt.a)
944			continue
945		}
946	}
947	pred := func(c rune) bool { return c == 'X' }
948	var fieldsFuncTests = []FieldsTest{
949		{"", []string{}},
950		{"XX", []string{}},
951		{"XXhiXXX", []string{"hi"}},
952		{"aXXbXXXcX", []string{"a", "b", "c"}},
953	}
954	for _, tt := range fieldsFuncTests {
955		b := []byte(tt.s)
956		a := FieldsFunc(b, pred)
957
958		// Appending to the results should not change future results.
959		var x []byte
960		for _, v := range a {
961			x = append(v, 'z')
962		}
963
964		result := sliceOfString(a)
965		if !eq(result, tt.a) {
966			t.Errorf("FieldsFunc(%q) = %v, want %v", tt.s, a, tt.a)
967		}
968
969		if string(b) != tt.s {
970			t.Errorf("slice changed to %s; want %s", b, tt.s)
971		}
972		if len(tt.a) > 0 {
973			if want := tt.a[len(tt.a)-1] + "z"; string(x) != want {
974				t.Errorf("last appended result was %s; want %s", x, want)
975			}
976		}
977	}
978}
979
980// Test case for any function which accepts and returns a byte slice.
981// For ease of creation, we write the input byte slice as a string.
982type StringTest struct {
983	in  string
984	out []byte
985}
986
987var upperTests = []StringTest{
988	{"", []byte("")},
989	{"ONLYUPPER", []byte("ONLYUPPER")},
990	{"abc", []byte("ABC")},
991	{"AbC123", []byte("ABC123")},
992	{"azAZ09_", []byte("AZAZ09_")},
993	{"longStrinGwitHmixofsmaLLandcAps", []byte("LONGSTRINGWITHMIXOFSMALLANDCAPS")},
994	{"long\u0250string\u0250with\u0250nonascii\u2C6Fchars", []byte("LONG\u2C6FSTRING\u2C6FWITH\u2C6FNONASCII\u2C6FCHARS")},
995	{"\u0250\u0250\u0250\u0250\u0250", []byte("\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F")}, // grows one byte per char
996	{"a\u0080\U0010FFFF", []byte("A\u0080\U0010FFFF")},                           // test utf8.RuneSelf and utf8.MaxRune
997}
998
999var lowerTests = []StringTest{
1000	{"", []byte("")},
1001	{"abc", []byte("abc")},
1002	{"AbC123", []byte("abc123")},
1003	{"azAZ09_", []byte("azaz09_")},
1004	{"longStrinGwitHmixofsmaLLandcAps", []byte("longstringwithmixofsmallandcaps")},
1005	{"LONG\u2C6FSTRING\u2C6FWITH\u2C6FNONASCII\u2C6FCHARS", []byte("long\u0250string\u0250with\u0250nonascii\u0250chars")},
1006	{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", []byte("\u0251\u0251\u0251\u0251\u0251")}, // shrinks one byte per char
1007	{"A\u0080\U0010FFFF", []byte("a\u0080\U0010FFFF")},                           // test utf8.RuneSelf and utf8.MaxRune
1008}
1009
1010const space = "\t\v\r\f\n\u0085\u00a0\u2000\u3000"
1011
1012var trimSpaceTests = []StringTest{
1013	{"", nil},
1014	{"  a", []byte("a")},
1015	{"b  ", []byte("b")},
1016	{"abc", []byte("abc")},
1017	{space + "abc" + space, []byte("abc")},
1018	{" ", nil},
1019	{"\u3000 ", nil},
1020	{" \u3000", nil},
1021	{" \t\r\n \t\t\r\r\n\n ", nil},
1022	{" \t\r\n x\t\t\r\r\n\n ", []byte("x")},
1023	{" \u2000\t\r\n x\t\t\r\r\ny\n \u3000", []byte("x\t\t\r\r\ny")},
1024	{"1 \t\r\n2", []byte("1 \t\r\n2")},
1025	{" x\x80", []byte("x\x80")},
1026	{" x\xc0", []byte("x\xc0")},
1027	{"x \xc0\xc0 ", []byte("x \xc0\xc0")},
1028	{"x \xc0", []byte("x \xc0")},
1029	{"x \xc0 ", []byte("x \xc0")},
1030	{"x \xc0\xc0 ", []byte("x \xc0\xc0")},
1031	{"x ☺\xc0\xc0 ", []byte("x ☺\xc0\xc0")},
1032	{"x ☺ ", []byte("x ☺")},
1033}
1034
1035// Execute f on each test case.  funcName should be the name of f; it's used
1036// in failure reports.
1037func runStringTests(t *testing.T, f func([]byte) []byte, funcName string, testCases []StringTest) {
1038	for _, tc := range testCases {
1039		actual := f([]byte(tc.in))
1040		if actual == nil && tc.out != nil {
1041			t.Errorf("%s(%q) = nil; want %q", funcName, tc.in, tc.out)
1042		}
1043		if actual != nil && tc.out == nil {
1044			t.Errorf("%s(%q) = %q; want nil", funcName, tc.in, actual)
1045		}
1046		if !Equal(actual, tc.out) {
1047			t.Errorf("%s(%q) = %q; want %q", funcName, tc.in, actual, tc.out)
1048		}
1049	}
1050}
1051
1052func tenRunes(r rune) string {
1053	runes := make([]rune, 10)
1054	for i := range runes {
1055		runes[i] = r
1056	}
1057	return string(runes)
1058}
1059
1060// User-defined self-inverse mapping function
1061func rot13(r rune) rune {
1062	const step = 13
1063	if r >= 'a' && r <= 'z' {
1064		return ((r - 'a' + step) % 26) + 'a'
1065	}
1066	if r >= 'A' && r <= 'Z' {
1067		return ((r - 'A' + step) % 26) + 'A'
1068	}
1069	return r
1070}
1071
1072func TestMap(t *testing.T) {
1073	// Run a couple of awful growth/shrinkage tests
1074	a := tenRunes('a')
1075
1076	// 1.  Grow. This triggers two reallocations in Map.
1077	maxRune := func(r rune) rune { return unicode.MaxRune }
1078	m := Map(maxRune, []byte(a))
1079	expect := tenRunes(unicode.MaxRune)
1080	if string(m) != expect {
1081		t.Errorf("growing: expected %q got %q", expect, m)
1082	}
1083
1084	// 2. Shrink
1085	minRune := func(r rune) rune { return 'a' }
1086	m = Map(minRune, []byte(tenRunes(unicode.MaxRune)))
1087	expect = a
1088	if string(m) != expect {
1089		t.Errorf("shrinking: expected %q got %q", expect, m)
1090	}
1091
1092	// 3. Rot13
1093	m = Map(rot13, []byte("a to zed"))
1094	expect = "n gb mrq"
1095	if string(m) != expect {
1096		t.Errorf("rot13: expected %q got %q", expect, m)
1097	}
1098
1099	// 4. Rot13^2
1100	m = Map(rot13, Map(rot13, []byte("a to zed")))
1101	expect = "a to zed"
1102	if string(m) != expect {
1103		t.Errorf("rot13: expected %q got %q", expect, m)
1104	}
1105
1106	// 5. Drop
1107	dropNotLatin := func(r rune) rune {
1108		if unicode.Is(unicode.Latin, r) {
1109			return r
1110		}
1111		return -1
1112	}
1113	m = Map(dropNotLatin, []byte("Hello, 세계"))
1114	expect = "Hello"
1115	if string(m) != expect {
1116		t.Errorf("drop: expected %q got %q", expect, m)
1117	}
1118
1119	// 6. Invalid rune
1120	invalidRune := func(r rune) rune {
1121		return utf8.MaxRune + 1
1122	}
1123	m = Map(invalidRune, []byte("x"))
1124	expect = "\uFFFD"
1125	if string(m) != expect {
1126		t.Errorf("invalidRune: expected %q got %q", expect, m)
1127	}
1128}
1129
1130func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
1131
1132func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
1133
1134func BenchmarkToUpper(b *testing.B) {
1135	for _, tc := range upperTests {
1136		tin := []byte(tc.in)
1137		b.Run(tc.in, func(b *testing.B) {
1138			for i := 0; i < b.N; i++ {
1139				actual := ToUpper(tin)
1140				if !Equal(actual, tc.out) {
1141					b.Errorf("ToUpper(%q) = %q; want %q", tc.in, actual, tc.out)
1142				}
1143			}
1144		})
1145	}
1146}
1147
1148func BenchmarkToLower(b *testing.B) {
1149	for _, tc := range lowerTests {
1150		tin := []byte(tc.in)
1151		b.Run(tc.in, func(b *testing.B) {
1152			for i := 0; i < b.N; i++ {
1153				actual := ToLower(tin)
1154				if !Equal(actual, tc.out) {
1155					b.Errorf("ToLower(%q) = %q; want %q", tc.in, actual, tc.out)
1156				}
1157			}
1158		})
1159	}
1160}
1161
1162var toValidUTF8Tests = []struct {
1163	in   string
1164	repl string
1165	out  string
1166}{
1167	{"", "\uFFFD", ""},
1168	{"abc", "\uFFFD", "abc"},
1169	{"\uFDDD", "\uFFFD", "\uFDDD"},
1170	{"a\xffb", "\uFFFD", "a\uFFFDb"},
1171	{"a\xffb\uFFFD", "X", "aXb\uFFFD"},
1172	{"a☺\xffb☺\xC0\xAFc☺\xff", "", "a☺b☺c☺"},
1173	{"a☺\xffb☺\xC0\xAFc☺\xff", "日本語", "a☺日本語b☺日本語c☺日本語"},
1174	{"\xC0\xAF", "\uFFFD", "\uFFFD"},
1175	{"\xE0\x80\xAF", "\uFFFD", "\uFFFD"},
1176	{"\xed\xa0\x80", "abc", "abc"},
1177	{"\xed\xbf\xbf", "\uFFFD", "\uFFFD"},
1178	{"\xF0\x80\x80\xaf", "☺", "☺"},
1179	{"\xF8\x80\x80\x80\xAF", "\uFFFD", "\uFFFD"},
1180	{"\xFC\x80\x80\x80\x80\xAF", "\uFFFD", "\uFFFD"},
1181}
1182
1183func TestToValidUTF8(t *testing.T) {
1184	for _, tc := range toValidUTF8Tests {
1185		got := ToValidUTF8([]byte(tc.in), []byte(tc.repl))
1186		if !Equal(got, []byte(tc.out)) {
1187			t.Errorf("ToValidUTF8(%q, %q) = %q; want %q", tc.in, tc.repl, got, tc.out)
1188		}
1189	}
1190}
1191
1192func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) }
1193
1194type RepeatTest struct {
1195	in, out string
1196	count   int
1197}
1198
1199var longString = "a" + string(make([]byte, 1<<16)) + "z"
1200
1201var RepeatTests = []RepeatTest{
1202	{"", "", 0},
1203	{"", "", 1},
1204	{"", "", 2},
1205	{"-", "", 0},
1206	{"-", "-", 1},
1207	{"-", "----------", 10},
1208	{"abc ", "abc abc abc ", 3},
1209	// Tests for results over the chunkLimit
1210	{string(rune(0)), string(make([]byte, 1<<16)), 1 << 16},
1211	{longString, longString + longString, 2},
1212}
1213
1214func TestRepeat(t *testing.T) {
1215	for _, tt := range RepeatTests {
1216		tin := []byte(tt.in)
1217		tout := []byte(tt.out)
1218		a := Repeat(tin, tt.count)
1219		if !Equal(a, tout) {
1220			t.Errorf("Repeat(%q, %d) = %q; want %q", tin, tt.count, a, tout)
1221			continue
1222		}
1223	}
1224}
1225
1226func repeat(b []byte, count int) (err error) {
1227	defer func() {
1228		if r := recover(); r != nil {
1229			switch v := r.(type) {
1230			case error:
1231				err = v
1232			default:
1233				err = fmt.Errorf("%s", v)
1234			}
1235		}
1236	}()
1237
1238	Repeat(b, count)
1239
1240	return
1241}
1242
1243// See Issue golang.org/issue/16237
1244func TestRepeatCatchesOverflow(t *testing.T) {
1245	type testCase struct {
1246		s      string
1247		count  int
1248		errStr string
1249	}
1250
1251	runTestCases := func(prefix string, tests []testCase) {
1252		for i, tt := range tests {
1253			err := repeat([]byte(tt.s), tt.count)
1254			if tt.errStr == "" {
1255				if err != nil {
1256					t.Errorf("#%d panicked %v", i, err)
1257				}
1258				continue
1259			}
1260
1261			if err == nil || !strings.Contains(err.Error(), tt.errStr) {
1262				t.Errorf("%s#%d got %q want %q", prefix, i, err, tt.errStr)
1263			}
1264		}
1265	}
1266
1267	const maxInt = int(^uint(0) >> 1)
1268
1269	runTestCases("", []testCase{
1270		0: {"--", -2147483647, "negative"},
1271		1: {"", maxInt, ""},
1272		2: {"-", 10, ""},
1273		3: {"gopher", 0, ""},
1274		4: {"-", -1, "negative"},
1275		5: {"--", -102, "negative"},
1276		6: {string(make([]byte, 255)), int((^uint(0))/255 + 1), "overflow"},
1277	})
1278
1279	const is64Bit = 1<<(^uintptr(0)>>63)/2 != 0
1280	if !is64Bit {
1281		return
1282	}
1283
1284	runTestCases("64-bit", []testCase{
1285		0: {"-", maxInt, "out of range"},
1286	})
1287}
1288
1289func runesEqual(a, b []rune) bool {
1290	if len(a) != len(b) {
1291		return false
1292	}
1293	for i, r := range a {
1294		if r != b[i] {
1295			return false
1296		}
1297	}
1298	return true
1299}
1300
1301type RunesTest struct {
1302	in    string
1303	out   []rune
1304	lossy bool
1305}
1306
1307var RunesTests = []RunesTest{
1308	{"", []rune{}, false},
1309	{" ", []rune{32}, false},
1310	{"ABC", []rune{65, 66, 67}, false},
1311	{"abc", []rune{97, 98, 99}, false},
1312	{"\u65e5\u672c\u8a9e", []rune{26085, 26412, 35486}, false},
1313	{"ab\x80c", []rune{97, 98, 0xFFFD, 99}, true},
1314	{"ab\xc0c", []rune{97, 98, 0xFFFD, 99}, true},
1315}
1316
1317func TestRunes(t *testing.T) {
1318	for _, tt := range RunesTests {
1319		tin := []byte(tt.in)
1320		a := Runes(tin)
1321		if !runesEqual(a, tt.out) {
1322			t.Errorf("Runes(%q) = %v; want %v", tin, a, tt.out)
1323			continue
1324		}
1325		if !tt.lossy {
1326			// can only test reassembly if we didn't lose information
1327			s := string(a)
1328			if s != tt.in {
1329				t.Errorf("string(Runes(%q)) = %x; want %x", tin, s, tin)
1330			}
1331		}
1332	}
1333}
1334
1335type TrimTest struct {
1336	f            string
1337	in, arg, out string
1338}
1339
1340var trimTests = []TrimTest{
1341	{"Trim", "abba", "a", "bb"},
1342	{"Trim", "abba", "ab", ""},
1343	{"TrimLeft", "abba", "ab", ""},
1344	{"TrimRight", "abba", "ab", ""},
1345	{"TrimLeft", "abba", "a", "bba"},
1346	{"TrimLeft", "abba", "b", "abba"},
1347	{"TrimRight", "abba", "a", "abb"},
1348	{"TrimRight", "abba", "b", "abba"},
1349	{"Trim", "<tag>", "<>", "tag"},
1350	{"Trim", "* listitem", " *", "listitem"},
1351	{"Trim", `"quote"`, `"`, "quote"},
1352	{"Trim", "\u2C6F\u2C6F\u0250\u0250\u2C6F\u2C6F", "\u2C6F", "\u0250\u0250"},
1353	{"Trim", "\x80test\xff", "\xff", "test"},
1354	{"Trim", " Ġ ", " ", "Ġ"},
1355	{"Trim", " Ġİ0", "0 ", "Ġİ"},
1356	//empty string tests
1357	{"Trim", "abba", "", "abba"},
1358	{"Trim", "", "123", ""},
1359	{"Trim", "", "", ""},
1360	{"TrimLeft", "abba", "", "abba"},
1361	{"TrimLeft", "", "123", ""},
1362	{"TrimLeft", "", "", ""},
1363	{"TrimRight", "abba", "", "abba"},
1364	{"TrimRight", "", "123", ""},
1365	{"TrimRight", "", "", ""},
1366	{"TrimRight", "☺\xc0", "", "☺\xc0"},
1367	{"TrimPrefix", "aabb", "a", "abb"},
1368	{"TrimPrefix", "aabb", "b", "aabb"},
1369	{"TrimSuffix", "aabb", "a", "aabb"},
1370	{"TrimSuffix", "aabb", "b", "aab"},
1371}
1372
1373type TrimNilTest struct {
1374	f   string
1375	in  []byte
1376	arg string
1377	out []byte
1378}
1379
1380var trimNilTests = []TrimNilTest{
1381	{"Trim", nil, "", nil},
1382	{"Trim", []byte{}, "", nil},
1383	{"Trim", []byte{'a'}, "a", nil},
1384	{"Trim", []byte{'a', 'a'}, "a", nil},
1385	{"Trim", []byte{'a'}, "ab", nil},
1386	{"Trim", []byte{'a', 'b'}, "ab", nil},
1387	{"Trim", []byte(""), "", nil},
1388	{"TrimLeft", nil, "", nil},
1389	{"TrimLeft", []byte{}, "", nil},
1390	{"TrimLeft", []byte{'a'}, "a", nil},
1391	{"TrimLeft", []byte{'a', 'a'}, "a", nil},
1392	{"TrimLeft", []byte{'a'}, "ab", nil},
1393	{"TrimLeft", []byte{'a', 'b'}, "ab", nil},
1394	{"TrimLeft", []byte(""), "", nil},
1395	{"TrimRight", nil, "", nil},
1396	{"TrimRight", []byte{}, "", []byte{}},
1397	{"TrimRight", []byte{'a'}, "a", []byte{}},
1398	{"TrimRight", []byte{'a', 'a'}, "a", []byte{}},
1399	{"TrimRight", []byte{'a'}, "ab", []byte{}},
1400	{"TrimRight", []byte{'a', 'b'}, "ab", []byte{}},
1401	{"TrimRight", []byte(""), "", []byte{}},
1402	{"TrimPrefix", nil, "", nil},
1403	{"TrimPrefix", []byte{}, "", []byte{}},
1404	{"TrimPrefix", []byte{'a'}, "a", []byte{}},
1405	{"TrimPrefix", []byte(""), "", []byte{}},
1406	{"TrimSuffix", nil, "", nil},
1407	{"TrimSuffix", []byte{}, "", []byte{}},
1408	{"TrimSuffix", []byte{'a'}, "a", []byte{}},
1409	{"TrimSuffix", []byte(""), "", []byte{}},
1410}
1411
1412func TestTrim(t *testing.T) {
1413	toFn := func(name string) (func([]byte, string) []byte, func([]byte, []byte) []byte) {
1414		switch name {
1415		case "Trim":
1416			return Trim, nil
1417		case "TrimLeft":
1418			return TrimLeft, nil
1419		case "TrimRight":
1420			return TrimRight, nil
1421		case "TrimPrefix":
1422			return nil, TrimPrefix
1423		case "TrimSuffix":
1424			return nil, TrimSuffix
1425		default:
1426			t.Errorf("Undefined trim function %s", name)
1427			return nil, nil
1428		}
1429	}
1430
1431	for _, tc := range trimTests {
1432		name := tc.f
1433		f, fb := toFn(name)
1434		if f == nil && fb == nil {
1435			continue
1436		}
1437		var actual string
1438		if f != nil {
1439			actual = string(f([]byte(tc.in), tc.arg))
1440		} else {
1441			actual = string(fb([]byte(tc.in), []byte(tc.arg)))
1442		}
1443		if actual != tc.out {
1444			t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out)
1445		}
1446	}
1447
1448	for _, tc := range trimNilTests {
1449		name := tc.f
1450		f, fb := toFn(name)
1451		if f == nil && fb == nil {
1452			continue
1453		}
1454		var actual []byte
1455		if f != nil {
1456			actual = f(tc.in, tc.arg)
1457		} else {
1458			actual = fb(tc.in, []byte(tc.arg))
1459		}
1460		report := func(s []byte) string {
1461			if s == nil {
1462				return "nil"
1463			} else {
1464				return fmt.Sprintf("%q", s)
1465			}
1466		}
1467		if len(actual) != 0 {
1468			t.Errorf("%s(%s, %q) returned non-empty value", name, report(tc.in), tc.arg)
1469		} else {
1470			actualNil := actual == nil
1471			outNil := tc.out == nil
1472			if actualNil != outNil {
1473				t.Errorf("%s(%s, %q) got nil %t; want nil %t", name, report(tc.in), tc.arg, actualNil, outNil)
1474			}
1475		}
1476	}
1477}
1478
1479type predicate struct {
1480	f    func(r rune) bool
1481	name string
1482}
1483
1484var isSpace = predicate{unicode.IsSpace, "IsSpace"}
1485var isDigit = predicate{unicode.IsDigit, "IsDigit"}
1486var isUpper = predicate{unicode.IsUpper, "IsUpper"}
1487var isValidRune = predicate{
1488	func(r rune) bool {
1489		return r != utf8.RuneError
1490	},
1491	"IsValidRune",
1492}
1493
1494type TrimFuncTest struct {
1495	f        predicate
1496	in       string
1497	trimOut  []byte
1498	leftOut  []byte
1499	rightOut []byte
1500}
1501
1502func not(p predicate) predicate {
1503	return predicate{
1504		func(r rune) bool {
1505			return !p.f(r)
1506		},
1507		"not " + p.name,
1508	}
1509}
1510
1511var trimFuncTests = []TrimFuncTest{
1512	{isSpace, space + " hello " + space,
1513		[]byte("hello"),
1514		[]byte("hello " + space),
1515		[]byte(space + " hello")},
1516	{isDigit, "\u0e50\u0e5212hello34\u0e50\u0e51",
1517		[]byte("hello"),
1518		[]byte("hello34\u0e50\u0e51"),
1519		[]byte("\u0e50\u0e5212hello")},
1520	{isUpper, "\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F",
1521		[]byte("hello"),
1522		[]byte("helloEF\u2C6F\u2C6FGH\u2C6F\u2C6F"),
1523		[]byte("\u2C6F\u2C6F\u2C6F\u2C6FABCDhello")},
1524	{not(isSpace), "hello" + space + "hello",
1525		[]byte(space),
1526		[]byte(space + "hello"),
1527		[]byte("hello" + space)},
1528	{not(isDigit), "hello\u0e50\u0e521234\u0e50\u0e51helo",
1529		[]byte("\u0e50\u0e521234\u0e50\u0e51"),
1530		[]byte("\u0e50\u0e521234\u0e50\u0e51helo"),
1531		[]byte("hello\u0e50\u0e521234\u0e50\u0e51")},
1532	{isValidRune, "ab\xc0a\xc0cd",
1533		[]byte("\xc0a\xc0"),
1534		[]byte("\xc0a\xc0cd"),
1535		[]byte("ab\xc0a\xc0")},
1536	{not(isValidRune), "\xc0a\xc0",
1537		[]byte("a"),
1538		[]byte("a\xc0"),
1539		[]byte("\xc0a")},
1540	// The nils returned by TrimLeftFunc are odd behavior, but we need
1541	// to preserve backwards compatibility.
1542	{isSpace, "",
1543		nil,
1544		nil,
1545		[]byte("")},
1546	{isSpace, " ",
1547		nil,
1548		nil,
1549		[]byte("")},
1550}
1551
1552func TestTrimFunc(t *testing.T) {
1553	for _, tc := range trimFuncTests {
1554		trimmers := []struct {
1555			name string
1556			trim func(s []byte, f func(r rune) bool) []byte
1557			out  []byte
1558		}{
1559			{"TrimFunc", TrimFunc, tc.trimOut},
1560			{"TrimLeftFunc", TrimLeftFunc, tc.leftOut},
1561			{"TrimRightFunc", TrimRightFunc, tc.rightOut},
1562		}
1563		for _, trimmer := range trimmers {
1564			actual := trimmer.trim([]byte(tc.in), tc.f.f)
1565			if actual == nil && trimmer.out != nil {
1566				t.Errorf("%s(%q, %q) = nil; want %q", trimmer.name, tc.in, tc.f.name, trimmer.out)
1567			}
1568			if actual != nil && trimmer.out == nil {
1569				t.Errorf("%s(%q, %q) = %q; want nil", trimmer.name, tc.in, tc.f.name, actual)
1570			}
1571			if !Equal(actual, trimmer.out) {
1572				t.Errorf("%s(%q, %q) = %q; want %q", trimmer.name, tc.in, tc.f.name, actual, trimmer.out)
1573			}
1574		}
1575	}
1576}
1577
1578type IndexFuncTest struct {
1579	in          string
1580	f           predicate
1581	first, last int
1582}
1583
1584var indexFuncTests = []IndexFuncTest{
1585	{"", isValidRune, -1, -1},
1586	{"abc", isDigit, -1, -1},
1587	{"0123", isDigit, 0, 3},
1588	{"a1b", isDigit, 1, 1},
1589	{space, isSpace, 0, len(space) - 3}, // last rune in space is 3 bytes
1590	{"\u0e50\u0e5212hello34\u0e50\u0e51", isDigit, 0, 18},
1591	{"\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", isUpper, 0, 34},
1592	{"12\u0e50\u0e52hello34\u0e50\u0e51", not(isDigit), 8, 12},
1593
1594	// tests of invalid UTF-8
1595	{"\x801", isDigit, 1, 1},
1596	{"\x80abc", isDigit, -1, -1},
1597	{"\xc0a\xc0", isValidRune, 1, 1},
1598	{"\xc0a\xc0", not(isValidRune), 0, 2},
1599	{"\xc0☺\xc0", not(isValidRune), 0, 4},
1600	{"\xc0☺\xc0\xc0", not(isValidRune), 0, 5},
1601	{"ab\xc0a\xc0cd", not(isValidRune), 2, 4},
1602	{"a\xe0\x80cd", not(isValidRune), 1, 2},
1603}
1604
1605func TestIndexFunc(t *testing.T) {
1606	for _, tc := range indexFuncTests {
1607		first := IndexFunc([]byte(tc.in), tc.f.f)
1608		if first != tc.first {
1609			t.Errorf("IndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, first, tc.first)
1610		}
1611		last := LastIndexFunc([]byte(tc.in), tc.f.f)
1612		if last != tc.last {
1613			t.Errorf("LastIndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, last, tc.last)
1614		}
1615	}
1616}
1617
1618type ReplaceTest struct {
1619	in       string
1620	old, new string
1621	n        int
1622	out      string
1623}
1624
1625var ReplaceTests = []ReplaceTest{
1626	{"hello", "l", "L", 0, "hello"},
1627	{"hello", "l", "L", -1, "heLLo"},
1628	{"hello", "x", "X", -1, "hello"},
1629	{"", "x", "X", -1, ""},
1630	{"radar", "r", "<r>", -1, "<r>ada<r>"},
1631	{"", "", "<>", -1, "<>"},
1632	{"banana", "a", "<>", -1, "b<>n<>n<>"},
1633	{"banana", "a", "<>", 1, "b<>nana"},
1634	{"banana", "a", "<>", 1000, "b<>n<>n<>"},
1635	{"banana", "an", "<>", -1, "b<><>a"},
1636	{"banana", "ana", "<>", -1, "b<>na"},
1637	{"banana", "", "<>", -1, "<>b<>a<>n<>a<>n<>a<>"},
1638	{"banana", "", "<>", 10, "<>b<>a<>n<>a<>n<>a<>"},
1639	{"banana", "", "<>", 6, "<>b<>a<>n<>a<>n<>a"},
1640	{"banana", "", "<>", 5, "<>b<>a<>n<>a<>na"},
1641	{"banana", "", "<>", 1, "<>banana"},
1642	{"banana", "a", "a", -1, "banana"},
1643	{"banana", "a", "a", 1, "banana"},
1644	{"☺☻☹", "", "<>", -1, "<>☺<>☻<>☹<>"},
1645}
1646
1647func TestReplace(t *testing.T) {
1648	for _, tt := range ReplaceTests {
1649		in := append([]byte(tt.in), "<spare>"...)
1650		in = in[:len(tt.in)]
1651		out := Replace(in, []byte(tt.old), []byte(tt.new), tt.n)
1652		if s := string(out); s != tt.out {
1653			t.Errorf("Replace(%q, %q, %q, %d) = %q, want %q", tt.in, tt.old, tt.new, tt.n, s, tt.out)
1654		}
1655		if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] {
1656			t.Errorf("Replace(%q, %q, %q, %d) didn't copy", tt.in, tt.old, tt.new, tt.n)
1657		}
1658		if tt.n == -1 {
1659			out := ReplaceAll(in, []byte(tt.old), []byte(tt.new))
1660			if s := string(out); s != tt.out {
1661				t.Errorf("ReplaceAll(%q, %q, %q) = %q, want %q", tt.in, tt.old, tt.new, s, tt.out)
1662			}
1663		}
1664	}
1665}
1666
1667type TitleTest struct {
1668	in, out string
1669}
1670
1671var TitleTests = []TitleTest{
1672	{"", ""},
1673	{"a", "A"},
1674	{" aaa aaa aaa ", " Aaa Aaa Aaa "},
1675	{" Aaa Aaa Aaa ", " Aaa Aaa Aaa "},
1676	{"123a456", "123a456"},
1677	{"double-blind", "Double-Blind"},
1678	{"ÿøû", "Ÿøû"},
1679	{"with_underscore", "With_underscore"},
1680	{"unicode \xe2\x80\xa8 line separator", "Unicode \xe2\x80\xa8 Line Separator"},
1681}
1682
1683func TestTitle(t *testing.T) {
1684	for _, tt := range TitleTests {
1685		if s := string(Title([]byte(tt.in))); s != tt.out {
1686			t.Errorf("Title(%q) = %q, want %q", tt.in, s, tt.out)
1687		}
1688	}
1689}
1690
1691var ToTitleTests = []TitleTest{
1692	{"", ""},
1693	{"a", "A"},
1694	{" aaa aaa aaa ", " AAA AAA AAA "},
1695	{" Aaa Aaa Aaa ", " AAA AAA AAA "},
1696	{"123a456", "123A456"},
1697	{"double-blind", "DOUBLE-BLIND"},
1698	{"ÿøû", "ŸØÛ"},
1699}
1700
1701func TestToTitle(t *testing.T) {
1702	for _, tt := range ToTitleTests {
1703		if s := string(ToTitle([]byte(tt.in))); s != tt.out {
1704			t.Errorf("ToTitle(%q) = %q, want %q", tt.in, s, tt.out)
1705		}
1706	}
1707}
1708
1709var EqualFoldTests = []struct {
1710	s, t string
1711	out  bool
1712}{
1713	{"abc", "abc", true},
1714	{"ABcd", "ABcd", true},
1715	{"123abc", "123ABC", true},
1716	{"αβδ", "ΑΒΔ", true},
1717	{"abc", "xyz", false},
1718	{"abc", "XYZ", false},
1719	{"abcdefghijk", "abcdefghijX", false},
1720	{"abcdefghijk", "abcdefghij\u212A", true},
1721	{"abcdefghijK", "abcdefghij\u212A", true},
1722	{"abcdefghijkz", "abcdefghij\u212Ay", false},
1723	{"abcdefghijKz", "abcdefghij\u212Ay", false},
1724}
1725
1726func TestEqualFold(t *testing.T) {
1727	for _, tt := range EqualFoldTests {
1728		if out := EqualFold([]byte(tt.s), []byte(tt.t)); out != tt.out {
1729			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.s, tt.t, out, tt.out)
1730		}
1731		if out := EqualFold([]byte(tt.t), []byte(tt.s)); out != tt.out {
1732			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.t, tt.s, out, tt.out)
1733		}
1734	}
1735}
1736
1737var cutTests = []struct {
1738	s, sep        string
1739	before, after string
1740	found         bool
1741}{
1742	{"abc", "b", "a", "c", true},
1743	{"abc", "a", "", "bc", true},
1744	{"abc", "c", "ab", "", true},
1745	{"abc", "abc", "", "", true},
1746	{"abc", "", "", "abc", true},
1747	{"abc", "d", "abc", "", false},
1748	{"", "d", "", "", false},
1749	{"", "", "", "", true},
1750}
1751
1752func TestCut(t *testing.T) {
1753	for _, tt := range cutTests {
1754		if before, after, found := Cut([]byte(tt.s), []byte(tt.sep)); string(before) != tt.before || string(after) != tt.after || found != tt.found {
1755			t.Errorf("Cut(%q, %q) = %q, %q, %v, want %q, %q, %v", tt.s, tt.sep, before, after, found, tt.before, tt.after, tt.found)
1756		}
1757	}
1758}
1759
1760var cutPrefixTests = []struct {
1761	s, sep string
1762	after  string
1763	found  bool
1764}{
1765	{"abc", "a", "bc", true},
1766	{"abc", "abc", "", true},
1767	{"abc", "", "abc", true},
1768	{"abc", "d", "abc", false},
1769	{"", "d", "", false},
1770	{"", "", "", true},
1771}
1772
1773func TestCutPrefix(t *testing.T) {
1774	for _, tt := range cutPrefixTests {
1775		if after, found := CutPrefix([]byte(tt.s), []byte(tt.sep)); string(after) != tt.after || found != tt.found {
1776			t.Errorf("CutPrefix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, after, found, tt.after, tt.found)
1777		}
1778	}
1779}
1780
1781var cutSuffixTests = []struct {
1782	s, sep string
1783	before string
1784	found  bool
1785}{
1786	{"abc", "bc", "a", true},
1787	{"abc", "abc", "", true},
1788	{"abc", "", "abc", true},
1789	{"abc", "d", "abc", false},
1790	{"", "d", "", false},
1791	{"", "", "", true},
1792}
1793
1794func TestCutSuffix(t *testing.T) {
1795	for _, tt := range cutSuffixTests {
1796		if before, found := CutSuffix([]byte(tt.s), []byte(tt.sep)); string(before) != tt.before || found != tt.found {
1797			t.Errorf("CutSuffix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, before, found, tt.before, tt.found)
1798		}
1799	}
1800}
1801
1802func TestBufferGrowNegative(t *testing.T) {
1803	defer func() {
1804		if err := recover(); err == nil {
1805			t.Fatal("Grow(-1) should have panicked")
1806		}
1807	}()
1808	var b Buffer
1809	b.Grow(-1)
1810}
1811
1812func TestBufferTruncateNegative(t *testing.T) {
1813	defer func() {
1814		if err := recover(); err == nil {
1815			t.Fatal("Truncate(-1) should have panicked")
1816		}
1817	}()
1818	var b Buffer
1819	b.Truncate(-1)
1820}
1821
1822func TestBufferTruncateOutOfRange(t *testing.T) {
1823	defer func() {
1824		if err := recover(); err == nil {
1825			t.Fatal("Truncate(20) should have panicked")
1826		}
1827	}()
1828	var b Buffer
1829	b.Write(make([]byte, 10))
1830	b.Truncate(20)
1831}
1832
1833var containsTests = []struct {
1834	b, subslice []byte
1835	want        bool
1836}{
1837	{[]byte("hello"), []byte("hel"), true},
1838	{[]byte("日本語"), []byte("日本"), true},
1839	{[]byte("hello"), []byte("Hello, world"), false},
1840	{[]byte("東京"), []byte("京東"), false},
1841}
1842
1843func TestContains(t *testing.T) {
1844	for _, tt := range containsTests {
1845		if got := Contains(tt.b, tt.subslice); got != tt.want {
1846			t.Errorf("Contains(%q, %q) = %v, want %v", tt.b, tt.subslice, got, tt.want)
1847		}
1848	}
1849}
1850
1851var ContainsAnyTests = []struct {
1852	b        []byte
1853	substr   string
1854	expected bool
1855}{
1856	{[]byte(""), "", false},
1857	{[]byte(""), "a", false},
1858	{[]byte(""), "abc", false},
1859	{[]byte("a"), "", false},
1860	{[]byte("a"), "a", true},
1861	{[]byte("aaa"), "a", true},
1862	{[]byte("abc"), "xyz", false},
1863	{[]byte("abc"), "xcz", true},
1864	{[]byte("abcd"), "uvwxyz", true},
1865	{[]byte("aRegExp*"), ".(|)*+?^$[]", true},
1866	{[]byte(dots + dots + dots), " ", false},
1867}
1868
1869func TestContainsAny(t *testing.T) {
1870	for _, ct := range ContainsAnyTests {
1871		if ContainsAny(ct.b, ct.substr) != ct.expected {
1872			t.Errorf("ContainsAny(%s, %s) = %v, want %v",
1873				ct.b, ct.substr, !ct.expected, ct.expected)
1874		}
1875	}
1876}
1877
1878var ContainsRuneTests = []struct {
1879	b        []byte
1880	r        rune
1881	expected bool
1882}{
1883	{[]byte(""), 'a', false},
1884	{[]byte("a"), 'a', true},
1885	{[]byte("aaa"), 'a', true},
1886	{[]byte("abc"), 'y', false},
1887	{[]byte("abc"), 'c', true},
1888	{[]byte("abcd"), 'x', false},
1889	{[]byte("abcd"), '☻', true},
1890	{[]byte("aRegExp*"), '*', true},
1891}
1892
1893func TestContainsRune(t *testing.T) {
1894	for _, ct := range ContainsRuneTests {
1895		if ContainsRune(ct.b, ct.r) != ct.expected {
1896			t.Errorf("ContainsRune(%q, %q) = %v, want %v",
1897				ct.b, ct.r, !ct.expected, ct.expected)
1898		}
1899	}
1900}
1901
1902func TestContainsFunc(t *testing.T) {
1903	for _, ct := range ContainsRuneTests {
1904		if ContainsFunc(ct.b, func(r rune) bool {
1905			return ct.r == r
1906		}) != ct.expected {
1907			t.Errorf("ContainsFunc(%q, func(%q)) = %v, want %v",
1908				ct.b, ct.r, !ct.expected, ct.expected)
1909		}
1910	}
1911}
1912
1913var makeFieldsInput = func() []byte {
1914	x := make([]byte, 1<<20)
1915	// Input is ~10% space, ~10% 2-byte UTF-8, rest ASCII non-space.
1916	for i := range x {
1917		switch rand.Intn(10) {
1918		case 0:
1919			x[i] = ' '
1920		case 1:
1921			if i > 0 && x[i-1] == 'x' {
1922				copy(x[i-1:], "χ")
1923				break
1924			}
1925			fallthrough
1926		default:
1927			x[i] = 'x'
1928		}
1929	}
1930	return x
1931}
1932
1933var makeFieldsInputASCII = func() []byte {
1934	x := make([]byte, 1<<20)
1935	// Input is ~10% space, rest ASCII non-space.
1936	for i := range x {
1937		if rand.Intn(10) == 0 {
1938			x[i] = ' '
1939		} else {
1940			x[i] = 'x'
1941		}
1942	}
1943	return x
1944}
1945
1946var bytesdata = []struct {
1947	name string
1948	data []byte
1949}{
1950	{"ASCII", makeFieldsInputASCII()},
1951	{"Mixed", makeFieldsInput()},
1952}
1953
1954func BenchmarkFields(b *testing.B) {
1955	for _, sd := range bytesdata {
1956		b.Run(sd.name, func(b *testing.B) {
1957			for j := 1 << 4; j <= 1<<20; j <<= 4 {
1958				b.Run(fmt.Sprintf("%d", j), func(b *testing.B) {
1959					b.ReportAllocs()
1960					b.SetBytes(int64(j))
1961					data := sd.data[:j]
1962					for i := 0; i < b.N; i++ {
1963						Fields(data)
1964					}
1965				})
1966			}
1967		})
1968	}
1969}
1970
1971func BenchmarkFieldsFunc(b *testing.B) {
1972	for _, sd := range bytesdata {
1973		b.Run(sd.name, func(b *testing.B) {
1974			for j := 1 << 4; j <= 1<<20; j <<= 4 {
1975				b.Run(fmt.Sprintf("%d", j), func(b *testing.B) {
1976					b.ReportAllocs()
1977					b.SetBytes(int64(j))
1978					data := sd.data[:j]
1979					for i := 0; i < b.N; i++ {
1980						FieldsFunc(data, unicode.IsSpace)
1981					}
1982				})
1983			}
1984		})
1985	}
1986}
1987
1988func BenchmarkTrimSpace(b *testing.B) {
1989	tests := []struct {
1990		name  string
1991		input []byte
1992	}{
1993		{"NoTrim", []byte("typical")},
1994		{"ASCII", []byte("  foo bar  ")},
1995		{"SomeNonASCII", []byte("    \u2000\t\r\n x\t\t\r\r\ny\n \u3000    ")},
1996		{"JustNonASCII", []byte("\u2000\u2000\u2000☺☺☺☺\u3000\u3000\u3000")},
1997	}
1998	for _, test := range tests {
1999		b.Run(test.name, func(b *testing.B) {
2000			for i := 0; i < b.N; i++ {
2001				TrimSpace(test.input)
2002			}
2003		})
2004	}
2005}
2006
2007func BenchmarkToValidUTF8(b *testing.B) {
2008	tests := []struct {
2009		name  string
2010		input []byte
2011	}{
2012		{"Valid", []byte("typical")},
2013		{"InvalidASCII", []byte("foo\xffbar")},
2014		{"InvalidNonASCII", []byte("日本語\xff日本語")},
2015	}
2016	replacement := []byte("\uFFFD")
2017	b.ResetTimer()
2018	for _, test := range tests {
2019		b.Run(test.name, func(b *testing.B) {
2020			for i := 0; i < b.N; i++ {
2021				ToValidUTF8(test.input, replacement)
2022			}
2023		})
2024	}
2025}
2026
2027func makeBenchInputHard() []byte {
2028	tokens := [...]string{
2029		"<a>", "<p>", "<b>", "<strong>",
2030		"</a>", "</p>", "</b>", "</strong>",
2031		"hello", "world",
2032	}
2033	x := make([]byte, 0, 1<<20)
2034	for {
2035		i := rand.Intn(len(tokens))
2036		if len(x)+len(tokens[i]) >= 1<<20 {
2037			break
2038		}
2039		x = append(x, tokens[i]...)
2040	}
2041	return x
2042}
2043
2044var benchInputHard = makeBenchInputHard()
2045
2046func benchmarkIndexHard(b *testing.B, sep []byte) {
2047	for i := 0; i < b.N; i++ {
2048		Index(benchInputHard, sep)
2049	}
2050}
2051
2052func benchmarkLastIndexHard(b *testing.B, sep []byte) {
2053	for i := 0; i < b.N; i++ {
2054		LastIndex(benchInputHard, sep)
2055	}
2056}
2057
2058func benchmarkCountHard(b *testing.B, sep []byte) {
2059	for i := 0; i < b.N; i++ {
2060		Count(benchInputHard, sep)
2061	}
2062}
2063
2064func BenchmarkIndexHard1(b *testing.B) { benchmarkIndexHard(b, []byte("<>")) }
2065func BenchmarkIndexHard2(b *testing.B) { benchmarkIndexHard(b, []byte("</pre>")) }
2066func BenchmarkIndexHard3(b *testing.B) { benchmarkIndexHard(b, []byte("<b>hello world</b>")) }
2067func BenchmarkIndexHard4(b *testing.B) {
2068	benchmarkIndexHard(b, []byte("<pre><b>hello</b><strong>world</strong></pre>"))
2069}
2070
2071func BenchmarkLastIndexHard1(b *testing.B) { benchmarkLastIndexHard(b, []byte("<>")) }
2072func BenchmarkLastIndexHard2(b *testing.B) { benchmarkLastIndexHard(b, []byte("</pre>")) }
2073func BenchmarkLastIndexHard3(b *testing.B) { benchmarkLastIndexHard(b, []byte("<b>hello world</b>")) }
2074
2075func BenchmarkCountHard1(b *testing.B) { benchmarkCountHard(b, []byte("<>")) }
2076func BenchmarkCountHard2(b *testing.B) { benchmarkCountHard(b, []byte("</pre>")) }
2077func BenchmarkCountHard3(b *testing.B) { benchmarkCountHard(b, []byte("<b>hello world</b>")) }
2078
2079func BenchmarkSplitEmptySeparator(b *testing.B) {
2080	for i := 0; i < b.N; i++ {
2081		Split(benchInputHard, nil)
2082	}
2083}
2084
2085func BenchmarkSplitSingleByteSeparator(b *testing.B) {
2086	sep := []byte("/")
2087	for i := 0; i < b.N; i++ {
2088		Split(benchInputHard, sep)
2089	}
2090}
2091
2092func BenchmarkSplitMultiByteSeparator(b *testing.B) {
2093	sep := []byte("hello")
2094	for i := 0; i < b.N; i++ {
2095		Split(benchInputHard, sep)
2096	}
2097}
2098
2099func BenchmarkSplitNSingleByteSeparator(b *testing.B) {
2100	sep := []byte("/")
2101	for i := 0; i < b.N; i++ {
2102		SplitN(benchInputHard, sep, 10)
2103	}
2104}
2105
2106func BenchmarkSplitNMultiByteSeparator(b *testing.B) {
2107	sep := []byte("hello")
2108	for i := 0; i < b.N; i++ {
2109		SplitN(benchInputHard, sep, 10)
2110	}
2111}
2112
2113func BenchmarkRepeat(b *testing.B) {
2114	for i := 0; i < b.N; i++ {
2115		Repeat([]byte("-"), 80)
2116	}
2117}
2118
2119func BenchmarkRepeatLarge(b *testing.B) {
2120	s := Repeat([]byte("@"), 8*1024)
2121	for j := 8; j <= 30; j++ {
2122		for _, k := range []int{1, 16, 4097} {
2123			s := s[:k]
2124			n := (1 << j) / k
2125			if n == 0 {
2126				continue
2127			}
2128			b.Run(fmt.Sprintf("%d/%d", 1<<j, k), func(b *testing.B) {
2129				for i := 0; i < b.N; i++ {
2130					Repeat(s, n)
2131				}
2132				b.SetBytes(int64(n * len(s)))
2133			})
2134		}
2135	}
2136}
2137
2138func BenchmarkBytesCompare(b *testing.B) {
2139	for n := 1; n <= 2048; n <<= 1 {
2140		b.Run(fmt.Sprint(n), func(b *testing.B) {
2141			var x = make([]byte, n)
2142			var y = make([]byte, n)
2143
2144			for i := 0; i < n; i++ {
2145				x[i] = 'a'
2146			}
2147
2148			for i := 0; i < n; i++ {
2149				y[i] = 'a'
2150			}
2151
2152			b.ResetTimer()
2153			for i := 0; i < b.N; i++ {
2154				Compare(x, y)
2155			}
2156		})
2157	}
2158}
2159
2160func BenchmarkIndexAnyASCII(b *testing.B) {
2161	x := Repeat([]byte{'#'}, 2048) // Never matches set
2162	cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"
2163	for k := 1; k <= 2048; k <<= 4 {
2164		for j := 1; j <= 64; j <<= 1 {
2165			b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
2166				for i := 0; i < b.N; i++ {
2167					IndexAny(x[:k], cs[:j])
2168				}
2169			})
2170		}
2171	}
2172}
2173
2174func BenchmarkIndexAnyUTF8(b *testing.B) {
2175	x := Repeat([]byte{'#'}, 2048) // Never matches set
2176	cs := "你好世界, hello world. 你好世界, hello world. 你好世界, hello world."
2177	for k := 1; k <= 2048; k <<= 4 {
2178		for j := 1; j <= 64; j <<= 1 {
2179			b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
2180				for i := 0; i < b.N; i++ {
2181					IndexAny(x[:k], cs[:j])
2182				}
2183			})
2184		}
2185	}
2186}
2187
2188func BenchmarkLastIndexAnyASCII(b *testing.B) {
2189	x := Repeat([]byte{'#'}, 2048) // Never matches set
2190	cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"
2191	for k := 1; k <= 2048; k <<= 4 {
2192		for j := 1; j <= 64; j <<= 1 {
2193			b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
2194				for i := 0; i < b.N; i++ {
2195					LastIndexAny(x[:k], cs[:j])
2196				}
2197			})
2198		}
2199	}
2200}
2201
2202func BenchmarkLastIndexAnyUTF8(b *testing.B) {
2203	x := Repeat([]byte{'#'}, 2048) // Never matches set
2204	cs := "你好世界, hello world. 你好世界, hello world. 你好世界, hello world."
2205	for k := 1; k <= 2048; k <<= 4 {
2206		for j := 1; j <= 64; j <<= 1 {
2207			b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
2208				for i := 0; i < b.N; i++ {
2209					LastIndexAny(x[:k], cs[:j])
2210				}
2211			})
2212		}
2213	}
2214}
2215
2216func BenchmarkTrimASCII(b *testing.B) {
2217	cs := "0123456789abcdef"
2218	for k := 1; k <= 4096; k <<= 4 {
2219		for j := 1; j <= 16; j <<= 1 {
2220			b.Run(fmt.Sprintf("%d:%d", k, j), func(b *testing.B) {
2221				x := Repeat([]byte(cs[:j]), k) // Always matches set
2222				for i := 0; i < b.N; i++ {
2223					Trim(x[:k], cs[:j])
2224				}
2225			})
2226		}
2227	}
2228}
2229
2230func BenchmarkTrimByte(b *testing.B) {
2231	x := []byte("  the quick brown fox   ")
2232	for i := 0; i < b.N; i++ {
2233		Trim(x, " ")
2234	}
2235}
2236
2237func BenchmarkIndexPeriodic(b *testing.B) {
2238	key := []byte{1, 1}
2239	for _, skip := range [...]int{2, 4, 8, 16, 32, 64} {
2240		b.Run(fmt.Sprintf("IndexPeriodic%d", skip), func(b *testing.B) {
2241			buf := make([]byte, 1<<16)
2242			for i := 0; i < len(buf); i += skip {
2243				buf[i] = 1
2244			}
2245			for i := 0; i < b.N; i++ {
2246				Index(buf, key)
2247			}
2248		})
2249	}
2250}
2251
2252func TestClone(t *testing.T) {
2253	var cloneTests = [][]byte{
2254		[]byte(nil),
2255		[]byte{},
2256		Clone([]byte{}),
2257		[]byte(strings.Repeat("a", 42))[:0],
2258		[]byte(strings.Repeat("a", 42))[:0:0],
2259		[]byte("short"),
2260		[]byte(strings.Repeat("a", 42)),
2261	}
2262	for _, input := range cloneTests {
2263		clone := Clone(input)
2264		if !Equal(clone, input) {
2265			t.Errorf("Clone(%q) = %q; want %q", input, clone, input)
2266		}
2267
2268		if input == nil && clone != nil {
2269			t.Errorf("Clone(%#v) return value should be equal to nil slice.", input)
2270		}
2271
2272		if input != nil && clone == nil {
2273			t.Errorf("Clone(%#v) return value should not be equal to nil slice.", input)
2274		}
2275
2276		if cap(input) != 0 && unsafe.SliceData(input) == unsafe.SliceData(clone) {
2277			t.Errorf("Clone(%q) return value should not reference inputs backing memory.", input)
2278		}
2279	}
2280}
2281