github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/search_test.go (about) 1 // +build amd64,go1.16,!go1.23 2 3 /* 4 * Copyright 2021 ByteDance Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package sonic 20 21 import ( 22 `bytes` 23 `encoding/hex` 24 `encoding/json` 25 `fmt` 26 `math/rand` 27 `reflect` 28 `strings` 29 `testing` 30 `time` 31 32 `github.com/davecgh/go-spew/spew` 33 `github.com/stretchr/testify/assert` 34 `github.com/bytedance/sonic/ast` 35 ) 36 37 func Parse(src string) (*ast.Node, error) { 38 node, err := ast.NewParser(src).Parse() 39 if err != 0 { 40 return &node, fmt.Errorf("parsing error: %v", err) 41 } 42 return &node, nil 43 } 44 45 func assertCond(cond bool) { 46 if !cond { 47 panic("assertCond failed") 48 } 49 } 50 51 func TestExampleSearch(t *testing.T) { 52 data := []byte(` { "xx" : [] ,"yy" :{ }, "test" : [ true , 0.1 , "abc", ["h"], {"a":"bc"} ] } `) 53 54 node, e := Get(data, "test", 0) 55 x, _ := node.Bool() 56 if e != nil || x != true { 57 t.Fatalf("node: %v, err: %v", node, e) 58 } 59 60 node, e = Get(data, "test", 1) 61 a, _ := node.Float64() 62 if e != nil || a != 0.1 { 63 t.Fatalf("node: %v, err: %v", node, e) 64 } 65 66 node, e = Get(data, "test", 2) 67 b, _ := node.String() 68 if e != nil || b != "abc" { 69 t.Fatalf("node: %v, err: %v", node, e) 70 } 71 72 node, e = Get(data, "test", 3) 73 arr, _ := node.Array() 74 if e != nil || arr[0] != "h" { 75 t.Fatalf("node: %v, err: %v", node, e) 76 } 77 78 node, e = Get(data, "test", 4, "a") 79 c, _ := node.String() 80 if e != nil || c != "bc" { 81 t.Fatalf("node: %v, err: %v", node, e) 82 } 83 } 84 85 func TestExampleSearchEscapedKey(t *testing.T) { 86 data := []byte(` 87 { 88 "xx" : [] , 89 "yy" :{ }, 90 "test\"" : [ 91 true , 92 0.1 , 93 "abc", 94 [ 95 "h" 96 ], 97 { 98 "a\u0008": {}, 99 "b\\\\": null, 100 "\u2028\u2028": "\u2028\u2029", 101 "\u0026":2, 102 "0":1 103 } 104 ], 105 ",,,,,,,,,,(,,15": ",", 106 ",,,,,,,,,,(,,,16": "a,]}", 107 ",,,,,,,,,,(,,,,17": 1, 108 ",,,,,,,,,,(,,,,,,,,,,,,,,,,(,,,,34": "c" 109 } `) 110 111 type getTest struct{ 112 path []interface{} 113 expect interface{} 114 } 115 116 tests := []getTest { 117 {[]interface{}{"test\"", 0}, true}, 118 {[]interface{}{"test\"", 1}, 0.1}, 119 {[]interface{}{"test\"", 2}, "abc"}, 120 {[]interface{}{"test\"", 3}, []interface{}{"h"}}, 121 {[]interface{}{"test\"", 4, "a\u0008"}, map[string]interface{}{}}, 122 {[]interface{}{"test\"", 4, "b\\\\"}, nil}, 123 {[]interface{}{"test\"", 4, "\u2028\u2028"}, "\u2028\u2029"}, 124 {[]interface{}{"test\"", 4, "0"}, float64(1)}, 125 {[]interface{}{",,,,,,,,,,(,,15"}, ","}, 126 {[]interface{}{",,,,,,,,,,(,,,16"}, "a,]}"}, 127 {[]interface{}{",,,,,,,,,,(,,,,17"}, float64(1)}, 128 {[]interface{}{",,,,,,,,,,(,,,,,,,,,,,,,,,,(,,,,34"}, "c"}, 129 } 130 131 for _, test := range(tests) { 132 node, err := Get(data, test.path...) 133 assert.NoErrorf(t, err, "get return errors") 134 got, err := node.Interface() 135 assert.NoErrorf(t, err, "get convert errors") 136 assert.Equalf(t, test.expect, got, "get result is wrong from path %#v", test.path) 137 } 138 } 139 140 func TestExampleSearchErr(t *testing.T) { 141 data := []byte(` { "xx" : [] ,"yy" :{ }, "test" : [ true , 0.1 , "abc", ["h"], {"a":"bc"} ] } `) 142 node, e := Get(data, "zz") 143 if e == nil { 144 t.Fatalf("node: %v, err: %v", node, e) 145 } 146 fmt.Println(e) 147 148 node, e = Get(data, "xx", 4) 149 if e == nil { 150 t.Fatalf("node: %v, err: %v", node, e) 151 } 152 fmt.Println(e) 153 154 node, e = Get(data, "yy", "a") 155 if e == nil { 156 t.Fatalf("node: %v, err: %v", node, e) 157 } 158 fmt.Println(e) 159 160 node, e = Get(data, "test", 4, "x") 161 if e == nil { 162 t.Fatalf("node: %v, err: %v", node, e) 163 } 164 fmt.Println(e) 165 } 166 167 func TestExampleSearchEscapedKeyError(t *testing.T) { 168 data := []byte(` { "xx" : [] ,"yy" :{ }, "x\u0008" : [] ,"y\\\"y" :{ }, "test" : [ true , 0.1 , "abc", ["h"], {"a":"bc"} ] } `) 169 node, e := Get(data, "zz") 170 if e == nil { 171 t.Fatalf("node: %v, err: %v", node, e) 172 } 173 fmt.Println(e) 174 175 node, e = Get(data, "x\u0008", 4) 176 if e == nil { 177 t.Fatalf("node: %v, err: %v", node, e) 178 } 179 fmt.Println(e) 180 181 node, e = Get(data, "yy", "a") 182 if e == nil { 183 t.Fatalf("node: %v, err: %v", node, e) 184 } 185 fmt.Println(e) 186 187 node, e = Get(data, "test", 4, "x") 188 if e == nil { 189 t.Fatalf("node: %v, err: %v", node, e) 190 } 191 192 node, e = Get(data, "y\\\"y", 4, "x") 193 if e == nil { 194 t.Fatalf("node: %v, err: %v", node, e) 195 } 196 fmt.Println(e) 197 } 198 199 func TestRandomData(t *testing.T) { 200 var lstr string 201 defer func() { 202 if v := recover(); v != nil { 203 println("'" + hex.Dump([]byte(lstr)) + "'") 204 println(lstr) 205 panic(v) 206 } 207 }() 208 data := []byte(`"�-mp�`) 209 _, err := ast.NewParser(string(data)).Parse() 210 if err != 0 { 211 fmt.Println(hex.Dump(data)) 212 fmt.Println(string(data)) 213 } 214 rand.Seed(time.Now().UnixNano()) 215 b := make([]byte, 200) 216 for i := 0; i < 1000000; i++ { 217 n, ee := rand.Read(b[:rand.Int()%len(b)]) 218 if ee != nil { 219 t.Fatalf("get random bytes failed: %v,", ee) 220 return 221 } 222 lstr = string(b[:n]) 223 _, _ = ast.NewParser(lstr).Parse() 224 } 225 } 226 227 func TestRandomValidStrings(t *testing.T) { 228 rand.Seed(time.Now().UnixNano()) 229 b := make([]byte, 200) 230 for i := 0; i < 1000; i++ { 231 n, err := rand.Read(b[:rand.Int()%len(b)]) 232 if err != nil { 233 t.Fatal("get random data failed:", err) 234 } 235 sm, err := json.Marshal(string(b[:n])) 236 if err != nil { 237 t.Fatal("marshal data failed:",err) 238 } 239 var su string 240 if err := json.Unmarshal(sm, &su); err != nil { 241 t.Fatal("unmarshal data failed:",err) 242 } 243 token, err := GetFromString(`{"str":`+string(sm)+`}`, "str") 244 if err != nil { 245 spew.Dump(string(sm)) 246 t.Fatal("search data failed:",err) 247 } 248 x, _ := token.Interface() 249 st, ok := x.(string) 250 if !ok { 251 t.Fatalf("type mismatch, exp: %v, got: %v", su, x) 252 } 253 if st != su { 254 t.Fatalf("string mismatch, exp: %v, got: %v", su, x) 255 } 256 } 257 } 258 259 260 func TestEmoji(t *testing.T) { 261 var input = []byte(`{"utf8":"Example emoji, KO: \ud83d\udd13, \ud83c\udfc3 ` + 262 `OK: \u2764\ufe0f "}`) 263 value, err := Get(input, "utf8") 264 if err != nil { 265 t.Fatal(err) 266 } 267 var v map[string]interface{} 268 if err := json.Unmarshal(input, &v); err != nil { 269 t.Fatal(err) 270 } 271 s, _ := v["utf8"].(string) 272 x, _ := value.String() 273 if x != s { 274 t.Fatalf("expected '%v', got '%v'", s, x) 275 } 276 } 277 278 func testEscapePath(t *testing.T, json, expect string, path ...interface{}) { 279 n, e := Get([]byte(json), path...) 280 if e != nil { 281 t.Fatal(e) 282 } 283 x, _ := n.String() 284 if x != expect { 285 x, _ := n.Interface() 286 t.Fatalf("expected '%v', got '%v'", expect, x) 287 } 288 } 289 290 func TestEscapePath(t *testing.T) { 291 data := `{ 292 "test":{ 293 "*":"valZ", 294 "*v":"val0", 295 "keyv*":"val1", 296 "key*v":"val2", 297 "keyv?":"val3", 298 "key?v":"val4", 299 "keyv.":"val5", 300 "key.v":"val6", 301 "keyk*":{"key?":"val7"} 302 } 303 }` 304 305 testEscapePath(t, data, "valZ", "test", "*") 306 testEscapePath(t, data, "val0", "test", "*v") 307 testEscapePath(t, data, "val1", "test", "keyv*") 308 testEscapePath(t, data, "val2", "test", "key*v") 309 testEscapePath(t, data, "val3", "test", "keyv?") 310 testEscapePath(t, data, "val4", "test", "key?v") 311 testEscapePath(t, data, "val5", "test", "keyv.") 312 testEscapePath(t, data, "val6", "test", "key.v") 313 testEscapePath(t, data, "val7", "test", "keyk*", "key?") 314 } 315 316 func TestParseAny(t *testing.T) { 317 n, e := Parse("100") 318 assertCond(e == nil) 319 if n == nil { 320 panic("n is nil") 321 } 322 x, _ := n.Float64() 323 assertCond(x == 100) 324 n, e = Parse("true") 325 assertCond(e == nil) 326 if n == nil { 327 panic("n is nil") 328 } 329 330 a, _ := n.Bool() 331 assertCond(a) 332 n, e = Parse("false") 333 assertCond(e == nil) 334 if n == nil { 335 panic("n is nil") 336 } 337 b, _ := n.Bool() 338 assertCond(b == false) 339 n, e = Parse("yikes") 340 assertCond(e != nil) 341 } 342 343 func TestTime(t *testing.T) { 344 data := []byte(`{ 345 "code": 0, 346 "msg": "", 347 "data": { 348 "sz002024": { 349 "qfqday": [ 350 [ 351 "2014-01-02", 352 "8.93", 353 "9.03", 354 "9.17", 355 "8.88", 356 "621143.00" 357 ], 358 [ 359 "2014-01-03", 360 "9.03", 361 "9.30", 362 "9.47", 363 "8.98", 364 "1624438.00" 365 ] 366 ] 367 } 368 } 369 }`) 370 371 var num []string 372 n, e := Get(data, "data", "sz002024", "qfqday", 0) 373 if e != nil { 374 t.Fatal(e) 375 } 376 377 arr, _ := n.Array() 378 for _, v := range arr { 379 s := v.(string) 380 num = append(num, s) 381 } 382 if fmt.Sprintf("%v", num) != "[2014-01-02 8.93 9.03 9.17 8.88 621143.00]" { 383 t.Fatalf("invalid result") 384 } 385 } 386 387 var exampleJSON = `{ 388 "widget": { 389 "debug": "on", 390 "window": { 391 "title": "Sample Konfabulator Widget", 392 "name": "main_window", 393 "width": 500, 394 "height": 500 395 }, 396 "image": { 397 "src": "Images/Sun.png", 398 "hOffset": 250, 399 "vOffset": 250, 400 "alignment": "center" 401 }, 402 "text": { 403 "data": "Click Here", 404 "size": 36, 405 "style": "bold", 406 "vOffset": 100, 407 "alignment": "center", 408 "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" 409 } 410 } 411 }` 412 413 func TestUnmarshalMap(t *testing.T) { 414 n, err := Parse(exampleJSON) 415 if err != nil || n == nil { 416 t.Fatal(err) 417 } 418 m1, _ := n.Map() 419 var m2 map[string]interface{} 420 if err := json.Unmarshal([]byte(exampleJSON), &m2); err != nil { 421 t.Fatal(err) 422 } 423 b1, err := json.Marshal(m1) 424 if err != nil { 425 t.Fatal(err) 426 } 427 b2, err := json.Marshal(m2) 428 if err != nil { 429 t.Fatal(err) 430 } 431 if !bytes.Equal(b1, b2) { 432 t.Fatalf("b1 != b2\n b1: %v\nb2: %v", string(b1), string(b2)) 433 } 434 } 435 436 func GetMany(src2 string, path ...string) (ret []string) { 437 src := []byte(src2) 438 for _, p := range path { 439 pathes := strings.Split(p, ".") 440 if len(pathes) == 0 { 441 panic(fmt.Sprintf("invalid path: %v", p)) 442 } 443 ps := make([]interface{}, 0, len(pathes)) 444 for _, p := range pathes { 445 ps = append(ps, p) 446 } 447 n, e := Get(src, ps...) 448 if e != nil { 449 ret = append(ret, "") 450 continue 451 } 452 x, _ := n.Interface() 453 ret = append(ret, fmt.Sprintf("%v", x)) 454 } 455 return 456 } 457 458 func get(str string, path string) *ast.Node { 459 src := []byte(str) 460 pathes := strings.Split(path, ".") 461 if len(pathes) == 0 { 462 panic(fmt.Sprintf("invalid path: %v", path)) 463 } 464 ps := make([]interface{}, 0, len(pathes)) 465 for _, p := range pathes { 466 ps = append(ps, p) 467 } 468 n, e := Get(src, ps...) 469 if e != nil { 470 return nil 471 } 472 return &n 473 } 474 475 func TestSingleArrayValue(t *testing.T) { 476 var data = []byte(`{"key": "value","key2":[1,2,3,4,"A"]}`) 477 array, _ := get(string(data), "key2").Array() 478 if len(array) != 5 { 479 t.Fatalf("got '%v', expected '%v'", len(array), 5) 480 } 481 482 _, e := Get(data, "key3") 483 if e == nil { 484 t.Fatalf("got '%v', expected '%v'", e, nil) 485 } 486 } 487 488 var manyJSON = ` { 489 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 490 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 491 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 492 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 493 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 494 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 495 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"hello":"world" 496 }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, 497 "position":{"type":"Point","coordinates":[-115.24,33.09]}, 498 "loves":["world peace"], 499 "name":{"last":"Anderson","first":"Nancy"}, 500 "age":31, 501 "x":{"a":"emptya","b":"emptyb"}, 502 "name_last":"Yellow", 503 "name_first":"Cat", 504 }` 505 506 func TestManyBasic(t *testing.T) { 507 testMany := func(shouldFallback bool, expect string, paths ...string) { 508 println() 509 rs := GetMany( 510 manyJSON, 511 paths..., 512 ) 513 // if len(rs) != len(paths) { 514 // t.Fatalf("expected %v, got %v", len(paths), len(rs)) 515 // } 516 var results = "[" + strings.Join(rs, " ") + "]" 517 if results != expect { 518 fmt.Printf("%v\n", paths) 519 t.Fatalf("expected %v, got %v", expect, results) 520 } 521 } 522 testMany(false, "[Point]", "position.type") 523 testMany(false, `[emptya [world peace] 31]`, "x.a", "loves", "age") 524 testMany(false, `[[world peace]]`, "loves") 525 testMany(false, `[map[first:Nancy last:Anderson] Nancy]`, "name", 526 "name.first") 527 testMany(true, `[]`, strings.Repeat("a.", 40)+"hello") 528 res := get(manyJSON, strings.Repeat("a.", 48)+"a") 529 assertCond(res != nil) 530 x, _ := res.Interface() 531 testMany(true, "["+fmt.Sprint(x)+"]", strings.Repeat("a.", 48)+"a") 532 // these should fallback 533 testMany(true, `[Cat Nancy]`, "name_first", "name.first") 534 testMany(true, `[world]`, strings.Repeat("a.", 70)+"hello") 535 } 536 537 func testMany(t *testing.T, json string, paths, expected []string) { 538 testManyAny(t, json, paths, expected) 539 testManyAny(t, json, paths, expected) 540 } 541 542 func testManyAny(t *testing.T, json string, paths, expected []string) { 543 var result []string 544 for i := 0; i < 2; i++ { 545 var which string 546 if i == 0 { 547 which = "Get" 548 result = nil 549 for j := 0; j < len(expected); j++ { 550 x, _ := get(json, paths[j]).Interface() 551 result = append(result, fmt.Sprintf("%v", x)) 552 } 553 } else if i == 1 { 554 which = "GetMany" 555 result = GetMany(json, paths...) 556 } 557 if result == nil { 558 panic("result is nil") 559 } 560 for j := 0; j < len(expected); j++ { 561 if result[j] != expected[j] { 562 t.Fatalf("Using key '%s' for '%s'\nexpected '%v', got '%v'", 563 paths[j], which, expected[j], result[j]) 564 } 565 } 566 } 567 } 568 569 func TestNested(t *testing.T) { 570 data := `{ "name": "FirstName", "name1": "FirstName1", ` + 571 `"address": "address1", "addressDetails": "address2", }` 572 paths := []string{"name", "name1", "address", "addressDetails"} 573 expected := []string{"FirstName", "FirstName1", "address1", "address2"} 574 t.Run("SingleMany", func(t *testing.T) { 575 testMany(t, data, paths, 576 expected) 577 }) 578 } 579 580 func TestMultiLevelFields(t *testing.T) { 581 data := `{ "Level1Field1":3, 582 "Level1Field4":4, 583 "Level1Field2":{ "Level2Field1":[ "value1", "value2" ], 584 "Level2Field2":{ "Level3Field1":[ { "key1":"value1" } ] } } }` 585 paths := []string{"Level1Field1", "Level1Field2.Level2Field1", 586 "Level1Field2.Level2Field2.Level3Field1", "Level1Field4"} 587 expected := []string{"3", `[value1 value2]`, 588 `[map[key1:value1]]`, "4"} 589 t.Run("SingleMany", func(t *testing.T) { 590 testMany(t, data, paths, 591 expected) 592 }) 593 } 594 595 func TestRandomMany(t *testing.T) { 596 var lstr string 597 defer func() { 598 if v := recover(); v != nil { 599 println("'" + hex.EncodeToString([]byte(lstr)) + "'") 600 println("'" + lstr + "'") 601 panic(v) 602 } 603 }() 604 rand.Seed(time.Now().UnixNano()) 605 b := make([]byte, 512) 606 for i := 0; i < 5000; i++ { 607 n, err := rand.Read(b[:rand.Int()%len(b)]) 608 if err != nil { 609 t.Fatal(err) 610 } 611 lstr = string(b[:n]) 612 paths := make([]string, rand.Int()%64) 613 for i := range paths { 614 var b []byte 615 n := rand.Int() % 5 616 for j := 0; j < n; j++ { 617 if j > 0 { 618 b = append(b, '.') 619 } 620 nn := rand.Int() % 10 621 for k := 0; k < nn; k++ { 622 b = append(b, 'a'+byte(rand.Int()%26)) 623 } 624 } 625 paths[i] = string(b) 626 } 627 GetMany(lstr, paths...) 628 } 629 } 630 631 func TestGetMany(t *testing.T) { 632 data := `{"bar": {"id": 99, "mybar": "my mybar" }, "foo": ` + 633 `{"myfoo": [605]}}` 634 paths := []string{"foo.myfoo", "bar.id", "bar.mybar", "bar.mybarx"} 635 expected := []string{"[605]", "99", "my mybar", ""} 636 results := GetMany(data, paths...) 637 if len(expected) != len(results) { 638 t.Fatalf("expected %v, got %v", len(expected), len(results)) 639 } 640 for i, path := range paths { 641 if results[i] != expected[i] { 642 t.Fatalf("expected '%v', got '%v' for path '%v'", expected[i], 643 results[i], path) 644 } 645 } 646 } 647 648 func TestGetMany2(t *testing.T) { 649 data := `{"bar": {"id": 99, "xyz": "my xyz"}, "foo": {"myfoo": [605]}}` 650 paths := []string{"foo.myfoo", "bar.id", "bar.xyz", "bar.abc"} 651 expected := []string{"[605]", "99", "my xyz", ""} 652 results := GetMany(data, paths...) 653 if len(expected) != len(results) { 654 t.Fatalf("expected %v, got %v", len(expected), len(results)) 655 } 656 for i, path := range paths { 657 if results[i] != expected[i] { 658 t.Fatalf("expected '%v', got '%v' for path '%v'", expected[i], 659 results[i], path) 660 } 661 } 662 } 663 664 func TestNullArray(t *testing.T) { 665 n, _ := get(`{"data":null}`, "data").Interface() 666 if n != nil { 667 t.Fatalf("expected '%v', got '%v'", nil, n) 668 } 669 n = get(`{}`, "data") 670 if reflect.DeepEqual(n, nil) { 671 t.Fatalf("expected '%v', got '%v'", nil, n) 672 } 673 n = get(`{"data":[]}`, "data") 674 if reflect.DeepEqual(n, &ast.Node{}) { 675 t.Fatalf("expected '%v', got '%v'", nil, n) 676 } 677 arr, _ := get(`{"data":[null]}`, "data").Array() 678 n = len(arr) 679 if n != 1 { 680 t.Fatalf("expected '%v', got '%v'", 1, n) 681 } 682 } 683 684 func TestGetMany3(t *testing.T) { 685 var r []string 686 data := `{"MarketName":null,"Nounce":6115}` 687 r = GetMany(data, "Nounce", "Buys", "Sells", "Fills") 688 if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" { 689 t.Fatalf("expected '%v', got '%v'", "[6115]", 690 strings.Replace(fmt.Sprintf("%v", r), " ", "", -1)) 691 } 692 r = GetMany(data, "Nounce", "Buys", "Sells") 693 if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" { 694 t.Fatalf("expected '%v', got '%v'", "[6115]", 695 strings.Replace(fmt.Sprintf("%v", r), " ", "", -1)) 696 } 697 r = GetMany(data, "Nounce") 698 if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" { 699 t.Fatalf("expected '%v', got '%v'", "[6115]", 700 strings.Replace(fmt.Sprintf("%v", r), " ", "", -1)) 701 } 702 } 703 704 func TestGetMany4(t *testing.T) { 705 data := `{"one": {"two": 2, "three": 3}, "four": 4, "five": 5}` 706 results := GetMany(data, "four", "five", "one.two", "one.six") 707 expected := []string{"4", "5", "2", ""} 708 for i, r := range results { 709 if r != expected[i] { 710 t.Fatalf("expected %v, got %v", expected[i], r) 711 } 712 } 713 } 714 715 func TestGetNotExist(t *testing.T) { 716 var dataStr = `{"m1":{"m2":3}}` 717 ret, err := GetFromString(dataStr, "not_exist", "m3") 718 if err == nil || ret.Exists() { 719 t.Fatal("Get exist!") 720 } 721 if ret.Type() != ast.V_NONE { 722 t.Fatal(ret.Type()) 723 } 724 ret, err = GetFromString(dataStr) 725 if !ret.IsRaw() || ret.Type() != ast.V_OBJECT { 726 t.Fatal(ret.Type()) 727 } 728 v11 := ret.Get("not_exist") 729 if v11.Exists() { 730 t.Fatal() 731 } 732 v2 := ret.GetByPath("m1", "m2") 733 if !v2.Exists() || !v2.IsRaw() { 734 t.Fatal(ret.Type()) 735 } 736 x, _ := v2.Int64() 737 if x != 3 { 738 t.Fatal(x) 739 } 740 }