github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/search_test.go (about) 1 //go:build amd64 && go1.16 && !go1.22 2 // +build amd64,go1.16,!go1.22 3 4 /* 5 * Copyright 2021 ByteDance Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package sonic 21 22 import ( 23 "bytes" 24 "encoding/hex" 25 "encoding/json" 26 "fmt" 27 "math/rand" 28 "reflect" 29 "strings" 30 "testing" 31 "time" 32 33 "github.com/davecgh/go-spew/spew" 34 "github.com/goshafaq/sonic/ast" 35 "github.com/stretchr/testify/assert" 36 ) 37 38 func Parse(src string) (*ast.Node, error) { 39 node, err := ast.NewParser(src).Parse() 40 if err != 0 { 41 return &node, fmt.Errorf("parsing error: %v", err) 42 } 43 return &node, nil 44 } 45 46 func assertCond(cond bool) { 47 if !cond { 48 panic("assertCond failed") 49 } 50 } 51 52 func TestExampleSearch(t *testing.T) { 53 data := []byte(` { "xx" : [] ,"yy" :{ }, "test" : [ true , 0.1 , "abc", ["h"], {"a":"bc"} ] } `) 54 55 node, e := Get(data, "test", 0) 56 x, _ := node.Bool() 57 if e != nil || x != true { 58 t.Fatalf("node: %v, err: %v", node, e) 59 } 60 61 node, e = Get(data, "test", 1) 62 a, _ := node.Float64() 63 if e != nil || a != 0.1 { 64 t.Fatalf("node: %v, err: %v", node, e) 65 } 66 67 node, e = Get(data, "test", 2) 68 b, _ := node.String() 69 if e != nil || b != "abc" { 70 t.Fatalf("node: %v, err: %v", node, e) 71 } 72 73 node, e = Get(data, "test", 3) 74 arr, _ := node.Array() 75 if e != nil || arr[0] != "h" { 76 t.Fatalf("node: %v, err: %v", node, e) 77 } 78 79 node, e = Get(data, "test", 4, "a") 80 c, _ := node.String() 81 if e != nil || c != "bc" { 82 t.Fatalf("node: %v, err: %v", node, e) 83 } 84 } 85 86 func TestExampleSearchEscapedKey(t *testing.T) { 87 data := []byte(` 88 { 89 "xx" : [] , 90 "yy" :{ }, 91 "test\"" : [ 92 true , 93 0.1 , 94 "abc", 95 [ 96 "h" 97 ], 98 { 99 "a\u0008": {}, 100 "b\\\\": null, 101 "\u2028\u2028": "\u2028\u2029", 102 "\u0026":2, 103 "0":1 104 } 105 ], 106 ",,,,,,,,,,(,,15": ",", 107 ",,,,,,,,,,(,,,16": "a,]}", 108 ",,,,,,,,,,(,,,,17": 1, 109 ",,,,,,,,,,(,,,,,,,,,,,,,,,,(,,,,34": "c" 110 } `) 111 112 type getTest struct { 113 path []interface{} 114 expect interface{} 115 } 116 117 tests := []getTest{ 118 {[]interface{}{"test\"", 0}, true}, 119 {[]interface{}{"test\"", 1}, 0.1}, 120 {[]interface{}{"test\"", 2}, "abc"}, 121 {[]interface{}{"test\"", 3}, []interface{}{"h"}}, 122 {[]interface{}{"test\"", 4, "a\u0008"}, map[string]interface{}{}}, 123 {[]interface{}{"test\"", 4, "b\\\\"}, nil}, 124 {[]interface{}{"test\"", 4, "\u2028\u2028"}, "\u2028\u2029"}, 125 {[]interface{}{"test\"", 4, "0"}, float64(1)}, 126 {[]interface{}{",,,,,,,,,,(,,15"}, ","}, 127 {[]interface{}{",,,,,,,,,,(,,,16"}, "a,]}"}, 128 {[]interface{}{",,,,,,,,,,(,,,,17"}, float64(1)}, 129 {[]interface{}{",,,,,,,,,,(,,,,,,,,,,,,,,,,(,,,,34"}, "c"}, 130 } 131 132 for _, test := range tests { 133 node, err := Get(data, test.path...) 134 assert.NoErrorf(t, err, "get return errors") 135 got, err := node.Interface() 136 assert.NoErrorf(t, err, "get convert errors") 137 assert.Equalf(t, test.expect, got, "get result is wrong from path %#v", test.path) 138 } 139 } 140 141 func TestExampleSearchErr(t *testing.T) { 142 data := []byte(` { "xx" : [] ,"yy" :{ }, "test" : [ true , 0.1 , "abc", ["h"], {"a":"bc"} ] } `) 143 node, e := Get(data, "zz") 144 if e == nil { 145 t.Fatalf("node: %v, err: %v", node, e) 146 } 147 fmt.Println(e) 148 149 node, e = Get(data, "xx", 4) 150 if e == nil { 151 t.Fatalf("node: %v, err: %v", node, e) 152 } 153 fmt.Println(e) 154 155 node, e = Get(data, "yy", "a") 156 if e == nil { 157 t.Fatalf("node: %v, err: %v", node, e) 158 } 159 fmt.Println(e) 160 161 node, e = Get(data, "test", 4, "x") 162 if e == nil { 163 t.Fatalf("node: %v, err: %v", node, e) 164 } 165 fmt.Println(e) 166 } 167 168 func TestExampleSearchEscapedKeyError(t *testing.T) { 169 data := []byte(` { "xx" : [] ,"yy" :{ }, "x\u0008" : [] ,"y\\\"y" :{ }, "test" : [ true , 0.1 , "abc", ["h"], {"a":"bc"} ] } `) 170 node, e := Get(data, "zz") 171 if e == nil { 172 t.Fatalf("node: %v, err: %v", node, e) 173 } 174 fmt.Println(e) 175 176 node, e = Get(data, "x\u0008", 4) 177 if e == nil { 178 t.Fatalf("node: %v, err: %v", node, e) 179 } 180 fmt.Println(e) 181 182 node, e = Get(data, "yy", "a") 183 if e == nil { 184 t.Fatalf("node: %v, err: %v", node, e) 185 } 186 fmt.Println(e) 187 188 node, e = Get(data, "test", 4, "x") 189 if e == nil { 190 t.Fatalf("node: %v, err: %v", node, e) 191 } 192 193 node, e = Get(data, "y\\\"y", 4, "x") 194 if e == nil { 195 t.Fatalf("node: %v, err: %v", node, e) 196 } 197 fmt.Println(e) 198 } 199 200 func TestRandomData(t *testing.T) { 201 var lstr string 202 defer func() { 203 if v := recover(); v != nil { 204 println("'" + hex.Dump([]byte(lstr)) + "'") 205 println(lstr) 206 panic(v) 207 } 208 }() 209 data := []byte(`"�-mp�`) 210 _, err := ast.NewParser(string(data)).Parse() 211 if err != 0 { 212 fmt.Println(hex.Dump(data)) 213 fmt.Println(string(data)) 214 } 215 rand.Seed(time.Now().UnixNano()) 216 b := make([]byte, 200) 217 for i := 0; i < 1000000; i++ { 218 n, ee := rand.Read(b[:rand.Int()%len(b)]) 219 if ee != nil { 220 t.Fatalf("get random bytes failed: %v,", ee) 221 return 222 } 223 lstr = string(b[:n]) 224 _, _ = ast.NewParser(lstr).Parse() 225 } 226 } 227 228 func TestRandomValidStrings(t *testing.T) { 229 rand.Seed(time.Now().UnixNano()) 230 b := make([]byte, 200) 231 for i := 0; i < 1000; i++ { 232 n, err := rand.Read(b[:rand.Int()%len(b)]) 233 if err != nil { 234 t.Fatal("get random data failed:", err) 235 } 236 sm, err := json.Marshal(string(b[:n])) 237 if err != nil { 238 t.Fatal("marshal data failed:", err) 239 } 240 var su string 241 if err := json.Unmarshal(sm, &su); err != nil { 242 t.Fatal("unmarshal data failed:", err) 243 } 244 token, err := GetFromString(`{"str":`+string(sm)+`}`, "str") 245 if err != nil { 246 spew.Dump(string(sm)) 247 t.Fatal("search data failed:", err) 248 } 249 x, _ := token.Interface() 250 st, ok := x.(string) 251 if !ok { 252 t.Fatalf("type mismatch, exp: %v, got: %v", su, x) 253 } 254 if st != su { 255 t.Fatalf("string mismatch, exp: %v, got: %v", su, x) 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 }