1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package literal
16
17 import (
18 "fmt"
19 "strings"
20 "testing"
21
22 "github.com/google/go-cmp/cmp"
23 )
24
25 func TestQuote(t *testing.T) {
26 testCases := []struct {
27 form Form
28 in string
29 out string
30 lossy bool
31 }{
32 {form: String, in: "\x00", out: `"\u0000"`},
33 {form: String, in: "abc\xffdef", out: `"abc�def"`, lossy: true},
34 {form: Bytes, in: "abc\xffdef", out: `'abc\xffdef'`},
35 {form: String.WithASCIIOnly(),
36 in: "abc\xffdef", out: `"abc\ufffddef"`, lossy: true},
37 {form: String, in: "\a\b\f\r\n\t\v", out: `"\a\b\f\r\n\t\v"`},
38 {form: String, in: "\"", out: `"\""`},
39 {form: String, in: "\\", out: `"\\"`},
40 {form: String, in: "\u263a", out: `"☺"`},
41 {form: String, in: "\U0010ffff", out: `"\U0010ffff"`},
42 {form: String, in: "\x04", out: `"\u0004"`},
43 {form: Bytes, in: "\x04", out: `'\x04'`},
44 {form: String.WithASCIIOnly(), in: "\u263a", out: `"\u263a"`},
45 {form: String.WithGraphicOnly(), in: "\u263a", out: `"☺"`},
46 {
47 form: String.WithASCIIOnly(),
48 in: "!\u00a0!\u2000!\u3000!",
49 out: `"!\u00a0!\u2000!\u3000!"`,
50 },
51 {form: String, in: "a\nb", out: `"a\nb"`},
52 {form: String.WithTabIndent(3), in: "a\nb", out: `"""
53 a
54 b
55 """`},
56 {form: String.WithTabIndent(3), in: "a", out: `"""
57 a
58 """`},
59 {form: String.WithTabIndent(3), in: "a\n", out: `"""
60 a
61
62 """`},
63 {form: String.WithTabIndent(3), in: "", out: `"""
64 """`},
65 {form: String.WithTabIndent(3), in: "\n", out: `"""
66
67
68 """`},
69 {form: String.WithTabIndent(3), in: "\n\n", out: `"""
70
71
72
73 """`},
74 {form: String.WithOptionalTabIndent(3), in: "a", out: `"a"`},
75 {form: String.WithOptionalTabIndent(3), in: "a\n", out: `"""
76 a
77
78 """`},
79
80
81 {form: String.WithTabIndent(3), in: "foo\n\"bar\"", out: `"""
82 foo
83 "bar"
84 """`},
85 {form: String.WithTabIndent(3), in: "foo\n\"\"\"bar\"", out: `#"""
86 foo
87 """bar"
88 """#`},
89 {form: String.WithTabIndent(3), in: "foo\n\"\"\"\"\"###bar\"", out: `####"""
90 foo
91 """""###bar"
92 """####`},
93 {form: String.WithTabIndent(3), in: "foo\n\"\"\"\r\f\\", out: `#"""
94 foo
95 """\#r\#f\#\
96 """#`},
97 {form: Bytes.WithTabIndent(3), in: "foo'''\nhello", out: `#'''
98 foo'''
99 hello
100 '''#`},
101 {form: Bytes.WithTabIndent(3), in: "foo\n'''\r\f\\", out: `#'''
102 foo
103 '''\#r\#f\#\
104 '''#`},
105 }
106 for _, tc := range testCases {
107 t.Run(fmt.Sprintf("%q", tc.in), func(t *testing.T) {
108 got := tc.form.Quote(tc.in)
109 if got != tc.out {
110 t.Errorf("Quote: %s", cmp.Diff(tc.out, got))
111 }
112
113 got = string(tc.form.Append(nil, tc.in))
114 if got != tc.out {
115 t.Errorf("Append: %s", cmp.Diff(tc.out, got))
116 }
117
118 str, err := Unquote(got)
119 if err != nil {
120 t.Errorf("Roundtrip error: %v", err)
121 }
122
123 if !tc.lossy && str != tc.in {
124 t.Errorf("Quote: %s", cmp.Diff(tc.in, str))
125 }
126 })
127 }
128 }
129
130 func TestAppendEscaped(t *testing.T) {
131 testCases := []struct {
132 form Form
133 in string
134 out string
135 }{
136 {String, "a", "a"},
137 {String, "", ""},
138 {String.WithTabIndent(2), "", ""},
139 {String.WithTabIndent(2), "\n", "\n"},
140 {String.WithTabIndent(2), "a\n", "a\n"},
141 {String.WithTabIndent(2), "a\nb", "a\n\t\tb"},
142 }
143 for _, tc := range testCases {
144 t.Run(tc.in, func(t *testing.T) {
145 buf := tc.form.AppendEscaped(nil, tc.in)
146 if got := string(buf); got != tc.out {
147 t.Error(cmp.Diff(tc.out, got))
148 }
149 })
150 }
151 }
152
153 func BenchmarkQuote(b *testing.B) {
154 inputs := []string{
155 "aaaa",
156 "aaaaaaa\n\naaaaaa",
157 strings.Repeat("aaaaaaaaaaa\n", 1000),
158 }
159
160 for _, f := range []Form{
161 String,
162 Bytes,
163 String.WithTabIndent(3),
164 String.WithOptionalTabIndent(3),
165 } {
166 b.Run("", func(b *testing.B) {
167 for i := 0; i < b.N; i++ {
168 for _, s := range inputs {
169 f.Quote(s)
170 }
171 }
172 })
173 }
174 }
175
View as plain text