1package json
2
3import (
4	"testing"
5)
6
7var encodeStringTests = []struct {
8	in  string
9	out string
10}{
11	{"", `""`},
12	{"\\", `"\\"`},
13	{"\x00", `"\u0000"`},
14	{"\x01", `"\u0001"`},
15	{"\x02", `"\u0002"`},
16	{"\x03", `"\u0003"`},
17	{"\x04", `"\u0004"`},
18	{"\x05", `"\u0005"`},
19	{"\x06", `"\u0006"`},
20	{"\x07", `"\u0007"`},
21	{"\x08", `"\b"`},
22	{"\x09", `"\t"`},
23	{"\x0a", `"\n"`},
24	{"\x0b", `"\u000b"`},
25	{"\x0c", `"\f"`},
26	{"\x0d", `"\r"`},
27	{"\x0e", `"\u000e"`},
28	{"\x0f", `"\u000f"`},
29	{"\x10", `"\u0010"`},
30	{"\x11", `"\u0011"`},
31	{"\x12", `"\u0012"`},
32	{"\x13", `"\u0013"`},
33	{"\x14", `"\u0014"`},
34	{"\x15", `"\u0015"`},
35	{"\x16", `"\u0016"`},
36	{"\x17", `"\u0017"`},
37	{"\x18", `"\u0018"`},
38	{"\x19", `"\u0019"`},
39	{"\x1a", `"\u001a"`},
40	{"\x1b", `"\u001b"`},
41	{"\x1c", `"\u001c"`},
42	{"\x1d", `"\u001d"`},
43	{"\x1e", `"\u001e"`},
44	{"\x1f", `"\u001f"`},
45	{"✭", `"✭"`},
46	{"foo\xc2\x7fbar", `"foo\ufffd\u007fbar"`}, // invalid sequence
47	{"ascii", `"ascii"`},
48	{"\"a", `"\"a"`},
49	{"\x1fa", `"\u001fa"`},
50	{"foo\"bar\"baz", `"foo\"bar\"baz"`},
51	{"\x1ffoo\x1fbar\x1fbaz", `"\u001ffoo\u001fbar\u001fbaz"`},
52	{"emoji \u2764\ufe0f!", `"emoji ❤️!"`},
53}
54
55var encodeHexTests = []struct {
56	in  byte
57	out string
58}{
59	{0x00, `"00"`},
60	{0x0f, `"0f"`},
61	{0x10, `"10"`},
62	{0xf0, `"f0"`},
63	{0xff, `"ff"`},
64}
65
66func TestAppendString(t *testing.T) {
67	for _, tt := range encodeStringTests {
68		b := enc.AppendString([]byte{}, tt.in)
69		if got, want := string(b), tt.out; got != want {
70			t.Errorf("appendString(%q) = %#q, want %#q", tt.in, got, want)
71		}
72	}
73}
74
75func BenchmarkAppendString(b *testing.B) {
76	tests := map[string]string{
77		"NoEncoding":       `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
78		"EncodingFirst":    `"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
79		"EncodingMiddle":   `aaaaaaaaaaaaaaaaaaaaaaaaa"aaaaaaaaaaaaaaaaaaaaaaaa`,
80		"EncodingLast":     `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"`,
81		"MultiBytesFirst":  `❤️aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,
82		"MultiBytesMiddle": `aaaaaaaaaaaaaaaaaaaaaaaaa❤️aaaaaaaaaaaaaaaaaaaaaaaa`,
83		"MultiBytesLast":   `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa❤️`,
84	}
85	for name, str := range tests {
86		b.Run(name, func(b *testing.B) {
87			buf := make([]byte, 0, 100)
88			for i := 0; i < b.N; i++ {
89				_ = enc.AppendString(buf, str)
90			}
91		})
92	}
93}
94