1
2
3
4
5
6
7 package jsonwire
8
9 import (
10 "errors"
11 "io"
12 "math"
13 "reflect"
14 "strings"
15 "testing"
16 )
17
18 func TestConsumeWhitespace(t *testing.T) {
19 tests := []struct {
20 in string
21 want int
22 }{
23 {"", 0},
24 {"a", 0},
25 {" a", 1},
26 {" a ", 1},
27 {" \n\r\ta", 4},
28 {" \n\r\t \n\r\t \n\r\t \n\r\t", 16},
29 {"\u00a0", 0},
30 }
31
32 for _, tt := range tests {
33 t.Run("", func(t *testing.T) {
34 if got := ConsumeWhitespace([]byte(tt.in)); got != tt.want {
35 t.Errorf("ConsumeWhitespace(%q) = %v, want %v", tt.in, got, tt.want)
36 }
37 })
38 }
39 }
40
41 func TestConsumeLiteral(t *testing.T) {
42 tests := []struct {
43 literal string
44 in string
45 want int
46 wantErr error
47 }{
48 {"null", "", 0, io.ErrUnexpectedEOF},
49 {"null", "n", 1, io.ErrUnexpectedEOF},
50 {"null", "nu", 2, io.ErrUnexpectedEOF},
51 {"null", "nul", 3, io.ErrUnexpectedEOF},
52 {"null", "null", 4, nil},
53 {"null", "nullx", 4, nil},
54 {"null", "x", 0, NewInvalidCharacterError("x", "in literal null (expecting 'n')")},
55 {"null", "nuxx", 2, NewInvalidCharacterError("x", "in literal null (expecting 'l')")},
56
57 {"false", "", 0, io.ErrUnexpectedEOF},
58 {"false", "f", 1, io.ErrUnexpectedEOF},
59 {"false", "fa", 2, io.ErrUnexpectedEOF},
60 {"false", "fal", 3, io.ErrUnexpectedEOF},
61 {"false", "fals", 4, io.ErrUnexpectedEOF},
62 {"false", "false", 5, nil},
63 {"false", "falsex", 5, nil},
64 {"false", "x", 0, NewInvalidCharacterError("x", "in literal false (expecting 'f')")},
65 {"false", "falsx", 4, NewInvalidCharacterError("x", "in literal false (expecting 'e')")},
66
67 {"true", "", 0, io.ErrUnexpectedEOF},
68 {"true", "t", 1, io.ErrUnexpectedEOF},
69 {"true", "tr", 2, io.ErrUnexpectedEOF},
70 {"true", "tru", 3, io.ErrUnexpectedEOF},
71 {"true", "true", 4, nil},
72 {"true", "truex", 4, nil},
73 {"true", "x", 0, NewInvalidCharacterError("x", "in literal true (expecting 't')")},
74 {"true", "trux", 3, NewInvalidCharacterError("x", "in literal true (expecting 'e')")},
75 }
76
77 for _, tt := range tests {
78 t.Run("", func(t *testing.T) {
79 var got int
80 switch tt.literal {
81 case "null":
82 got = ConsumeNull([]byte(tt.in))
83 case "false":
84 got = ConsumeFalse([]byte(tt.in))
85 case "true":
86 got = ConsumeTrue([]byte(tt.in))
87 default:
88 t.Errorf("invalid literal: %v", tt.literal)
89 }
90 switch {
91 case tt.wantErr == nil && got != tt.want:
92 t.Errorf("Consume%v(%q) = %v, want %v", strings.Title(tt.literal), tt.in, got, tt.want)
93 case tt.wantErr != nil && got != 0:
94 t.Errorf("Consume%v(%q) = %v, want %v", strings.Title(tt.literal), tt.in, got, 0)
95 }
96
97 got, gotErr := ConsumeLiteral([]byte(tt.in), tt.literal)
98 if got != tt.want || !reflect.DeepEqual(gotErr, tt.wantErr) {
99 t.Errorf("ConsumeLiteral(%q, %q) = (%v, %v), want (%v, %v)", tt.in, tt.literal, got, gotErr, tt.want, tt.wantErr)
100 }
101 })
102 }
103 }
104
105 func TestConsumeString(t *testing.T) {
106 var errPrev = errors.New("same as previous error")
107 tests := []struct {
108 in string
109 simple bool
110 want int
111 wantUTF8 int
112 wantFlags ValueFlags
113 wantUnquote string
114 wantErr error
115 wantErrUTF8 error
116 wantErrUnquote error
117 }{
118 {``, false, 0, 0, 0, "", io.ErrUnexpectedEOF, errPrev, errPrev},
119 {`"`, false, 1, 1, 0, "", io.ErrUnexpectedEOF, errPrev, errPrev},
120 {`""`, true, 2, 2, 0, "", nil, nil, nil},
121 {`""x`, true, 2, 2, 0, "", nil, nil, NewInvalidCharacterError("x", "after string value")},
122 {` ""x`, false, 0, 0, 0, "", NewInvalidCharacterError(" ", "at start of string (expecting '\"')"), errPrev, errPrev},
123 {`"hello`, false, 6, 6, 0, "hello", io.ErrUnexpectedEOF, errPrev, errPrev},
124 {`"hello"`, true, 7, 7, 0, "hello", nil, nil, nil},
125 {"\"\x00\"", false, 1, 1, stringNonVerbatim | stringNonCanonical, "", NewInvalidCharacterError("\x00", "in string (expecting non-control character)"), errPrev, errPrev},
126 {`"\u0000"`, false, 8, 8, stringNonVerbatim, "\x00", nil, nil, nil},
127 {"\"\x1f\"", false, 1, 1, stringNonVerbatim | stringNonCanonical, "", NewInvalidCharacterError("\x1f", "in string (expecting non-control character)"), errPrev, errPrev},
128 {`"\u001f"`, false, 8, 8, stringNonVerbatim, "\x1f", nil, nil, nil},
129 {`"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"`, true, 54, 54, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", nil, nil, nil},
130 {"\" !#$%'()*+,-./0123456789:;=?@[]^_`{|}~\x7f\"", true, 41, 41, 0, " !#$%'()*+,-./0123456789:;=?@[]^_`{|}~\x7f", nil, nil, nil},
131 {`"&"`, false, 3, 3, 0, "&", nil, nil, nil},
132 {`"<"`, false, 3, 3, 0, "<", nil, nil, nil},
133 {`">"`, false, 3, 3, 0, ">", nil, nil, nil},
134 {"\"x\x80\"", false, 4, 2, stringNonVerbatim | stringNonCanonical, "x\ufffd", nil, ErrInvalidUTF8, errPrev},
135 {"\"x\xff\"", false, 4, 2, stringNonVerbatim | stringNonCanonical, "x\ufffd", nil, ErrInvalidUTF8, errPrev},
136 {"\"x\xc0", false, 3, 2, stringNonVerbatim | stringNonCanonical, "x\ufffd", io.ErrUnexpectedEOF, ErrInvalidUTF8, io.ErrUnexpectedEOF},
137 {"\"x\xc0\x80\"", false, 5, 2, stringNonVerbatim | stringNonCanonical, "x\ufffd\ufffd", nil, ErrInvalidUTF8, errPrev},
138 {"\"x\xe0", false, 2, 2, 0, "x", io.ErrUnexpectedEOF, errPrev, errPrev},
139 {"\"x\xe0\x80", false, 4, 2, stringNonVerbatim | stringNonCanonical, "x\ufffd\ufffd", io.ErrUnexpectedEOF, ErrInvalidUTF8, io.ErrUnexpectedEOF},
140 {"\"x\xe0\x80\x80\"", false, 6, 2, stringNonVerbatim | stringNonCanonical, "x\ufffd\ufffd\ufffd", nil, ErrInvalidUTF8, errPrev},
141 {"\"x\xf0", false, 2, 2, 0, "x", io.ErrUnexpectedEOF, errPrev, errPrev},
142 {"\"x\xf0\x80", false, 4, 2, stringNonVerbatim | stringNonCanonical, "x\ufffd\ufffd", io.ErrUnexpectedEOF, ErrInvalidUTF8, io.ErrUnexpectedEOF},
143 {"\"x\xf0\x80\x80", false, 5, 2, stringNonVerbatim | stringNonCanonical, "x\ufffd\ufffd\ufffd", io.ErrUnexpectedEOF, ErrInvalidUTF8, io.ErrUnexpectedEOF},
144 {"\"x\xf0\x80\x80\x80\"", false, 7, 2, stringNonVerbatim | stringNonCanonical, "x\ufffd\ufffd\ufffd\ufffd", nil, ErrInvalidUTF8, errPrev},
145 {"\"x\xed\xba\xad\"", false, 6, 2, stringNonVerbatim | stringNonCanonical, "x\ufffd\ufffd\ufffd", nil, ErrInvalidUTF8, errPrev},
146 {"\"\u0080\u00f6\u20ac\ud799\ue000\ufb33\ufffd\U0001f602\"", false, 25, 25, 0, "\u0080\u00f6\u20ac\ud799\ue000\ufb33\ufffd\U0001f602", nil, nil, nil},
147 {`"¢"`[:2], false, 1, 1, 0, "", io.ErrUnexpectedEOF, errPrev, errPrev},
148 {`"¢"`[:3], false, 3, 3, 0, "¢", io.ErrUnexpectedEOF, errPrev, errPrev},
149 {`"¢"`[:4], false, 4, 4, 0, "¢", nil, nil, nil},
150 {`"€"`[:2], false, 1, 1, 0, "", io.ErrUnexpectedEOF, errPrev, errPrev},
151 {`"€"`[:3], false, 1, 1, 0, "", io.ErrUnexpectedEOF, errPrev, errPrev},
152 {`"€"`[:4], false, 4, 4, 0, "€", io.ErrUnexpectedEOF, errPrev, errPrev},
153 {`"€"`[:5], false, 5, 5, 0, "€", nil, nil, nil},
154 {`"𐍈"`[:2], false, 1, 1, 0, "", io.ErrUnexpectedEOF, errPrev, errPrev},
155 {`"𐍈"`[:3], false, 1, 1, 0, "", io.ErrUnexpectedEOF, errPrev, errPrev},
156 {`"𐍈"`[:4], false, 1, 1, 0, "", io.ErrUnexpectedEOF, errPrev, errPrev},
157 {`"𐍈"`[:5], false, 5, 5, 0, "𐍈", io.ErrUnexpectedEOF, errPrev, errPrev},
158 {`"𐍈"`[:6], false, 6, 6, 0, "𐍈", nil, nil, nil},
159 {`"x\`, false, 2, 2, stringNonVerbatim, "x", io.ErrUnexpectedEOF, errPrev, errPrev},
160 {`"x\"`, false, 4, 4, stringNonVerbatim, "x\"", io.ErrUnexpectedEOF, errPrev, errPrev},
161 {`"x\x"`, false, 2, 2, stringNonVerbatim | stringNonCanonical, "x", NewInvalidEscapeSequenceError(`\x`), errPrev, errPrev},
162 {`"\"\\\b\f\n\r\t"`, false, 16, 16, stringNonVerbatim, "\"\\\b\f\n\r\t", nil, nil, nil},
163 {`"/"`, true, 3, 3, 0, "/", nil, nil, nil},
164 {`"\/"`, false, 4, 4, stringNonVerbatim | stringNonCanonical, "/", nil, nil, nil},
165 {`"\u002f"`, false, 8, 8, stringNonVerbatim | stringNonCanonical, "/", nil, nil, nil},
166 {`"\u`, false, 1, 1, stringNonVerbatim, "", io.ErrUnexpectedEOF, errPrev, errPrev},
167 {`"\uf`, false, 1, 1, stringNonVerbatim, "", io.ErrUnexpectedEOF, errPrev, errPrev},
168 {`"\uff`, false, 1, 1, stringNonVerbatim, "", io.ErrUnexpectedEOF, errPrev, errPrev},
169 {`"\ufff`, false, 1, 1, stringNonVerbatim, "", io.ErrUnexpectedEOF, errPrev, errPrev},
170 {`"\ufffd`, false, 7, 7, stringNonVerbatim | stringNonCanonical, "\ufffd", io.ErrUnexpectedEOF, errPrev, errPrev},
171 {`"\ufffd"`, false, 8, 8, stringNonVerbatim | stringNonCanonical, "\ufffd", nil, nil, nil},
172 {`"\uABCD"`, false, 8, 8, stringNonVerbatim | stringNonCanonical, "\uabcd", nil, nil, nil},
173 {`"\uefX0"`, false, 1, 1, stringNonVerbatim | stringNonCanonical, "", NewInvalidEscapeSequenceError(`\uefX0`), errPrev, errPrev},
174 {`"\uDEAD`, false, 7, 1, stringNonVerbatim | stringNonCanonical, "\ufffd", io.ErrUnexpectedEOF, errPrev, errPrev},
175 {`"\uDEAD"`, false, 8, 1, stringNonVerbatim | stringNonCanonical, "\ufffd", nil, NewInvalidEscapeSequenceError(`\uDEAD"`), errPrev},
176 {`"\uDEAD______"`, false, 14, 1, stringNonVerbatim | stringNonCanonical, "\ufffd______", nil, NewInvalidEscapeSequenceError(`\uDEAD______`), errPrev},
177 {`"\uDEAD\uXXXX"`, false, 7, 1, stringNonVerbatim | stringNonCanonical, "\ufffd", NewInvalidEscapeSequenceError(`\uXXXX`), NewInvalidEscapeSequenceError(`\uDEAD\uXXXX`), NewInvalidEscapeSequenceError(`\uXXXX`)},
178 {`"\uDEAD\uBEEF"`, false, 14, 1, stringNonVerbatim | stringNonCanonical, "\ufffd\ubeef", nil, NewInvalidEscapeSequenceError(`\uDEAD\uBEEF`), errPrev},
179 {`"\uD800\udea`, false, 7, 1, stringNonVerbatim | stringNonCanonical, "\ufffd", io.ErrUnexpectedEOF, errPrev, errPrev},
180 {`"\uD800\udb`, false, 7, 1, stringNonVerbatim | stringNonCanonical, "\ufffd", io.ErrUnexpectedEOF, NewInvalidEscapeSequenceError(`\uD800\udb`), io.ErrUnexpectedEOF},
181 {`"\uD800\udead"`, false, 14, 14, stringNonVerbatim | stringNonCanonical, "\U000102ad", nil, nil, nil},
182 {`"\u0022\u005c\u002f\u0008\u000c\u000a\u000d\u0009"`, false, 50, 50, stringNonVerbatim | stringNonCanonical, "\"\\/\b\f\n\r\t", nil, nil, nil},
183 {`"\u0080\u00f6\u20ac\ud799\ue000\ufb33\ufffd\ud83d\ude02"`, false, 56, 56, stringNonVerbatim | stringNonCanonical, "\u0080\u00f6\u20ac\ud799\ue000\ufb33\ufffd\U0001f602", nil, nil, nil},
184 }
185
186 for _, tt := range tests {
187 t.Run("", func(t *testing.T) {
188 if tt.wantErrUTF8 == errPrev {
189 tt.wantErrUTF8 = tt.wantErr
190 }
191 if tt.wantErrUnquote == errPrev {
192 tt.wantErrUnquote = tt.wantErrUTF8
193 }
194
195 switch got := ConsumeSimpleString([]byte(tt.in)); {
196 case tt.simple && got != tt.want:
197 t.Errorf("consumeSimpleString(%q) = %v, want %v", tt.in, got, tt.want)
198 case !tt.simple && got != 0:
199 t.Errorf("consumeSimpleString(%q) = %v, want %v", tt.in, got, 0)
200 }
201
202 var gotFlags ValueFlags
203 got, gotErr := ConsumeString(&gotFlags, []byte(tt.in), false)
204 if gotFlags != tt.wantFlags {
205 t.Errorf("consumeString(%q, false) flags = %v, want %v", tt.in, gotFlags, tt.wantFlags)
206 }
207 if got != tt.want || !reflect.DeepEqual(gotErr, tt.wantErr) {
208 t.Errorf("consumeString(%q, false) = (%v, %v), want (%v, %v)", tt.in, got, gotErr, tt.want, tt.wantErr)
209 }
210
211 got, gotErr = ConsumeString(&gotFlags, []byte(tt.in), true)
212 if got != tt.wantUTF8 || !reflect.DeepEqual(gotErr, tt.wantErrUTF8) {
213 t.Errorf("consumeString(%q, false) = (%v, %v), want (%v, %v)", tt.in, got, gotErr, tt.wantUTF8, tt.wantErrUTF8)
214 }
215
216 gotUnquote, gotErr := AppendUnquote(nil, tt.in)
217 if string(gotUnquote) != tt.wantUnquote || !reflect.DeepEqual(gotErr, tt.wantErrUnquote) {
218 t.Errorf("AppendUnquote(nil, %q) = (%q, %v), want (%q, %v)", tt.in[:got], gotUnquote, gotErr, tt.wantUnquote, tt.wantErrUnquote)
219 }
220 })
221 }
222 }
223
224 func TestConsumeNumber(t *testing.T) {
225 tests := []struct {
226 in string
227 simple bool
228 want int
229 wantErr error
230 }{
231 {"", false, 0, io.ErrUnexpectedEOF},
232 {`"NaN"`, false, 0, NewInvalidCharacterError("\"", "in number (expecting digit)")},
233 {`"Infinity"`, false, 0, NewInvalidCharacterError("\"", "in number (expecting digit)")},
234 {`"-Infinity"`, false, 0, NewInvalidCharacterError("\"", "in number (expecting digit)")},
235 {".0", false, 0, NewInvalidCharacterError(".", "in number (expecting digit)")},
236 {"0", true, 1, nil},
237 {"-0", false, 2, nil},
238 {"+0", false, 0, NewInvalidCharacterError("+", "in number (expecting digit)")},
239 {"1", true, 1, nil},
240 {"-1", false, 2, nil},
241 {"00", true, 1, nil},
242 {"-00", false, 2, nil},
243 {"01", true, 1, nil},
244 {"-01", false, 2, nil},
245 {"0i", true, 1, nil},
246 {"-0i", false, 2, nil},
247 {"0f", true, 1, nil},
248 {"-0f", false, 2, nil},
249 {"9876543210", true, 10, nil},
250 {"-9876543210", false, 11, nil},
251 {"9876543210x", true, 10, nil},
252 {"-9876543210x", false, 11, nil},
253 {" 9876543210", true, 0, NewInvalidCharacterError(" ", "in number (expecting digit)")},
254 {"- 9876543210", false, 1, NewInvalidCharacterError(" ", "in number (expecting digit)")},
255 {strings.Repeat("9876543210", 1000), true, 10000, nil},
256 {"-" + strings.Repeat("9876543210", 1000), false, 1 + 10000, nil},
257 {"0.", false, 1, io.ErrUnexpectedEOF},
258 {"-0.", false, 2, io.ErrUnexpectedEOF},
259 {"0e", false, 1, io.ErrUnexpectedEOF},
260 {"-0e", false, 2, io.ErrUnexpectedEOF},
261 {"0E", false, 1, io.ErrUnexpectedEOF},
262 {"-0E", false, 2, io.ErrUnexpectedEOF},
263 {"0.0", false, 3, nil},
264 {"-0.0", false, 4, nil},
265 {"0e0", false, 3, nil},
266 {"-0e0", false, 4, nil},
267 {"0E0", false, 3, nil},
268 {"-0E0", false, 4, nil},
269 {"0.0123456789", false, 12, nil},
270 {"-0.0123456789", false, 13, nil},
271 {"1.f", false, 2, NewInvalidCharacterError("f", "in number (expecting digit)")},
272 {"-1.f", false, 3, NewInvalidCharacterError("f", "in number (expecting digit)")},
273 {"1.e", false, 2, NewInvalidCharacterError("e", "in number (expecting digit)")},
274 {"-1.e", false, 3, NewInvalidCharacterError("e", "in number (expecting digit)")},
275 {"1e0", false, 3, nil},
276 {"-1e0", false, 4, nil},
277 {"1E0", false, 3, nil},
278 {"-1E0", false, 4, nil},
279 {"1Ex", false, 2, NewInvalidCharacterError("x", "in number (expecting digit)")},
280 {"-1Ex", false, 3, NewInvalidCharacterError("x", "in number (expecting digit)")},
281 {"1e-0", false, 4, nil},
282 {"-1e-0", false, 5, nil},
283 {"1e+0", false, 4, nil},
284 {"-1e+0", false, 5, nil},
285 {"1E-0", false, 4, nil},
286 {"-1E-0", false, 5, nil},
287 {"1E+0", false, 4, nil},
288 {"-1E+0", false, 5, nil},
289 {"1E+00500", false, 8, nil},
290 {"-1E+00500", false, 9, nil},
291 {"1E+00500x", false, 8, nil},
292 {"-1E+00500x", false, 9, nil},
293 {"9876543210.0123456789e+01234589x", false, 31, nil},
294 {"-9876543210.0123456789e+01234589x", false, 32, nil},
295 {"1_000_000", true, 1, nil},
296 {"0x12ef", true, 1, nil},
297 {"0x1p-2", true, 1, nil},
298 }
299
300 for _, tt := range tests {
301 t.Run("", func(t *testing.T) {
302 switch got := ConsumeSimpleNumber([]byte(tt.in)); {
303 case tt.simple && got != tt.want:
304 t.Errorf("ConsumeSimpleNumber(%q) = %v, want %v", tt.in, got, tt.want)
305 case !tt.simple && got != 0:
306 t.Errorf("ConsumeSimpleNumber(%q) = %v, want %v", tt.in, got, 0)
307 }
308
309 got, gotErr := ConsumeNumber([]byte(tt.in))
310 if got != tt.want || !reflect.DeepEqual(gotErr, tt.wantErr) {
311 t.Errorf("ConsumeNumber(%q) = (%v, %v), want (%v, %v)", tt.in, got, gotErr, tt.want, tt.wantErr)
312 }
313 })
314 }
315 }
316
317 func TestParseHexUint16(t *testing.T) {
318 tests := []struct {
319 in string
320 want uint16
321 wantOk bool
322 }{
323 {"", 0, false},
324 {"a", 0, false},
325 {"ab", 0, false},
326 {"abc", 0, false},
327 {"abcd", 0xabcd, true},
328 {"abcde", 0, false},
329 {"9eA1", 0x9ea1, true},
330 {"gggg", 0, false},
331 {"0000", 0x0000, true},
332 {"1234", 0x1234, true},
333 }
334
335 for _, tt := range tests {
336 t.Run("", func(t *testing.T) {
337 got, gotOk := parseHexUint16([]byte(tt.in))
338 if got != tt.want || gotOk != tt.wantOk {
339 t.Errorf("parseHexUint16(%q) = (0x%04x, %v), want (0x%04x, %v)", tt.in, got, gotOk, tt.want, tt.wantOk)
340 }
341 })
342 }
343 }
344
345 func TestParseUint(t *testing.T) {
346 tests := []struct {
347 in string
348 want uint64
349 wantOk bool
350 }{
351 {"", 0, false},
352 {"0", 0, true},
353 {"1", 1, true},
354 {"-1", 0, false},
355 {"1f", 0, false},
356 {"00", 0, false},
357 {"01", 0, false},
358 {"10", 10, true},
359 {"10.9", 0, false},
360 {" 10", 0, false},
361 {"10 ", 0, false},
362 {"123456789", 123456789, true},
363 {"123456789d", 0, false},
364 {"18446744073709551614", math.MaxUint64 - 1, true},
365 {"18446744073709551615", math.MaxUint64, true},
366 {"18446744073709551616", math.MaxUint64, false},
367 {"18446744073709551620", math.MaxUint64, false},
368 {"18446744073709551700", math.MaxUint64, false},
369 {"18446744073709552000", math.MaxUint64, false},
370 {"18446744073709560000", math.MaxUint64, false},
371 {"18446744073709600000", math.MaxUint64, false},
372 {"18446744073710000000", math.MaxUint64, false},
373 {"18446744073800000000", math.MaxUint64, false},
374 {"18446744074000000000", math.MaxUint64, false},
375 {"18446744080000000000", math.MaxUint64, false},
376 {"18446744100000000000", math.MaxUint64, false},
377 {"18446745000000000000", math.MaxUint64, false},
378 {"18446750000000000000", math.MaxUint64, false},
379 {"18446800000000000000", math.MaxUint64, false},
380 {"18447000000000000000", math.MaxUint64, false},
381 {"18450000000000000000", math.MaxUint64, false},
382 {"18500000000000000000", math.MaxUint64, false},
383 {"19000000000000000000", math.MaxUint64, false},
384 {"19999999999999999999", math.MaxUint64, false},
385 {"20000000000000000000", math.MaxUint64, false},
386 {"100000000000000000000", math.MaxUint64, false},
387 {"99999999999999999999999999999999", math.MaxUint64, false},
388 {"99999999999999999999999999999999f", 0, false},
389 }
390
391 for _, tt := range tests {
392 t.Run("", func(t *testing.T) {
393 got, gotOk := ParseUint([]byte(tt.in))
394 if got != tt.want || gotOk != tt.wantOk {
395 t.Errorf("ParseUint(%q) = (%v, %v), want (%v, %v)", tt.in, got, gotOk, tt.want, tt.wantOk)
396 }
397 })
398 }
399 }
400
401 func TestParseFloat(t *testing.T) {
402 tests := []struct {
403 in string
404 want32 float64
405 want64 float64
406 wantOk bool
407 }{
408 {"0", 0, 0, true},
409 {"-1", -1, -1, true},
410 {"1", 1, 1, true},
411
412 {"-16777215", -16777215, -16777215, true},
413 {"16777215", 16777215, 16777215, true},
414 {"-16777216", -16777216, -16777216, true},
415 {"16777216", 16777216, 16777216, true},
416 {"-16777217", -16777216, -16777217, true},
417 {"16777217", 16777216, 16777217, true},
418
419 {"-9007199254740991", -9007199254740992, -9007199254740991, true},
420 {"9007199254740991", 9007199254740992, 9007199254740991, true},
421 {"-9007199254740992", -9007199254740992, -9007199254740992, true},
422 {"9007199254740992", 9007199254740992, 9007199254740992, true},
423 {"-9007199254740993", -9007199254740992, -9007199254740992, true},
424 {"9007199254740993", 9007199254740992, 9007199254740992, true},
425
426 {"-1e1000", -math.MaxFloat32, -math.MaxFloat64, false},
427 {"1e1000", +math.MaxFloat32, +math.MaxFloat64, false},
428 }
429
430 for _, tt := range tests {
431 t.Run("", func(t *testing.T) {
432 got32, gotOk32 := ParseFloat([]byte(tt.in), 32)
433 if got32 != tt.want32 || gotOk32 != tt.wantOk {
434 t.Errorf("ParseFloat(%q, 32) = (%v, %v), want (%v, %v)", tt.in, got32, gotOk32, tt.want32, tt.wantOk)
435 }
436
437 got64, gotOk64 := ParseFloat([]byte(tt.in), 64)
438 if got64 != tt.want64 || gotOk64 != tt.wantOk {
439 t.Errorf("ParseFloat(%q, 64) = (%v, %v), want (%v, %v)", tt.in, got64, gotOk64, tt.want64, tt.wantOk)
440 }
441 })
442 }
443 }
444
View as plain text