1
2
3
4
5
20
21 package sse
22
23 import (
24 `encoding/hex`
25 `fmt`
26 `math`
27 `strings`
28 `testing`
29 `unsafe`
30
31 `github.com/bytedance/sonic/internal/native/types`
32 `github.com/bytedance/sonic/internal/rt`
33 `github.com/davecgh/go-spew/spew`
34 `github.com/stretchr/testify/assert`
35 `github.com/stretchr/testify/require`
36 )
37
38 func TestNative_Value(t *testing.T) {
39 var v types.JsonState
40 s := ` -12345`
41 p := (*rt.GoString)(unsafe.Pointer(&s))
42 x := value(p.Ptr, p.Len, 0, &v, 0)
43 assert.Equal(t, 9, x)
44 assert.Equal(t, types.V_INTEGER, v.Vt)
45 assert.Equal(t, int64(-12345), v.Iv)
46 assert.Equal(t, 3, v.Ep)
47 }
48
49 func TestNative_Value_OutOfBound(t *testing.T) {
50 var v types.JsonState
51 mem := []byte{'"', '"'}
52 s := rt.Mem2Str(mem[:1])
53 p := (*rt.GoString)(unsafe.Pointer(&s))
54 x := value(p.Ptr, p.Len, 0, &v, 0)
55 assert.Equal(t, 1, x)
56 assert.Equal(t, -int(types.ERR_EOF), int(v.Vt))
57 }
58
59 func TestNative_Quote(t *testing.T) {
60 s := "hello\b\f\n\r\t\\\"\u666fworld"
61 d := make([]byte, 256)
62 dp := (*rt.GoSlice)(unsafe.Pointer(&d))
63 sp := (*rt.GoString)(unsafe.Pointer(&s))
64 rv := quote(sp.Ptr, sp.Len, dp.Ptr, &dp.Len, 0)
65 if rv < 0 {
66 require.NoError(t, types.ParsingError(-rv))
67 }
68 assert.Equal(t, len(s), rv)
69 assert.Equal(t, 35, len(d))
70 assert.Equal(t, `hello\u0008\u000c\n\r\t\\\"景world`, string(d))
71 }
72
73 func TestNative_QuoteNoMem(t *testing.T) {
74 s := "hello\b\f\n\r\t\\\"\u666fworld"
75 d := make([]byte, 10)
76 dp := (*rt.GoSlice)(unsafe.Pointer(&d))
77 sp := (*rt.GoString)(unsafe.Pointer(&s))
78 rv := quote(sp.Ptr, sp.Len, dp.Ptr, &dp.Len, 0)
79 assert.Equal(t, -6, rv)
80 assert.Equal(t, 5, len(d))
81 assert.Equal(t, `hello`, string(d))
82 }
83
84 func TestNative_DoubleQuote(t *testing.T) {
85 s := "hello\b\f\n\r\t\\\"\u666fworld"
86 d := make([]byte, 256)
87 dp := (*rt.GoSlice)(unsafe.Pointer(&d))
88 sp := (*rt.GoString)(unsafe.Pointer(&s))
89 rv := quote(sp.Ptr, sp.Len, dp.Ptr, &dp.Len, types.F_DOUBLE_UNQUOTE)
90 if rv < 0 {
91 require.NoError(t, types.ParsingError(-rv))
92 }
93 assert.Equal(t, len(s), rv)
94 assert.Equal(t, 44, len(d))
95 assert.Equal(t, `hello\\u0008\\u000c\\n\\r\\t\\\\\\\"景world`, string(d))
96 }
97
98 func TestNative_Unquote(t *testing.T) {
99 s := `hello\b\f\n\r\t\\\"\u2333world`
100 d := make([]byte, 0, len(s))
101 ep := -1
102 dp := (*rt.GoSlice)(unsafe.Pointer(&d))
103 sp := (*rt.GoString)(unsafe.Pointer(&s))
104 rv := unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
105 if rv < 0 {
106 require.NoError(t, types.ParsingError(-rv))
107 }
108 dp.Len = rv
109 assert.Equal(t, -1, ep)
110 assert.Equal(t, "hello\b\f\n\r\t\\\"\u2333world", string(d))
111 }
112
113 func TestNative_UnquoteError(t *testing.T) {
114 s := `asdf\`
115 d := make([]byte, 0, len(s))
116 ep := -1
117 dp := (*rt.GoSlice)(unsafe.Pointer(&d))
118 sp := (*rt.GoString)(unsafe.Pointer(&s))
119 rv := unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
120 assert.Equal(t, -int(types.ERR_EOF), rv)
121 assert.Equal(t, 5, ep)
122 s = `asdf\gqwer`
123 d = make([]byte, 0, len(s))
124 ep = -1
125 dp = (*rt.GoSlice)(unsafe.Pointer(&d))
126 sp = (*rt.GoString)(unsafe.Pointer(&s))
127 rv = unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
128 assert.Equal(t, -int(types.ERR_INVALID_ESCAPE), rv)
129 assert.Equal(t, 5, ep)
130 s = `asdf\u1gggqwer`
131 d = make([]byte, 0, len(s))
132 ep = -1
133 dp = (*rt.GoSlice)(unsafe.Pointer(&d))
134 sp = (*rt.GoString)(unsafe.Pointer(&s))
135 rv = unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
136 assert.Equal(t, -int(types.ERR_INVALID_CHAR), rv)
137 assert.Equal(t, 7, ep)
138 s = `asdf\ud800qwer`
139 d = make([]byte, 0, len(s))
140 ep = -1
141 dp = (*rt.GoSlice)(unsafe.Pointer(&d))
142 sp = (*rt.GoString)(unsafe.Pointer(&s))
143 rv = unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
144 assert.Equal(t, -int(types.ERR_INVALID_UNICODE), rv)
145 assert.Equal(t, 6, ep)
146 s = `asdf\\ud800qwer`
147 d = make([]byte, 0, len(s))
148 ep = -1
149 dp = (*rt.GoSlice)(unsafe.Pointer(&d))
150 sp = (*rt.GoString)(unsafe.Pointer(&s))
151 rv = unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, types.F_DOUBLE_UNQUOTE)
152 assert.Equal(t, -int(types.ERR_INVALID_UNICODE), rv)
153 assert.Equal(t, 7, ep)
154 s = `asdf\ud800\ud800qwer`
155 d = make([]byte, 0, len(s))
156 ep = -1
157 dp = (*rt.GoSlice)(unsafe.Pointer(&d))
158 sp = (*rt.GoString)(unsafe.Pointer(&s))
159 rv = unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, 0)
160 assert.Equal(t, -int(types.ERR_INVALID_UNICODE), rv)
161 assert.Equal(t, 12, ep)
162 s = `asdf\\ud800\\ud800qwer`
163 d = make([]byte, 0, len(s))
164 ep = -1
165 dp = (*rt.GoSlice)(unsafe.Pointer(&d))
166 sp = (*rt.GoString)(unsafe.Pointer(&s))
167 rv = unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, types.F_DOUBLE_UNQUOTE)
168 assert.Equal(t, -int(types.ERR_INVALID_UNICODE), rv)
169 assert.Equal(t, 14, ep)
170 }
171
172 func TestNative_DoubleUnquote(t *testing.T) {
173 s := `hello\\b\\f\\n\\r\\t\\\\\\\"\\u2333world`
174 d := make([]byte, 0, len(s))
175 ep := -1
176 dp := (*rt.GoSlice)(unsafe.Pointer(&d))
177 sp := (*rt.GoString)(unsafe.Pointer(&s))
178 rv := unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, types.F_DOUBLE_UNQUOTE)
179 if rv < 0 {
180 require.NoError(t, types.ParsingError(-rv))
181 }
182 dp.Len = rv
183 assert.Equal(t, -1, ep)
184 assert.Equal(t, "hello\b\f\n\r\t\\\"\u2333world", string(d))
185 }
186
187 func TestNative_UnquoteUnicodeReplacement(t *testing.T) {
188 s := `hello\ud800world`
189 d := make([]byte, 0, len(s))
190 ep := -1
191 dp := (*rt.GoSlice)(unsafe.Pointer(&d))
192 sp := (*rt.GoString)(unsafe.Pointer(&s))
193 rv := unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, types.F_UNICODE_REPLACE)
194 if rv < 0 {
195 require.NoError(t, types.ParsingError(-rv))
196 }
197 dp.Len = rv
198 assert.Equal(t, -1, ep)
199 assert.Equal(t, "hello\ufffdworld", string(d))
200 s = `hello\ud800\ud800world`
201 d = make([]byte, 0, len(s))
202 ep = -1
203 dp = (*rt.GoSlice)(unsafe.Pointer(&d))
204 sp = (*rt.GoString)(unsafe.Pointer(&s))
205 rv = unquote(sp.Ptr, sp.Len, dp.Ptr, &ep, types.F_UNICODE_REPLACE)
206 if rv < 0 {
207 require.NoError(t, types.ParsingError(-rv))
208 }
209 dp.Len = rv
210 assert.Equal(t, -1, ep)
211 assert.Equal(t, "hello\ufffd\ufffdworld", string(d))
212 }
213
214 func TestNative_HTMLEscape(t *testing.T) {
215 s := "hello\u2029\u2028<&>world"
216 d := make([]byte, 256)
217 dp := (*rt.GoSlice)(unsafe.Pointer(&d))
218 sp := (*rt.GoString)(unsafe.Pointer(&s))
219 rv := html_escape(sp.Ptr, sp.Len, dp.Ptr, &dp.Len)
220 if rv < 0 {
221 require.NoError(t, types.ParsingError(-rv))
222 }
223 assert.Equal(t, len(s), rv)
224 assert.Equal(t, 40, len(d))
225 assert.Equal(t, `hello\u2029\u2028\u003c\u0026\u003eworld`, string(d))
226 }
227
228 func TestNative_HTMLEscapeNoMem(t *testing.T) {
229 s := "hello\u2029\u2028<&>world"
230 d := make([]byte, 10)
231 dp := (*rt.GoSlice)(unsafe.Pointer(&d))
232 sp := (*rt.GoString)(unsafe.Pointer(&s))
233 rv := html_escape(sp.Ptr, sp.Len, dp.Ptr, &dp.Len)
234 assert.Equal(t, -6, rv)
235 assert.Equal(t, 5, len(d))
236 assert.Equal(t, `hello`, string(d))
237 }
238
239 func TestNative_Vstring(t *testing.T) {
240 var v types.JsonState
241 i := 0
242 s := `test"test\n2"`
243 vstring(&s, &i, &v, 0)
244 assert.Equal(t, 5, i)
245 assert.Equal(t, -1, v.Ep)
246 assert.Equal(t, int64(0), v.Iv)
247 vstring(&s, &i, &v, 0)
248 assert.Equal(t, 13, i)
249 assert.Equal(t, 9, v.Ep)
250 assert.Equal(t, int64(5), v.Iv)
251 }
252
253 func TestNative_Vstring_ValidUnescapedChars(t *testing.T) {
254 var v types.JsonState
255 valid := uint64(types.F_VALIDATE_STRING)
256 i := 0
257 s := "test\x1f\""
258 vstring(&s, &i, &v, valid)
259 assert.Equal(t, -int(types.ERR_INVALID_CHAR), int(v.Vt))
260 }
261
262 func TestNative_VstringEscapeEOF(t *testing.T) {
263 var v types.JsonState
264 i := 0
265 s := `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"x`
266 vstring(&s, &i, &v, 0)
267 assert.Equal(t, 95, i)
268 assert.Equal(t, 63, v.Ep)
269 assert.Equal(t, int64(0), v.Iv)
270 }
271
272 func TestNative_VstringHangUpOnRandomData(t *testing.T) {
273 v, e := hex.DecodeString(
274 "228dc61efd54ef80a908fb6026b7f2d5f92a257ba8b347c995f259eb8685376a" +
275 "8c4500262d9c308b3f3ec2577689cf345d9f86f9b5d18d3e463bec5c22df2d2e" +
276 "4506010eba1dae7278",
277 )
278 assert.Nil(t, e)
279 p := 1
280 s := rt.Mem2Str(v)
281 var js types.JsonState
282 vstring(&s, &p, &js, 0)
283 fmt.Printf("js: %s\n", spew.Sdump(js))
284 }
285
286 func TestNative_Vnumber(t *testing.T) {
287 var v types.JsonState
288 i := 0
289 s := "1234"
290 vnumber(&s, &i, &v)
291 assert.Equal(t, 4, i)
292 assert.Equal(t, 0, v.Ep)
293 assert.Equal(t, int64(1234), v.Iv)
294 assert.Equal(t, types.V_INTEGER, v.Vt)
295 i = 0
296 s = "1.234"
297 vnumber(&s, &i, &v)
298 assert.Equal(t, 5, i)
299 assert.Equal(t, 0, v.Ep)
300 assert.Equal(t, 1.234, v.Dv)
301 assert.Equal(t, types.V_DOUBLE, v.Vt)
302 i = 0
303 s = "1.234e5"
304 vnumber(&s, &i, &v)
305 assert.Equal(t, 7, i)
306 assert.Equal(t, 0, v.Ep)
307 assert.Equal(t, 1.234e5, v.Dv)
308 assert.Equal(t, types.V_DOUBLE, v.Vt)
309 i = 0
310 s = "0.0125"
311 vnumber(&s, &i, &v)
312 assert.Equal(t, 6, i)
313 assert.Equal(t, 0, v.Ep)
314 assert.Equal(t, 0.0125, v.Dv)
315 assert.Equal(t, types.V_DOUBLE, v.Vt)
316 i = 0
317 s = "100000000000000000000"
318 vnumber(&s, &i, &v)
319 assert.Equal(t, 21, i)
320 assert.Equal(t, 0, v.Ep)
321 assert.Equal(t, 100000000000000000000.0, v.Dv)
322 assert.Equal(t, types.V_DOUBLE, v.Vt)
323 i = 0
324 s = "999999999999999900000"
325 vnumber(&s, &i, &v)
326 assert.Equal(t, 21, i)
327 assert.Equal(t, 0, v.Ep)
328 assert.Equal(t, 999999999999999900000.0, v.Dv)
329 assert.Equal(t, types.V_DOUBLE, v.Vt)
330 i = 0
331 s = "-1.234"
332 vnumber(&s, &i, &v)
333 assert.Equal(t, 6, i)
334 assert.Equal(t, 0, v.Ep)
335 assert.Equal(t, -1.234, v.Dv)
336 assert.Equal(t, types.V_DOUBLE, v.Vt)
337 }
338
339 func TestNative_Vsigned(t *testing.T) {
340 var v types.JsonState
341 i := 0
342 s := "1234"
343 vsigned(&s, &i, &v)
344 assert.Equal(t, 4, i)
345 assert.Equal(t, 0, v.Ep)
346 assert.Equal(t, int64(1234), v.Iv)
347 assert.Equal(t, types.V_INTEGER, v.Vt)
348 i = 0
349 s = "-1234"
350 vsigned(&s, &i, &v)
351 assert.Equal(t, 5, i)
352 assert.Equal(t, 0, v.Ep)
353 assert.Equal(t, int64(-1234), v.Iv)
354 assert.Equal(t, types.V_INTEGER, v.Vt)
355 i = 0
356 s = "9223372036854775807"
357 vsigned(&s, &i, &v)
358 assert.Equal(t, 19, i)
359 assert.Equal(t, 0, v.Ep)
360 assert.Equal(t, int64(math.MaxInt64), v.Iv)
361 assert.Equal(t, types.V_INTEGER, v.Vt)
362 i = 0
363 s = "-9223372036854775808"
364 vsigned(&s, &i, &v)
365 assert.Equal(t, 20, i)
366 assert.Equal(t, 0, v.Ep)
367 assert.Equal(t, int64(math.MinInt64), v.Iv)
368 assert.Equal(t, types.V_INTEGER, v.Vt)
369 i = 0
370 s = "9223372036854775808"
371 vsigned(&s, &i, &v)
372 assert.Equal(t, 18, i)
373 assert.Equal(t, 0, v.Ep)
374 assert.Equal(t, types.ValueType(-int(types.ERR_INTEGER_OVERFLOW)), v.Vt)
375 i = 0
376 s = "-9223372036854775809"
377 vsigned(&s, &i, &v)
378 assert.Equal(t, 19, i)
379 assert.Equal(t, 0, v.Ep)
380 assert.Equal(t, types.ValueType(-int(types.ERR_INTEGER_OVERFLOW)), v.Vt)
381 i = 0
382 s = "1.234"
383 vsigned(&s, &i, &v)
384 assert.Equal(t, 1, i)
385 assert.Equal(t, 0, v.Ep)
386 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
387 i = 0
388 s = "0.0125"
389 vsigned(&s, &i, &v)
390 assert.Equal(t, 1, i)
391 assert.Equal(t, 0, v.Ep)
392 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
393 i = 0
394 s = "-1234e5"
395 vsigned(&s, &i, &v)
396 assert.Equal(t, 5, i)
397 assert.Equal(t, 0, v.Ep)
398 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
399 i = 0
400 s = "-1234e-5"
401 vsigned(&s, &i, &v)
402 assert.Equal(t, 5, i)
403 assert.Equal(t, 0, v.Ep)
404 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
405 }
406
407 func TestNative_Vunsigned(t *testing.T) {
408 var v types.JsonState
409 i := 0
410 s := "1234"
411 vunsigned(&s, &i, &v)
412 assert.Equal(t, 4, i)
413 assert.Equal(t, 0, v.Ep)
414 assert.Equal(t, int64(1234), v.Iv)
415 assert.Equal(t, types.V_INTEGER, v.Vt)
416 i = 0
417 s = "18446744073709551615"
418 vunsigned(&s, &i, &v)
419 assert.Equal(t, 20, i)
420 assert.Equal(t, 0, v.Ep)
421 assert.Equal(t, ^int64(0), v.Iv)
422 assert.Equal(t, types.V_INTEGER, v.Vt)
423 i = 0
424 s = "18446744073709551616"
425 vunsigned(&s, &i, &v)
426 assert.Equal(t, 19, i)
427 assert.Equal(t, 0, v.Ep)
428 assert.Equal(t, types.ValueType(-int(types.ERR_INTEGER_OVERFLOW)), v.Vt)
429 i = 0
430 s = "-1234"
431 vunsigned(&s, &i, &v)
432 assert.Equal(t, 0, i)
433 assert.Equal(t, 0, v.Ep)
434 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
435 i = 0
436 s = "1.234"
437 vunsigned(&s, &i, &v)
438 assert.Equal(t, 1, i)
439 assert.Equal(t, 0, v.Ep)
440 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
441 i = 0
442 s = "0.0125"
443 vunsigned(&s, &i, &v)
444 assert.Equal(t, 1, i)
445 assert.Equal(t, 0, v.Ep)
446 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
447 i = 0
448 s = "1234e5"
449 vunsigned(&s, &i, &v)
450 assert.Equal(t, 4, i)
451 assert.Equal(t, 0, v.Ep)
452 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
453 i = 0
454 s = "-1234e5"
455 vunsigned(&s, &i, &v)
456 assert.Equal(t, 0, i)
457 assert.Equal(t, 0, v.Ep)
458 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
459 i = 0
460 s = "-1.234e5"
461 vunsigned(&s, &i, &v)
462 assert.Equal(t, 0, i)
463 assert.Equal(t, 0, v.Ep)
464 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
465 i = 0
466 s = "-1.234e-5"
467 vunsigned(&s, &i, &v)
468 assert.Equal(t, 0, i)
469 assert.Equal(t, 0, v.Ep)
470 assert.Equal(t, types.ValueType(-int(types.ERR_INVALID_NUMBER_FMT)), v.Vt)
471 }
472
473 func TestNative_SkipOne(t *testing.T) {
474 p := 0
475 s := ` {"asdf": [null, true, false, 1, 2.0, -3]}, 1234.5`
476 q := skip_one(&s, &p, &types.StateMachine{}, uint64(0))
477 assert.Equal(t, 42, p)
478 assert.Equal(t, 1, q)
479 p = 0
480 s = `1 2.5 -3 "asdf\nqwer" true false null {} []`
481 q = skip_one(&s, &p, &types.StateMachine{}, uint64(0))
482 assert.Equal(t, 1, p)
483 assert.Equal(t, 0, q)
484 q = skip_one(&s, &p, &types.StateMachine{}, uint64(0))
485 assert.Equal(t, 5, p)
486 assert.Equal(t, 2, q)
487 q = skip_one(&s, &p, &types.StateMachine{}, uint64(0))
488 assert.Equal(t, 8, p)
489 assert.Equal(t, 6, q)
490 q = skip_one(&s, &p, &types.StateMachine{}, uint64(0))
491 assert.Equal(t, 21, p)
492 assert.Equal(t, 9, q)
493 q = skip_one(&s, &p, &types.StateMachine{}, uint64(0))
494 assert.Equal(t, 26, p)
495 assert.Equal(t, 22, q)
496 q = skip_one(&s, &p, &types.StateMachine{}, uint64(0))
497 assert.Equal(t, 32, p)
498 assert.Equal(t, 27, q)
499 q = skip_one(&s, &p, &types.StateMachine{}, uint64(0))
500 assert.Equal(t, 37, p)
501 assert.Equal(t, 33, q)
502 q = skip_one(&s, &p, &types.StateMachine{}, uint64(0))
503 assert.Equal(t, 40, p)
504 assert.Equal(t, 38, q)
505 q = skip_one(&s, &p, &types.StateMachine{}, uint64(0))
506 assert.Equal(t, 43, p)
507 assert.Equal(t, 41, q)
508 }
509
510 func TestNative_SkipOne_Error(t *testing.T) {
511 for _, s := range([]string{
512 "-", "+", "0.", "0. ", "+1", "0.0e ", "9e+", "0e-",
513 "tru", "fals", "nul", "trux", "fals ",
514 `"asdf`, `"\\\"`,
515 }) {
516 p := 0
517 q := skip_one(&s, &p, &types.StateMachine{}, uint64(0))
518 assert.True(t, q < 0)
519 }
520 }
521
522 func TestNative_SkipArray(t *testing.T) {
523 p := 0
524 s := `null, true, false, 1, 2.0, -3, {"asdf": "wqer"}],`
525 skip_array(&s, &p, &types.StateMachine{}, uint64(0))
526 assert.Equal(t, p, 48)
527 }
528
529 func TestNative_SkipObject(t *testing.T) {
530 p := 0
531 s := `"asdf": "wqer"},`
532 skip_object(&s, &p, &types.StateMachine{}, uint64(0))
533 assert.Equal(t, p, 15)
534 }
535
536 func TestNative_SkipNumber(t *testing.T) {
537 p := 0
538 s := `-1.23e+12`
539 q := skip_number(&s, &p)
540 assert.Equal(t, 9, p)
541 assert.Equal(t, 0, q)
542 }
543
544 func TestNative_SkipNumberInJson(t *testing.T) {
545 p := 0x13
546 s := "{\"h\":\"1.00000\",\"i\":true,\"pass3\":1}"
547 q := skip_number(&s, &p)
548 assert.Equal(t, 0x13, p)
549 assert.Equal(t, -2, q)
550 }
551
552 func TestNative_SkipOneFast(t *testing.T) {
553 p := 0
554 s := ` {"asdf": [null, true, false, 1, 2.0, -3]}, 1234.5`
555 q := skip_one_fast(&s, &p)
556 assert.Equal(t, 42, p)
557 assert.Equal(t, 1, q)
558 p = 0
559 s = `1, 2.5, -3, "asdf\nqwer", true, false, null, {}, [],`
560 q = skip_one_fast(&s, &p)
561 assert.Equal(t, 1, p)
562 assert.Equal(t, 0, q)
563 p += 1
564 q = skip_one_fast(&s, &p)
565 assert.Equal(t, 6, p)
566 assert.Equal(t, 3, q)
567 p += 1
568 q = skip_one_fast(&s, &p)
569 assert.Equal(t, 10, p)
570 assert.Equal(t, 8, q)
571 p += 1
572 q = skip_one_fast(&s, &p)
573 assert.Equal(t, 24, p)
574 assert.Equal(t, 12, q)
575 p += 1
576 q = skip_one_fast(&s, &p)
577 assert.Equal(t, 30, p)
578 assert.Equal(t, 26, q)
579 p += 1
580 q = skip_one_fast(&s, &p)
581 assert.Equal(t, 37, p)
582 assert.Equal(t, 32, q)
583 p += 1
584 q = skip_one_fast(&s, &p)
585 assert.Equal(t, 43, p)
586 assert.Equal(t, 39, q)
587 p += 1
588 q = skip_one_fast(&s, &p)
589 assert.Equal(t, 47, p)
590 assert.Equal(t, 45, q)
591 p += 1
592 q = skip_one_fast(&s, &p)
593 assert.Equal(t, 51, p)
594 assert.Equal(t, 49, q)
595 }
596
597 func TestNative_SkipOneFast_Error(t *testing.T) {
598 for _, s := range([]string{
599 "{{", "[{", "{{}",
600 `"asdf`, `"\\\"`,
601 }) {
602 p := 0
603 q := skip_one_fast(&s, &p)
604 assert.True(t, q < 0)
605 }
606 }
607
608 func TestNative_GetByPath(t *testing.T) {
609 s := `{"asdf": [null, true, false, 1, 2.0, -3]}, 1234.5`
610 p := 0
611 path := []interface{}{"asdf", 4}
612 ret := get_by_path(&s, &p, &path, types.NewStateMachine())
613 assert.Equal(t, strings.Index(s, "2.0"), ret)
614 }
615
616 func BenchmarkNative_SkipOneFast(b *testing.B) {
617 b.ResetTimer()
618 for i:=0; i<b.N; i++ {
619 s := `{"asdf": [null, true, false, 1, 2.0, -3]}, 1234.5`
620 p := 0
621 _ = skip_one_fast(&s, &p)
622 }
623 }
624
625 func BenchmarkNative_GetByPath(b *testing.B) {
626 b.ResetTimer()
627 for i:=0; i<b.N; i++ {
628 s := `{"asdf": [null, true, false, 1, 2.0, -3]}, 1234.5`
629 p := 0
630 path := []interface{}{"asdf", 3}
631 sm := types.NewStateMachine()
632 _ = get_by_path(&s, &p, &path, sm)
633 types.FreeStateMachine(sm)
634 }
635 }
View as plain text