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