github.com/zhangdapeng520/zdpgo_json@v0.1.5/query/query_test.go (about) 1 package query 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "encoding/json" 7 "fmt" 8 "math" 9 "math/rand" 10 "strconv" 11 "strings" 12 "testing" 13 "time" 14 ) 15 16 // 测试查询json的功能 17 func TestGet(t *testing.T) { 18 const jsonStr = `{"name":{"first":"dapeng","last":"zhang"},"age":47, "gender":true}` 19 20 // 查找字符串 21 value := Get(jsonStr, "name.last") 22 println(value.String()) 23 24 // 查找数字 25 age := Get(jsonStr, "age") 26 fmt.Println(age.Int()) 27 28 // 查找布尔值 29 gender := Get(jsonStr, "gender") 30 fmt.Println(gender.Bool()) 31 } 32 33 // 测试查询语法 34 func TestPathSyntax(t *testing.T) { 35 const jsonStr = `{ 36 "name": {"first": "Tom", "last": "Anderson"}, 37 "age":37, 38 "children": ["Sara","Alex","Jack"], 39 "fav.movie": "Deer Hunter", 40 "friends": [ 41 {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]}, 42 {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]}, 43 {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]} 44 ] 45 }` 46 47 // 查找字符串 48 value := Get(jsonStr, "name.last") 49 println(value.String()) 50 51 // 获取数组长度 52 arrLen := Get(jsonStr, "children.#") 53 println(arrLen.Int()) 54 55 // 获取数组指定索引元素 56 arrIndex := Get(jsonStr, "children.1") 57 println(arrIndex.String()) 58 59 // 模糊匹配获取数组指定索引元素 60 arrLikeIndex := Get(jsonStr, "child*.2") 61 println(arrLikeIndex.String()) 62 63 // 模糊匹配获取数组指定索引元素 64 arrLikeOneIndex := Get(jsonStr, "c?ildren.0") 65 println(arrLikeOneIndex.String()) 66 67 // 键本身包含小数点,使用转义字符 68 trans := Get(jsonStr, `fav\.movie`) // 注意:不要用双引号 69 println(trans.String()) 70 71 // 取所有数组的指定元素 72 arrAllFrist := Get(jsonStr, "friends.#.first") 73 println(arrAllFrist.Array()) 74 for _, v := range arrAllFrist.Array() { 75 fmt.Print(v, " ") 76 } 77 fmt.Println() 78 79 // 取指定数组的指定元素 80 arrFirstFrist := Get(jsonStr, "friends.1.first") 81 println(arrFirstFrist.String()) 82 } 83 84 // 测试过滤器的使用 85 func TestModifierFilter(t *testing.T) { 86 const jsonStr = `{ 87 "name": {"first": "Tom", "last": "Anderson"}, 88 "age":37, 89 "children": ["Sara","Alex","Jack"], 90 "fav.movie": "Deer Hunter", 91 "friends": [ 92 {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]}, 93 {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]}, 94 {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]} 95 ] 96 }` 97 98 // 自定义过滤器 99 AddModifier("case", func(jsonStr, arg string) string { 100 if arg == "upper" { 101 return strings.ToUpper(jsonStr) 102 } 103 if arg == "lower" { 104 return strings.ToLower(jsonStr) 105 } 106 return jsonStr 107 }) 108 109 // 使用过滤器 110 value := Get(jsonStr, "children|@case:upper") 111 for _, v := range value.Array() { 112 fmt.Print(v, " ") 113 } 114 fmt.Println() 115 116 value = Get(jsonStr, "children|@case:lower") 117 for _, v := range value.Array() { 118 fmt.Print(v, " ") 119 } 120 fmt.Println() 121 } 122 123 // 测试遍历每一行数据 124 func TestLines(t *testing.T) { 125 const jsonStr = `{"name": "Gilbert", "age": 61} 126 {"name": "Alexa", "age": 34} 127 {"name": "May", "age": 57} 128 {"name": "Deloise", "age": 44}` 129 130 // 遍历每一行jsonStr 131 ForEachLine(jsonStr, func(line Result) bool { 132 println(line.String()) 133 return true 134 }) 135 } 136 137 // 测试遍历数组 138 func TestForeachArray(t *testing.T) { 139 const jsonStr = `{ 140 "programmers": [ 141 { 142 "firstName": "Janet", 143 "lastName": "McLaughlin", 144 }, { 145 "firstName": "Elliotte", 146 "lastName": "Hunter", 147 }, { 148 "firstName": "Jason", 149 "lastName": "Harold", 150 } 151 ] 152 }` 153 154 // 获取每一行的lastName 155 result := Get(jsonStr, "programmers.#.lastName") 156 for _, name := range result.Array() { 157 println(name.String()) 158 } 159 160 // 查找lastName为Hunter的数据 161 name := Get(jsonStr, `programmers.#(lastName="Hunter").firstName`) 162 println(name.String()) 163 164 // 遍历数组 165 result = Get(jsonStr, "programmers") 166 result.ForEach(func(_, value Result) bool { 167 println(value.String()) 168 return true // keep iterating 169 }) 170 } 171 172 // 测试判断数据是否存在 173 func TestExists(t *testing.T) { 174 const jsonStr = `{ 175 "programmers": [ 176 { 177 "firstName": "Janet", 178 "lastName": "McLaughlin" 179 }, { 180 "firstName": "Elliotte", 181 "lastName": "Hunter" 182 }, { 183 "firstName": "Jason", 184 "lastName": "Harold" 185 } 186 ] 187 }` 188 189 // 判断是否为jsonStr字符串 190 if !Valid(jsonStr) { 191 fmt.Println("json数据格式校验失败") 192 } 193 } 194 195 // 测试解析随机数据 196 func TestRandomData(t *testing.T) { 197 var lstr string 198 defer func() { 199 if v := recover(); v != nil { 200 println("'" + hex.EncodeToString([]byte(lstr)) + "'") 201 println("'" + lstr + "'") 202 panic(v) 203 } 204 }() 205 rand.Seed(time.Now().UnixNano()) 206 b := make([]byte, 200) 207 for i := 0; i < 2000000; i++ { 208 n, err := rand.Read(b[:rand.Int()%len(b)]) 209 if err != nil { 210 t.Fatal(err) 211 } 212 lstr = string(b[:n]) 213 GetBytes([]byte(lstr), "zzzz") 214 Parse(lstr) 215 } 216 } 217 218 // 测试校验随机的字符串 219 func TestRandomValidStrings(t *testing.T) { 220 rand.Seed(time.Now().UnixNano()) 221 b := make([]byte, 200) 222 for i := 0; i < 100000; i++ { 223 n, err := rand.Read(b[:rand.Int()%len(b)]) 224 if err != nil { 225 t.Fatal(err) 226 } 227 sm, err := json.Marshal(string(b[:n])) 228 if err != nil { 229 t.Fatal(err) 230 } 231 var su string 232 if err := json.Unmarshal([]byte(sm), &su); err != nil { 233 t.Fatal(err) 234 } 235 token := Get(`{"str":`+string(sm)+`}`, "str") 236 if token.Type != String || token.Str != su { 237 println("["+token.Raw+"]", "["+token.Str+"]", "["+su+"]", 238 "["+string(sm)+"]") 239 t.Fatal("string mismatch") 240 } 241 } 242 } 243 244 // 测试校验emoji标签 245 func TestEmoji(t *testing.T) { 246 const input = `{"utf8":"Example emoji, KO: \ud83d\udd13, \ud83c\udfc3 ` + 247 `OK: \u2764\ufe0f "}` 248 value := Get(input, "utf8") 249 var s string 250 json.Unmarshal([]byte(value.Raw), &s) 251 if value.String() != s { 252 t.Fatalf("expected '%v', got '%v'", s, value.String()) 253 } 254 } 255 256 // 测试转换路径 257 func testEscapePath(t *testing.T, json, path, expect string) { 258 if Get(json, path).String() != expect { 259 t.Fatalf("expected '%v', got '%v'", expect, Get(json, path).String()) 260 } 261 } 262 263 func TestEscapePath(t *testing.T) { 264 jsonStr := `{ 265 "test":{ 266 "*":"valZ", 267 "*v":"val0", 268 "keyv*":"val1", 269 "key*v":"val2", 270 "keyv?":"val3", 271 "key?v":"val4", 272 "keyv.":"val5", 273 "key.v":"val6", 274 "keyk*":{"key?":"val7"} 275 } 276 }` 277 278 testEscapePath(t, jsonStr, "test.\\*", "valZ") 279 testEscapePath(t, jsonStr, "test.\\*v", "val0") 280 testEscapePath(t, jsonStr, "test.keyv\\*", "val1") 281 testEscapePath(t, jsonStr, "test.key\\*v", "val2") 282 testEscapePath(t, jsonStr, "test.keyv\\?", "val3") 283 testEscapePath(t, jsonStr, "test.key\\?v", "val4") 284 testEscapePath(t, jsonStr, "test.keyv\\.", "val5") 285 testEscapePath(t, jsonStr, "test.key\\.v", "val6") 286 testEscapePath(t, jsonStr, "test.keyk\\*.key\\?", "val7") 287 } 288 289 // this json block is poorly formed on purpose. 290 var basicJSON = ` {"age":100, "name":{"here":"B\\\"R"}, 291 "noop":{"what is a wren?":"a bird"}, 292 "happy":true,"immortal":false, 293 "items":[1,2,3,{"tags":[1,2,3],"points":[[1,2],[3,4]]},4,5,6,7], 294 "arr":["1",2,"3",{"hello":"world"},"4",5], 295 "vals":[1,2,3,{"sadf":sdf"asdf"}],"name":{"first":"tom","last":null}, 296 "created":"2014-05-16T08:28:06.989Z", 297 "loggy":{ 298 "programmers": [ 299 { 300 "firstName": "Brett", 301 "lastName": "McLaughlin", 302 "email": "aaaa", 303 "tag": "good" 304 }, 305 { 306 "firstName": "Jason", 307 "lastName": "Hunter", 308 "email": "bbbb", 309 "tag": "bad" 310 }, 311 { 312 "firstName": "Elliotte", 313 "lastName": "Harold", 314 "email": "cccc", 315 "tag":, "good" 316 }, 317 { 318 "firstName": 1002.3, 319 "age": 101 320 } 321 ] 322 }, 323 "lastly":{"end...ing":"soon","yay":"final"} 324 }` 325 326 // 测试路径 327 func TestPath(t *testing.T) { 328 jsonStr := basicJSON 329 r := Get(jsonStr, "@this") 330 path := r.Path(jsonStr) 331 if path != "@this" { 332 t.FailNow() 333 } 334 335 r = Parse(jsonStr) 336 path = r.Path(jsonStr) 337 if path != "@this" { 338 t.FailNow() 339 } 340 341 obj := Parse(jsonStr) 342 obj.ForEach(func(key, val Result) bool { 343 kp := key.Path(jsonStr) 344 assert(t, kp == "") 345 vp := val.Path(jsonStr) 346 if vp == "name" { 347 // there are two "name" keys 348 return true 349 } 350 val2 := obj.Get(vp) 351 assert(t, val2.Raw == val.Raw) 352 return true 353 }) 354 arr := obj.Get("loggy.programmers") 355 arr.ForEach(func(_, val Result) bool { 356 vp := val.Path(jsonStr) 357 val2 := Get(jsonStr, vp) 358 assert(t, val2.Raw == val.Raw) 359 return true 360 }) 361 get := func(path string) { 362 r1 := Get(jsonStr, path) 363 path2 := r1.Path(jsonStr) 364 r2 := Get(jsonStr, path2) 365 assert(t, r1.Raw == r2.Raw) 366 } 367 get("age") 368 get("name") 369 get("name.here") 370 get("noop") 371 get("noop.what is a wren?") 372 get("arr.0") 373 get("arr.1") 374 get("arr.2") 375 get("arr.3") 376 get("arr.3.hello") 377 get("arr.4") 378 get("arr.5") 379 get("loggy.programmers.2.email") 380 get("lastly.end\\.\\.\\.ing") 381 get("lastly.yay") 382 383 } 384 385 // 测试时间类型 386 func TestTimeResult(t *testing.T) { 387 assert(t, Get(basicJSON, "created").String() == 388 Get(basicJSON, "created").Time().Format(time.RFC3339Nano)) 389 } 390 391 // 测试解析任意类型数据 392 func TestParseAny(t *testing.T) { 393 assert(t, Parse("100").Float() == 100) 394 assert(t, Parse("true").Bool()) 395 assert(t, Parse("false").Bool() == false) 396 assert(t, Parse("yikes").Exists() == false) 397 } 398 399 func TestManyVariousPathCounts(t *testing.T) { 400 jsonStr := `{"a":"a","b":"b","c":"c"}` 401 counts := []int{3, 4, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 402 128, 129, 255, 256, 257, 511, 512, 513} 403 paths := []string{"a", "b", "c"} 404 expects := []string{"a", "b", "c"} 405 for _, count := range counts { 406 var gpaths []string 407 for i := 0; i < count; i++ { 408 if i < len(paths) { 409 gpaths = append(gpaths, paths[i]) 410 } else { 411 gpaths = append(gpaths, fmt.Sprintf("not%d", i)) 412 } 413 } 414 results := GetMany(jsonStr, gpaths...) 415 for i := 0; i < len(paths); i++ { 416 if results[i].String() != expects[i] { 417 t.Fatalf("expected '%v', got '%v'", expects[i], 418 results[i].String()) 419 } 420 } 421 } 422 } 423 func TestManyRecursion(t *testing.T) { 424 var jsonStr string 425 var path string 426 for i := 0; i < 100; i++ { 427 jsonStr += `{"a":` 428 path += ".a" 429 } 430 jsonStr += `"b"` 431 for i := 0; i < 100; i++ { 432 jsonStr += `}` 433 } 434 path = path[1:] 435 assert(t, GetMany(jsonStr, path)[0].String() == "b") 436 } 437 func TestByteSafety(t *testing.T) { 438 jsonb := []byte(`{"name":"Janet","age":38}`) 439 mtok := GetBytes(jsonb, "name") 440 if mtok.String() != "Janet" { 441 t.Fatalf("expected %v, got %v", "Jason", mtok.String()) 442 } 443 mtok2 := GetBytes(jsonb, "age") 444 if mtok2.Raw != "38" { 445 t.Fatalf("expected %v, got %v", "Jason", mtok2.Raw) 446 } 447 jsonb[9] = 'T' 448 jsonb[12] = 'd' 449 jsonb[13] = 'y' 450 if mtok.String() != "Janet" { 451 t.Fatalf("expected %v, got %v", "Jason", mtok.String()) 452 } 453 } 454 455 func get(json, path string) Result { 456 return GetBytes([]byte(json), path) 457 } 458 459 func TestBasic(t *testing.T) { 460 var mtok Result 461 mtok = get(basicJSON, `loggy.programmers.#[tag="good"].firstName`) 462 if mtok.String() != "Brett" { 463 t.Fatalf("expected %v, got %v", "Brett", mtok.String()) 464 } 465 mtok = get(basicJSON, `loggy.programmers.#[tag="good"]#.firstName`) 466 if mtok.String() != `["Brett","Elliotte"]` { 467 t.Fatalf("expected %v, got %v", `["Brett","Elliotte"]`, mtok.String()) 468 } 469 } 470 471 func TestIsArrayIsObject(t *testing.T) { 472 mtok := get(basicJSON, "loggy") 473 assert(t, mtok.IsObject()) 474 assert(t, !mtok.IsArray()) 475 476 mtok = get(basicJSON, "loggy.programmers") 477 assert(t, !mtok.IsObject()) 478 assert(t, mtok.IsArray()) 479 480 mtok = get(basicJSON, `loggy.programmers.#[tag="good"]#.firstName`) 481 assert(t, mtok.IsArray()) 482 483 mtok = get(basicJSON, `loggy.programmers.0.firstName`) 484 assert(t, !mtok.IsObject()) 485 assert(t, !mtok.IsArray()) 486 } 487 488 func TestPlus53BitInts(t *testing.T) { 489 jsonStr := `{"IdentityData":{"GameInstanceId":634866135153775564}}` 490 value := Get(jsonStr, "IdentityData.GameInstanceId") 491 assert(t, value.Uint() == 634866135153775564) 492 assert(t, value.Int() == 634866135153775564) 493 assert(t, value.Float() == 634866135153775616) 494 495 jsonStr = `{"IdentityData":{"GameInstanceId":634866135153775564.88172}}` 496 value = Get(jsonStr, "IdentityData.GameInstanceId") 497 assert(t, value.Uint() == 634866135153775616) 498 assert(t, value.Int() == 634866135153775616) 499 assert(t, value.Float() == 634866135153775616.88172) 500 501 jsonStr = `{ 502 "min_uint64": 0, 503 "max_uint64": 18446744073709551615, 504 "overflow_uint64": 18446744073709551616, 505 "min_int64": -9223372036854775808, 506 "max_int64": 9223372036854775807, 507 "overflow_int64": 9223372036854775808, 508 "min_uint53": 0, 509 "max_uint53": 4503599627370495, 510 "overflow_uint53": 4503599627370496, 511 "min_int53": -2251799813685248, 512 "max_int53": 2251799813685247, 513 "overflow_int53": 2251799813685248 514 }` 515 516 assert(t, Get(jsonStr, "min_uint53").Uint() == 0) 517 assert(t, Get(jsonStr, "max_uint53").Uint() == 4503599627370495) 518 assert(t, Get(jsonStr, "overflow_uint53").Int() == 4503599627370496) 519 assert(t, Get(jsonStr, "min_int53").Int() == -2251799813685248) 520 assert(t, Get(jsonStr, "max_int53").Int() == 2251799813685247) 521 assert(t, Get(jsonStr, "overflow_int53").Int() == 2251799813685248) 522 assert(t, Get(jsonStr, "min_uint64").Uint() == 0) 523 assert(t, Get(jsonStr, "max_uint64").Uint() == 18446744073709551615) 524 // this next value overflows the max uint64 by one which will just 525 // flip the number to zero 526 assert(t, Get(jsonStr, "overflow_uint64").Int() == 0) 527 assert(t, Get(jsonStr, "min_int64").Int() == -9223372036854775808) 528 assert(t, Get(jsonStr, "max_int64").Int() == 9223372036854775807) 529 // this next value overflows the max int64 by one which will just 530 // flip the number to the negative sign. 531 assert(t, Get(jsonStr, "overflow_int64").Int() == -9223372036854775808) 532 } 533 func TestIssue38(t *testing.T) { 534 // These should not fail, even though the unicode is invalid. 535 Get(`["S3O PEDRO DO BUTI\udf93"]`, "0") 536 Get(`["S3O PEDRO DO BUTI\udf93asdf"]`, "0") 537 Get(`["S3O PEDRO DO BUTI\udf93\u"]`, "0") 538 Get(`["S3O PEDRO DO BUTI\udf93\u1"]`, "0") 539 Get(`["S3O PEDRO DO BUTI\udf93\u13"]`, "0") 540 Get(`["S3O PEDRO DO BUTI\udf93\u134"]`, "0") 541 Get(`["S3O PEDRO DO BUTI\udf93\u1345"]`, "0") 542 Get(`["S3O PEDRO DO BUTI\udf93\u1345asd"]`, "0") 543 } 544 func TestTypes(t *testing.T) { 545 assert(t, (Result{Type: String}).Type.String() == "String") 546 assert(t, (Result{Type: Number}).Type.String() == "Number") 547 assert(t, (Result{Type: Null}).Type.String() == "Null") 548 assert(t, (Result{Type: False}).Type.String() == "False") 549 assert(t, (Result{Type: True}).Type.String() == "True") 550 assert(t, (Result{Type: JSON}).Type.String() == "JSON") 551 assert(t, (Result{Type: 100}).Type.String() == "") 552 // bool 553 assert(t, (Result{Type: True}).Bool() == true) 554 assert(t, (Result{Type: False}).Bool() == false) 555 assert(t, (Result{Type: Number, Num: 1}).Bool() == true) 556 assert(t, (Result{Type: Number, Num: 0}).Bool() == false) 557 assert(t, (Result{Type: String, Str: "1"}).Bool() == true) 558 assert(t, (Result{Type: String, Str: "T"}).Bool() == true) 559 assert(t, (Result{Type: String, Str: "t"}).Bool() == true) 560 assert(t, (Result{Type: String, Str: "true"}).Bool() == true) 561 assert(t, (Result{Type: String, Str: "True"}).Bool() == true) 562 assert(t, (Result{Type: String, Str: "TRUE"}).Bool() == true) 563 assert(t, (Result{Type: String, Str: "tRuE"}).Bool() == true) 564 assert(t, (Result{Type: String, Str: "0"}).Bool() == false) 565 assert(t, (Result{Type: String, Str: "f"}).Bool() == false) 566 assert(t, (Result{Type: String, Str: "F"}).Bool() == false) 567 assert(t, (Result{Type: String, Str: "false"}).Bool() == false) 568 assert(t, (Result{Type: String, Str: "False"}).Bool() == false) 569 assert(t, (Result{Type: String, Str: "FALSE"}).Bool() == false) 570 assert(t, (Result{Type: String, Str: "fAlSe"}).Bool() == false) 571 assert(t, (Result{Type: String, Str: "random"}).Bool() == false) 572 573 // int 574 assert(t, (Result{Type: String, Str: "1"}).Int() == 1) 575 assert(t, (Result{Type: True}).Int() == 1) 576 assert(t, (Result{Type: False}).Int() == 0) 577 assert(t, (Result{Type: Number, Num: 1}).Int() == 1) 578 // uint 579 assert(t, (Result{Type: String, Str: "1"}).Uint() == 1) 580 assert(t, (Result{Type: True}).Uint() == 1) 581 assert(t, (Result{Type: False}).Uint() == 0) 582 assert(t, (Result{Type: Number, Num: 1}).Uint() == 1) 583 // float 584 assert(t, (Result{Type: String, Str: "1"}).Float() == 1) 585 assert(t, (Result{Type: True}).Float() == 1) 586 assert(t, (Result{Type: False}).Float() == 0) 587 assert(t, (Result{Type: Number, Num: 1}).Float() == 1) 588 } 589 func TestForEach(t *testing.T) { 590 Result{}.ForEach(nil) 591 Result{Type: String, Str: "Hello"}.ForEach(func(_, value Result) bool { 592 assert(t, value.String() == "Hello") 593 return false 594 }) 595 Result{Type: JSON, Raw: "*invalid*"}.ForEach(nil) 596 597 jsonStr := ` {"name": {"first": "Janet","last": "Prichard"}, 598 "asd\nf":"\ud83d\udd13","age": 47}` 599 var count int 600 ParseBytes([]byte(jsonStr)).ForEach(func(key, value Result) bool { 601 count++ 602 return true 603 }) 604 assert(t, count == 3) 605 ParseBytes([]byte(`{"bad`)).ForEach(nil) 606 ParseBytes([]byte(`{"ok":"bad`)).ForEach(nil) 607 } 608 func TestMap(t *testing.T) { 609 assert(t, len(ParseBytes([]byte(`"asdf"`)).Map()) == 0) 610 assert(t, ParseBytes([]byte(`{"asdf":"ghjk"`)).Map()["asdf"].String() == 611 "ghjk") 612 assert(t, len(Result{Type: JSON, Raw: "**invalid**"}.Map()) == 0) 613 assert(t, Result{Type: JSON, Raw: "**invalid**"}.Value() == nil) 614 assert(t, Result{Type: JSON, Raw: "{"}.Map() != nil) 615 } 616 func TestBasic1(t *testing.T) { 617 mtok := get(basicJSON, `loggy.programmers`) 618 var count int 619 mtok.ForEach(func(key, value Result) bool { 620 assert(t, key.Exists()) 621 assert(t, key.String() == fmt.Sprint(count)) 622 assert(t, key.Int() == int64(count)) 623 count++ 624 if count == 3 { 625 return false 626 } 627 if count == 1 { 628 i := 0 629 value.ForEach(func(key, value Result) bool { 630 switch i { 631 case 0: 632 if key.String() != "firstName" || 633 value.String() != "Brett" { 634 t.Fatalf("expected %v/%v got %v/%v", "firstName", 635 "Brett", key.String(), value.String()) 636 } 637 case 1: 638 if key.String() != "lastName" || 639 value.String() != "McLaughlin" { 640 t.Fatalf("expected %v/%v got %v/%v", "lastName", 641 "McLaughlin", key.String(), value.String()) 642 } 643 case 2: 644 if key.String() != "email" || value.String() != "aaaa" { 645 t.Fatalf("expected %v/%v got %v/%v", "email", "aaaa", 646 key.String(), value.String()) 647 } 648 } 649 i++ 650 return true 651 }) 652 } 653 return true 654 }) 655 if count != 3 { 656 t.Fatalf("expected %v, got %v", 3, count) 657 } 658 } 659 func TestBasic2(t *testing.T) { 660 mtok := get(basicJSON, `loggy.programmers.#[age=101].firstName`) 661 if mtok.String() != "1002.3" { 662 t.Fatalf("expected %v, got %v", "1002.3", mtok.String()) 663 } 664 mtok = get(basicJSON, 665 `loggy.programmers.#[firstName != "Brett"].firstName`) 666 if mtok.String() != "Jason" { 667 t.Fatalf("expected %v, got %v", "Jason", mtok.String()) 668 } 669 mtok = get(basicJSON, `loggy.programmers.#[firstName % "Bre*"].email`) 670 if mtok.String() != "aaaa" { 671 t.Fatalf("expected %v, got %v", "aaaa", mtok.String()) 672 } 673 mtok = get(basicJSON, `loggy.programmers.#[firstName !% "Bre*"].email`) 674 if mtok.String() != "bbbb" { 675 t.Fatalf("expected %v, got %v", "bbbb", mtok.String()) 676 } 677 mtok = get(basicJSON, `loggy.programmers.#[firstName == "Brett"].email`) 678 if mtok.String() != "aaaa" { 679 t.Fatalf("expected %v, got %v", "aaaa", mtok.String()) 680 } 681 mtok = get(basicJSON, "loggy") 682 if mtok.Type != JSON { 683 t.Fatalf("expected %v, got %v", JSON, mtok.Type) 684 } 685 if len(mtok.Map()) != 1 { 686 t.Fatalf("expected %v, got %v", 1, len(mtok.Map())) 687 } 688 programmers := mtok.Map()["programmers"] 689 if programmers.Array()[1].Map()["firstName"].Str != "Jason" { 690 t.Fatalf("expected %v, got %v", "Jason", 691 mtok.Map()["programmers"].Array()[1].Map()["firstName"].Str) 692 } 693 } 694 func TestBasic3(t *testing.T) { 695 var mtok Result 696 if Parse(basicJSON).Get("loggy.programmers").Get("1"). 697 Get("firstName").Str != "Jason" { 698 t.Fatalf("expected %v, got %v", "Jason", Parse(basicJSON). 699 Get("loggy.programmers").Get("1").Get("firstName").Str) 700 } 701 var token Result 702 if token = Parse("-102"); token.Num != -102 { 703 t.Fatalf("expected %v, got %v", -102, token.Num) 704 } 705 if token = Parse("102"); token.Num != 102 { 706 t.Fatalf("expected %v, got %v", 102, token.Num) 707 } 708 if token = Parse("102.2"); token.Num != 102.2 { 709 t.Fatalf("expected %v, got %v", 102.2, token.Num) 710 } 711 if token = Parse(`"hello"`); token.Str != "hello" { 712 t.Fatalf("expected %v, got %v", "hello", token.Str) 713 } 714 if token = Parse(`"\"he\nllo\""`); token.Str != "\"he\nllo\"" { 715 t.Fatalf("expected %v, got %v", "\"he\nllo\"", token.Str) 716 } 717 mtok = get(basicJSON, "loggy.programmers.#.firstName") 718 if len(mtok.Array()) != 4 { 719 t.Fatalf("expected 4, got %v", len(mtok.Array())) 720 } 721 for i, ex := range []string{"Brett", "Jason", "Elliotte", "1002.3"} { 722 if mtok.Array()[i].String() != ex { 723 t.Fatalf("expected '%v', got '%v'", ex, mtok.Array()[i].String()) 724 } 725 } 726 mtok = get(basicJSON, "loggy.programmers.#.asd") 727 if mtok.Type != JSON { 728 t.Fatalf("expected %v, got %v", JSON, mtok.Type) 729 } 730 if len(mtok.Array()) != 0 { 731 t.Fatalf("expected 0, got %v", len(mtok.Array())) 732 } 733 } 734 func TestBasic4(t *testing.T) { 735 if get(basicJSON, "items.3.tags.#").Num != 3 { 736 t.Fatalf("expected 3, got %v", get(basicJSON, "items.3.tags.#").Num) 737 } 738 if get(basicJSON, "items.3.points.1.#").Num != 2 { 739 t.Fatalf("expected 2, got %v", 740 get(basicJSON, "items.3.points.1.#").Num) 741 } 742 if get(basicJSON, "items.#").Num != 8 { 743 t.Fatalf("expected 6, got %v", get(basicJSON, "items.#").Num) 744 } 745 if get(basicJSON, "vals.#").Num != 4 { 746 t.Fatalf("expected 4, got %v", get(basicJSON, "vals.#").Num) 747 } 748 if !get(basicJSON, "name.last").Exists() { 749 t.Fatal("expected true, got false") 750 } 751 token := get(basicJSON, "name.here") 752 if token.String() != "B\\\"R" { 753 t.Fatal("expecting 'B\\\"R'", "got", token.String()) 754 } 755 token = get(basicJSON, "arr.#") 756 if token.String() != "6" { 757 fmt.Printf("%#v\n", token) 758 t.Fatal("expecting 6", "got", token.String()) 759 } 760 token = get(basicJSON, "arr.3.hello") 761 if token.String() != "world" { 762 t.Fatal("expecting 'world'", "got", token.String()) 763 } 764 _ = token.Value().(string) 765 token = get(basicJSON, "name.first") 766 if token.String() != "tom" { 767 t.Fatal("expecting 'tom'", "got", token.String()) 768 } 769 _ = token.Value().(string) 770 token = get(basicJSON, "name.last") 771 if token.String() != "" { 772 t.Fatal("expecting ''", "got", token.String()) 773 } 774 if token.Value() != nil { 775 t.Fatal("should be nil") 776 } 777 } 778 func TestBasic5(t *testing.T) { 779 token := get(basicJSON, "age") 780 if token.String() != "100" { 781 t.Fatal("expecting '100'", "got", token.String()) 782 } 783 _ = token.Value().(float64) 784 token = get(basicJSON, "happy") 785 if token.String() != "true" { 786 t.Fatal("expecting 'true'", "got", token.String()) 787 } 788 _ = token.Value().(bool) 789 token = get(basicJSON, "immortal") 790 if token.String() != "false" { 791 t.Fatal("expecting 'false'", "got", token.String()) 792 } 793 _ = token.Value().(bool) 794 token = get(basicJSON, "noop") 795 if token.String() != `{"what is a wren?":"a bird"}` { 796 t.Fatal("expecting '"+`{"what is a wren?":"a bird"}`+"'", "got", 797 token.String()) 798 } 799 _ = token.Value().(map[string]interface{}) 800 801 if get(basicJSON, "").Value() != nil { 802 t.Fatal("should be nil") 803 } 804 805 get(basicJSON, "vals.hello") 806 807 type msi = map[string]interface{} 808 type fi = []interface{} 809 mm := Parse(basicJSON).Value().(msi) 810 fn := mm["loggy"].(msi)["programmers"].(fi)[1].(msi)["firstName"].(string) 811 if fn != "Jason" { 812 t.Fatalf("expecting %v, got %v", "Jason", fn) 813 } 814 } 815 func TestUnicode(t *testing.T) { 816 var jsonStr = `{"key":0,"的情况下解":{"key":1,"的情况":2}}` 817 if Get(jsonStr, "的情况下解.key").Num != 1 { 818 t.Fatal("fail") 819 } 820 if Get(jsonStr, "的情况下解.的情况").Num != 2 { 821 t.Fatal("fail") 822 } 823 if Get(jsonStr, "的情况下解.的?况").Num != 2 { 824 t.Fatal("fail") 825 } 826 if Get(jsonStr, "的情况下解.的?*").Num != 2 { 827 t.Fatal("fail") 828 } 829 if Get(jsonStr, "的情况下解.*?况").Num != 2 { 830 t.Fatal("fail") 831 } 832 if Get(jsonStr, "的情?下解.*?况").Num != 2 { 833 t.Fatal("fail") 834 } 835 if Get(jsonStr, "的情下解.*?况").Num != 0 { 836 t.Fatal("fail") 837 } 838 } 839 840 func TestUnescape(t *testing.T) { 841 unescape(string([]byte{'\\', '\\', 0})) 842 unescape(string([]byte{'\\', '/', '\\', 'b', '\\', 'f'})) 843 } 844 func assert(t testing.TB, cond bool) { 845 if !cond { 846 panic("assert failed") 847 } 848 } 849 func TestLess(t *testing.T) { 850 assert(t, !Result{Type: Null}.Less(Result{Type: Null}, true)) 851 assert(t, Result{Type: Null}.Less(Result{Type: False}, true)) 852 assert(t, Result{Type: Null}.Less(Result{Type: True}, true)) 853 assert(t, Result{Type: Null}.Less(Result{Type: JSON}, true)) 854 assert(t, Result{Type: Null}.Less(Result{Type: Number}, true)) 855 assert(t, Result{Type: Null}.Less(Result{Type: String}, true)) 856 assert(t, !Result{Type: False}.Less(Result{Type: Null}, true)) 857 assert(t, Result{Type: False}.Less(Result{Type: True}, true)) 858 assert(t, Result{Type: String, Str: "abc"}.Less(Result{Type: String, 859 Str: "bcd"}, true)) 860 assert(t, Result{Type: String, Str: "ABC"}.Less(Result{Type: String, 861 Str: "abc"}, true)) 862 assert(t, !Result{Type: String, Str: "ABC"}.Less(Result{Type: String, 863 Str: "abc"}, false)) 864 assert(t, Result{Type: Number, Num: 123}.Less(Result{Type: Number, 865 Num: 456}, true)) 866 assert(t, !Result{Type: Number, Num: 456}.Less(Result{Type: Number, 867 Num: 123}, true)) 868 assert(t, !Result{Type: Number, Num: 456}.Less(Result{Type: Number, 869 Num: 456}, true)) 870 assert(t, stringLessInsensitive("abcde", "BBCDE")) 871 assert(t, stringLessInsensitive("abcde", "bBCDE")) 872 assert(t, stringLessInsensitive("Abcde", "BBCDE")) 873 assert(t, stringLessInsensitive("Abcde", "bBCDE")) 874 assert(t, !stringLessInsensitive("bbcde", "aBCDE")) 875 assert(t, !stringLessInsensitive("bbcde", "ABCDE")) 876 assert(t, !stringLessInsensitive("Bbcde", "aBCDE")) 877 assert(t, !stringLessInsensitive("Bbcde", "ABCDE")) 878 assert(t, !stringLessInsensitive("abcde", "ABCDE")) 879 assert(t, !stringLessInsensitive("Abcde", "ABCDE")) 880 assert(t, !stringLessInsensitive("abcde", "ABCDE")) 881 assert(t, !stringLessInsensitive("ABCDE", "ABCDE")) 882 assert(t, !stringLessInsensitive("abcde", "abcde")) 883 assert(t, !stringLessInsensitive("123abcde", "123Abcde")) 884 assert(t, !stringLessInsensitive("123Abcde", "123Abcde")) 885 assert(t, !stringLessInsensitive("123Abcde", "123abcde")) 886 assert(t, !stringLessInsensitive("123abcde", "123abcde")) 887 assert(t, !stringLessInsensitive("124abcde", "123abcde")) 888 assert(t, !stringLessInsensitive("124Abcde", "123Abcde")) 889 assert(t, !stringLessInsensitive("124Abcde", "123abcde")) 890 assert(t, !stringLessInsensitive("124abcde", "123abcde")) 891 assert(t, stringLessInsensitive("124abcde", "125abcde")) 892 assert(t, stringLessInsensitive("124Abcde", "125Abcde")) 893 assert(t, stringLessInsensitive("124Abcde", "125abcde")) 894 assert(t, stringLessInsensitive("124abcde", "125abcde")) 895 } 896 897 func TestIssue6(t *testing.T) { 898 data := `{ 899 "code": 0, 900 "msg": "", 901 "data": { 902 "sz002024": { 903 "qfqday": [ 904 [ 905 "2014-01-02", 906 "8.93", 907 "9.03", 908 "9.17", 909 "8.88", 910 "621143.00" 911 ], 912 [ 913 "2014-01-03", 914 "9.03", 915 "9.30", 916 "9.47", 917 "8.98", 918 "1624438.00" 919 ] 920 ] 921 } 922 } 923 }` 924 925 var num []string 926 for _, v := range Get(data, "data.sz002024.qfqday.0").Array() { 927 num = append(num, v.String()) 928 } 929 if fmt.Sprintf("%v", num) != "[2014-01-02 8.93 9.03 9.17 8.88 621143.00]" { 930 t.Fatalf("invalid result") 931 } 932 } 933 934 var exampleJSON = `{ 935 "widget": { 936 "debug": "on", 937 "window": { 938 "title": "Sample Konfabulator Widget", 939 "name": "main_window", 940 "width": 500, 941 "height": 500 942 }, 943 "image": { 944 "src": "Images/Sun.png", 945 "hOffset": 250, 946 "vOffset": 250, 947 "alignment": "center" 948 }, 949 "text": { 950 "data": "Click Here", 951 "size": 36, 952 "style": "bold", 953 "vOffset": 100, 954 "alignment": "center", 955 "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" 956 } 957 } 958 }` 959 960 func TestUnmarshalMap(t *testing.T) { 961 var m1 = Parse(exampleJSON).Value().(map[string]interface{}) 962 var m2 map[string]interface{} 963 if err := json.Unmarshal([]byte(exampleJSON), &m2); err != nil { 964 t.Fatal(err) 965 } 966 b1, err := json.Marshal(m1) 967 if err != nil { 968 t.Fatal(err) 969 } 970 b2, err := json.Marshal(m2) 971 if err != nil { 972 t.Fatal(err) 973 } 974 if !bytes.Equal(b1, b2) { 975 t.Fatal("b1 != b2") 976 } 977 } 978 979 func TestSingleArrayValue(t *testing.T) { 980 var jsonStr = `{"key": "value","key2":[1,2,3,4,"A"]}` 981 var result = Get(jsonStr, "key") 982 var array = result.Array() 983 if len(array) != 1 { 984 t.Fatal("array is empty") 985 } 986 if array[0].String() != "value" { 987 t.Fatalf("got %s, should be %s", array[0].String(), "value") 988 } 989 990 array = Get(jsonStr, "key2.#").Array() 991 if len(array) != 1 { 992 t.Fatalf("got '%v', expected '%v'", len(array), 1) 993 } 994 995 array = Get(jsonStr, "key3").Array() 996 if len(array) != 0 { 997 t.Fatalf("got '%v', expected '%v'", len(array), 0) 998 } 999 1000 } 1001 1002 var manyJSON = ` { 1003 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 1004 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 1005 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 1006 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 1007 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 1008 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{ 1009 "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"hello":"world" 1010 }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} 1011 "position":{"type":"Point","coordinates":[-115.24,33.09]}, 1012 "loves":["world peace"], 1013 "name":{"last":"Anderson","first":"Nancy"}, 1014 "age":31 1015 "":{"a":"emptya","b":"emptyb"}, 1016 "name.last":"Yellow", 1017 "name.first":"Cat", 1018 }` 1019 1020 var testWatchForFallback bool 1021 1022 func TestManyBasic(t *testing.T) { 1023 testWatchForFallback = true 1024 defer func() { 1025 testWatchForFallback = false 1026 }() 1027 testMany := func(shouldFallback bool, expect string, paths ...string) { 1028 results := GetManyBytes( 1029 []byte(manyJSON), 1030 paths..., 1031 ) 1032 if len(results) != len(paths) { 1033 t.Fatalf("expected %v, got %v", len(paths), len(results)) 1034 } 1035 if fmt.Sprintf("%v", results) != expect { 1036 fmt.Printf("%v\n", paths) 1037 t.Fatalf("expected %v, got %v", expect, results) 1038 } 1039 } 1040 testMany(false, "[Point]", "position.type") 1041 testMany(false, `[emptya ["world peace"] 31]`, ".a", "loves", "age") 1042 testMany(false, `[["world peace"]]`, "loves") 1043 testMany(false, `[{"last":"Anderson","first":"Nancy"} Nancy]`, "name", 1044 "name.first") 1045 testMany(true, `[]`, strings.Repeat("a.", 40)+"hello") 1046 res := Get(manyJSON, strings.Repeat("a.", 48)+"a") 1047 testMany(true, `[`+res.String()+`]`, strings.Repeat("a.", 48)+"a") 1048 // these should fallback 1049 testMany(true, `[Cat Nancy]`, "name\\.first", "name.first") 1050 testMany(true, `[world]`, strings.Repeat("a.", 70)+"hello") 1051 } 1052 func testMany(t *testing.T, json string, paths, expected []string) { 1053 testManyAny(t, json, paths, expected, true) 1054 testManyAny(t, json, paths, expected, false) 1055 } 1056 func testManyAny(t *testing.T, json string, paths, expected []string, 1057 bytes bool) { 1058 var result []Result 1059 for i := 0; i < 2; i++ { 1060 var which string 1061 if i == 0 { 1062 which = "Get" 1063 result = nil 1064 for j := 0; j < len(expected); j++ { 1065 if bytes { 1066 result = append(result, GetBytes([]byte(json), paths[j])) 1067 } else { 1068 result = append(result, Get(json, paths[j])) 1069 } 1070 } 1071 } else if i == 1 { 1072 which = "GetMany" 1073 if bytes { 1074 result = GetManyBytes([]byte(json), paths...) 1075 } else { 1076 result = GetMany(json, paths...) 1077 } 1078 } 1079 for j := 0; j < len(expected); j++ { 1080 if result[j].String() != expected[j] { 1081 t.Fatalf("Using key '%s' for '%s'\nexpected '%v', got '%v'", 1082 paths[j], which, expected[j], result[j].String()) 1083 } 1084 } 1085 } 1086 } 1087 func TestIssue20(t *testing.T) { 1088 jsonStr := `{ "name": "FirstName", "name1": "FirstName1", ` + 1089 `"address": "address1", "addressDetails": "address2", }` 1090 paths := []string{"name", "name1", "address", "addressDetails"} 1091 expected := []string{"FirstName", "FirstName1", "address1", "address2"} 1092 t.Run("SingleMany", func(t *testing.T) { 1093 testMany(t, jsonStr, paths, 1094 expected) 1095 }) 1096 } 1097 1098 func TestIssue21(t *testing.T) { 1099 jsonStr := `{ "Level1Field1":3, 1100 "Level1Field4":4, 1101 "Level1Field2":{ "Level2Field1":[ "value1", "value2" ], 1102 "Level2Field2":{ "Level3Field1":[ { "key1":"value1" } ] } } }` 1103 paths := []string{"Level1Field1", "Level1Field2.Level2Field1", 1104 "Level1Field2.Level2Field2.Level3Field1", "Level1Field4"} 1105 expected := []string{"3", `[ "value1", "value2" ]`, 1106 `[ { "key1":"value1" } ]`, "4"} 1107 t.Run("SingleMany", func(t *testing.T) { 1108 testMany(t, jsonStr, paths, 1109 expected) 1110 }) 1111 } 1112 1113 func TestRandomMany(t *testing.T) { 1114 var lstr string 1115 defer func() { 1116 if v := recover(); v != nil { 1117 println("'" + hex.EncodeToString([]byte(lstr)) + "'") 1118 println("'" + lstr + "'") 1119 panic(v) 1120 } 1121 }() 1122 rand.Seed(time.Now().UnixNano()) 1123 b := make([]byte, 512) 1124 for i := 0; i < 50000; i++ { 1125 n, err := rand.Read(b[:rand.Int()%len(b)]) 1126 if err != nil { 1127 t.Fatal(err) 1128 } 1129 lstr = string(b[:n]) 1130 paths := make([]string, rand.Int()%64) 1131 for i := range paths { 1132 var b []byte 1133 n := rand.Int() % 5 1134 for j := 0; j < n; j++ { 1135 if j > 0 { 1136 b = append(b, '.') 1137 } 1138 nn := rand.Int() % 10 1139 for k := 0; k < nn; k++ { 1140 b = append(b, 'a'+byte(rand.Int()%26)) 1141 } 1142 } 1143 paths[i] = string(b) 1144 } 1145 GetMany(lstr, paths...) 1146 } 1147 } 1148 1149 var complicatedJSON = ` 1150 { 1151 "tagged": "OK", 1152 "Tagged": "KO", 1153 "NotTagged": true, 1154 "unsettable": 101, 1155 "Nested": { 1156 "Yellow": "Green", 1157 "yellow": "yellow" 1158 }, 1159 "nestedTagged": { 1160 "Green": "Green", 1161 "Map": { 1162 "this": "that", 1163 "and": "the other thing" 1164 }, 1165 "Ints": { 1166 "Uint": 99, 1167 "Uint16": 16, 1168 "Uint32": 32, 1169 "Uint64": 65 1170 }, 1171 "Uints": { 1172 "int": -99, 1173 "Int": -98, 1174 "Int16": -16, 1175 "Int32": -32, 1176 "int64": -64, 1177 "Int64": -65 1178 }, 1179 "Uints": { 1180 "Float32": 32.32, 1181 "Float64": 64.64 1182 }, 1183 "Byte": 254, 1184 "Bool": true 1185 }, 1186 "LeftOut": "you shouldn't be here", 1187 "SelfPtr": {"tagged":"OK","nestedTagged":{"Ints":{"Uint32":32}}}, 1188 "SelfSlice": [{"tagged":"OK","nestedTagged":{"Ints":{"Uint32":32}}}], 1189 "SelfSlicePtr": [{"tagged":"OK","nestedTagged":{"Ints":{"Uint32":32}}}], 1190 "SelfPtrSlice": [{"tagged":"OK","nestedTagged":{"Ints":{"Uint32":32}}}], 1191 "interface": "Tile38 Rocks!", 1192 "Interface": "Please Download", 1193 "Array": [0,2,3,4,5], 1194 "time": "2017-05-07T13:24:43-07:00", 1195 "Binary": "R0lGODlhPQBEAPeo", 1196 "NonBinary": [9,3,100,115] 1197 } 1198 ` 1199 1200 func testvalid(t *testing.T, json string, expect bool) { 1201 t.Helper() 1202 _, ok := validpayload([]byte(json), 0) 1203 if ok != expect { 1204 t.Fatal("mismatch") 1205 } 1206 } 1207 1208 func TestValidBasic(t *testing.T) { 1209 testvalid(t, "0", true) 1210 testvalid(t, "00", false) 1211 testvalid(t, "-00", false) 1212 testvalid(t, "-.", false) 1213 testvalid(t, "-.123", false) 1214 testvalid(t, "0.0", true) 1215 testvalid(t, "10.0", true) 1216 testvalid(t, "10e1", true) 1217 testvalid(t, "10EE", false) 1218 testvalid(t, "10E-", false) 1219 testvalid(t, "10E+", false) 1220 testvalid(t, "10E123", true) 1221 testvalid(t, "10E-123", true) 1222 testvalid(t, "10E-0123", true) 1223 testvalid(t, "", false) 1224 testvalid(t, " ", false) 1225 testvalid(t, "{}", true) 1226 testvalid(t, "{", false) 1227 testvalid(t, "-", false) 1228 testvalid(t, "-1", true) 1229 testvalid(t, "-1.", false) 1230 testvalid(t, "-1.0", true) 1231 testvalid(t, " -1.0", true) 1232 testvalid(t, " -1.0 ", true) 1233 testvalid(t, "-1.0 ", true) 1234 testvalid(t, "-1.0 i", false) 1235 testvalid(t, "-1.0 i", false) 1236 testvalid(t, "true", true) 1237 testvalid(t, " true", true) 1238 testvalid(t, " true ", true) 1239 testvalid(t, " True ", false) 1240 testvalid(t, " tru", false) 1241 testvalid(t, "false", true) 1242 testvalid(t, " false", true) 1243 testvalid(t, " false ", true) 1244 testvalid(t, " False ", false) 1245 testvalid(t, " fals", false) 1246 testvalid(t, "null", true) 1247 testvalid(t, " null", true) 1248 testvalid(t, " null ", true) 1249 testvalid(t, " Null ", false) 1250 testvalid(t, " nul", false) 1251 testvalid(t, " []", true) 1252 testvalid(t, " [true]", true) 1253 testvalid(t, " [ true, null ]", true) 1254 testvalid(t, " [ true,]", false) 1255 testvalid(t, `{"hello":"world"}`, true) 1256 testvalid(t, `{ "hello": "world" }`, true) 1257 testvalid(t, `{ "hello": "world", }`, false) 1258 testvalid(t, `{"a":"b",}`, false) 1259 testvalid(t, `{"a":"b","a"}`, false) 1260 testvalid(t, `{"a":"b","a":}`, false) 1261 testvalid(t, `{"a":"b","a":1}`, true) 1262 testvalid(t, `{"a":"b",2"1":2}`, false) 1263 testvalid(t, `{"a":"b","a": 1, "c":{"hi":"there"} }`, true) 1264 testvalid(t, `{"a":"b","a": 1, "c":{"hi":"there", "easy":["going",`+ 1265 `{"mixed":"bag"}]} }`, true) 1266 testvalid(t, `""`, true) 1267 testvalid(t, `"`, false) 1268 testvalid(t, `"\n"`, true) 1269 testvalid(t, `"\"`, false) 1270 testvalid(t, `"\\"`, true) 1271 testvalid(t, `"a\\b"`, true) 1272 testvalid(t, `"a\\b\\\"a"`, true) 1273 testvalid(t, `"a\\b\\\uFFAAa"`, true) 1274 testvalid(t, `"a\\b\\\uFFAZa"`, false) 1275 testvalid(t, `"a\\b\\\uFFA"`, false) 1276 testvalid(t, string(complicatedJSON), true) 1277 testvalid(t, string(exampleJSON), true) 1278 testvalid(t, "[-]", false) 1279 testvalid(t, "[-.123]", false) 1280 } 1281 1282 var jsonchars = []string{"{", "[", ",", ":", "}", "]", "1", "0", "true", 1283 "false", "null", `""`, `"\""`, `"a"`} 1284 1285 func makeRandomJSONChars(b []byte) { 1286 var bb []byte 1287 for len(bb) < len(b) { 1288 bb = append(bb, jsonchars[rand.Int()%len(jsonchars)]...) 1289 } 1290 copy(b, bb[:len(b)]) 1291 } 1292 1293 func TestValidRandom(t *testing.T) { 1294 rand.Seed(time.Now().UnixNano()) 1295 b := make([]byte, 100000) 1296 start := time.Now() 1297 for time.Since(start) < time.Second*3 { 1298 n := rand.Int() % len(b) 1299 rand.Read(b[:n]) 1300 validpayload(b[:n], 0) 1301 } 1302 1303 start = time.Now() 1304 for time.Since(start) < time.Second*3 { 1305 n := rand.Int() % len(b) 1306 makeRandomJSONChars(b[:n]) 1307 validpayload(b[:n], 0) 1308 } 1309 } 1310 1311 func TestGetMany47(t *testing.T) { 1312 jsonStr := `{"bar": {"id": 99, "mybar": "my mybar" }, "foo": ` + 1313 `{"myfoo": [605]}}` 1314 paths := []string{"foo.myfoo", "bar.id", "bar.mybar", "bar.mybarx"} 1315 expected := []string{"[605]", "99", "my mybar", ""} 1316 results := GetMany(jsonStr, paths...) 1317 if len(expected) != len(results) { 1318 t.Fatalf("expected %v, got %v", len(expected), len(results)) 1319 } 1320 for i, path := range paths { 1321 if results[i].String() != expected[i] { 1322 t.Fatalf("expected '%v', got '%v' for path '%v'", expected[i], 1323 results[i].String(), path) 1324 } 1325 } 1326 } 1327 1328 func TestGetMany48(t *testing.T) { 1329 jsonStr := `{"bar": {"id": 99, "xyz": "my xyz"}, "foo": {"myfoo": [605]}}` 1330 paths := []string{"foo.myfoo", "bar.id", "bar.xyz", "bar.abc"} 1331 expected := []string{"[605]", "99", "my xyz", ""} 1332 results := GetMany(jsonStr, paths...) 1333 if len(expected) != len(results) { 1334 t.Fatalf("expected %v, got %v", len(expected), len(results)) 1335 } 1336 for i, path := range paths { 1337 if results[i].String() != expected[i] { 1338 t.Fatalf("expected '%v', got '%v' for path '%v'", expected[i], 1339 results[i].String(), path) 1340 } 1341 } 1342 } 1343 1344 func TestResultRawForLiteral(t *testing.T) { 1345 for _, lit := range []string{"null", "true", "false"} { 1346 result := Parse(lit) 1347 if result.Raw != lit { 1348 t.Fatalf("expected '%v', got '%v'", lit, result.Raw) 1349 } 1350 } 1351 } 1352 1353 func TestNullArray(t *testing.T) { 1354 n := len(Get(`{"data":null}`, "data").Array()) 1355 if n != 0 { 1356 t.Fatalf("expected '%v', got '%v'", 0, n) 1357 } 1358 n = len(Get(`{}`, "data").Array()) 1359 if n != 0 { 1360 t.Fatalf("expected '%v', got '%v'", 0, n) 1361 } 1362 n = len(Get(`{"data":[]}`, "data").Array()) 1363 if n != 0 { 1364 t.Fatalf("expected '%v', got '%v'", 0, n) 1365 } 1366 n = len(Get(`{"data":[null]}`, "data").Array()) 1367 if n != 1 { 1368 t.Fatalf("expected '%v', got '%v'", 1, n) 1369 } 1370 } 1371 1372 func TestIssue54(t *testing.T) { 1373 var r []Result 1374 jsonStr := `{"MarketName":null,"Nounce":6115}` 1375 r = GetMany(jsonStr, "Nounce", "Buys", "Sells", "Fills") 1376 if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" { 1377 t.Fatalf("expected '%v', got '%v'", "[6115]", 1378 strings.Replace(fmt.Sprintf("%v", r), " ", "", -1)) 1379 } 1380 r = GetMany(jsonStr, "Nounce", "Buys", "Sells") 1381 if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" { 1382 t.Fatalf("expected '%v', got '%v'", "[6115]", 1383 strings.Replace(fmt.Sprintf("%v", r), " ", "", -1)) 1384 } 1385 r = GetMany(jsonStr, "Nounce") 1386 if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" { 1387 t.Fatalf("expected '%v', got '%v'", "[6115]", 1388 strings.Replace(fmt.Sprintf("%v", r), " ", "", -1)) 1389 } 1390 } 1391 1392 func TestIssue55(t *testing.T) { 1393 jsonStr := `{"one": {"two": 2, "three": 3}, "four": 4, "five": 5}` 1394 results := GetMany(jsonStr, "four", "five", "one.two", "one.six") 1395 expected := []string{"4", "5", "2", ""} 1396 for i, r := range results { 1397 if r.String() != expected[i] { 1398 t.Fatalf("expected %v, got %v", expected[i], r.String()) 1399 } 1400 } 1401 } 1402 func TestIssue58(t *testing.T) { 1403 jsonStr := `{"data":[{"uid": 1},{"uid": 2}]}` 1404 res := Get(jsonStr, `data.#[uid!=1]`).Raw 1405 if res != `{"uid": 2}` { 1406 t.Fatalf("expected '%v', got '%v'", `{"uid": 1}`, res) 1407 } 1408 } 1409 1410 func TestObjectGrouping(t *testing.T) { 1411 jsonStr := ` 1412 [ 1413 true, 1414 {"name":"tom"}, 1415 false, 1416 {"name":"janet"}, 1417 null 1418 ] 1419 ` 1420 res := Get(jsonStr, "#.name") 1421 if res.String() != `["tom","janet"]` { 1422 t.Fatalf("expected '%v', got '%v'", `["tom","janet"]`, res.String()) 1423 } 1424 } 1425 1426 func TestJSONLines(t *testing.T) { 1427 jsonStr := ` 1428 true 1429 false 1430 {"name":"tom"} 1431 [1,2,3,4,5] 1432 {"name":"janet"} 1433 null 1434 12930.1203 1435 ` 1436 paths := []string{"..#", "..0", "..2.name", "..#.name", "..6", "..7"} 1437 ress := []string{"7", "true", "tom", `["tom","janet"]`, "12930.1203", ""} 1438 for i, path := range paths { 1439 res := Get(jsonStr, path) 1440 if res.String() != ress[i] { 1441 t.Fatalf("expected '%v', got '%v'", ress[i], res.String()) 1442 } 1443 } 1444 1445 jsonStr = ` 1446 {"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]} 1447 {"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]} 1448 {"name": "May", "wins": []} 1449 {"name": "Deloise", "wins": [["three of a kind", "5♣"]]} 1450 ` 1451 1452 var i int 1453 lines := strings.Split(strings.TrimSpace(jsonStr), "\n") 1454 ForEachLine(jsonStr, func(line Result) bool { 1455 if line.Raw != lines[i] { 1456 t.Fatalf("expected '%v', got '%v'", lines[i], line.Raw) 1457 } 1458 i++ 1459 return true 1460 }) 1461 if i != 4 { 1462 t.Fatalf("expected '%v', got '%v'", 4, i) 1463 } 1464 1465 } 1466 1467 func TestNumUint64String(t *testing.T) { 1468 var i int64 = 9007199254740993 //2^53 + 1 1469 j := fmt.Sprintf(`{"data": [ %d, "hello" ] }`, i) 1470 res := Get(j, "data.0") 1471 if res.String() != "9007199254740993" { 1472 t.Fatalf("expected '%v', got '%v'", "9007199254740993", res.String()) 1473 } 1474 } 1475 1476 func TestNumInt64String(t *testing.T) { 1477 var i int64 = -9007199254740993 1478 j := fmt.Sprintf(`{"data":[ "hello", %d ]}`, i) 1479 res := Get(j, "data.1") 1480 if res.String() != "-9007199254740993" { 1481 t.Fatalf("expected '%v', got '%v'", "-9007199254740993", res.String()) 1482 } 1483 } 1484 1485 func TestNumBigString(t *testing.T) { 1486 i := "900719925474099301239109123101" // very big 1487 j := fmt.Sprintf(`{"data":[ "hello", "%s" ]}`, i) 1488 res := Get(j, "data.1") 1489 if res.String() != "900719925474099301239109123101" { 1490 t.Fatalf("expected '%v', got '%v'", "900719925474099301239109123101", 1491 res.String()) 1492 } 1493 } 1494 1495 func TestNumFloatString(t *testing.T) { 1496 var i int64 = -9007199254740993 1497 j := fmt.Sprintf(`{"data":[ "hello", %d ]}`, i) //No quotes around value!! 1498 res := Get(j, "data.1") 1499 if res.String() != "-9007199254740993" { 1500 t.Fatalf("expected '%v', got '%v'", "-9007199254740993", res.String()) 1501 } 1502 } 1503 1504 func TestDuplicateKeys(t *testing.T) { 1505 // this is vaild jsonStr according to the JSON spec 1506 var jsonStr = `{"name": "Alex","name": "Peter"}` 1507 if Parse(jsonStr).Get("name").String() != 1508 Parse(jsonStr).Map()["name"].String() { 1509 t.Fatalf("expected '%v', got '%v'", 1510 Parse(jsonStr).Get("name").String(), 1511 Parse(jsonStr).Map()["name"].String(), 1512 ) 1513 } 1514 if !Valid(jsonStr) { 1515 t.Fatal("should be valid") 1516 } 1517 } 1518 1519 func BenchmarkValid(b *testing.B) { 1520 for i := 0; i < b.N; i++ { 1521 Valid(complicatedJSON) 1522 } 1523 } 1524 1525 func BenchmarkValidBytes(b *testing.B) { 1526 complicatedJSON := []byte(complicatedJSON) 1527 for i := 0; i < b.N; i++ { 1528 ValidBytes(complicatedJSON) 1529 } 1530 } 1531 1532 func BenchmarkGoStdlibValidBytes(b *testing.B) { 1533 complicatedJSON := []byte(complicatedJSON) 1534 for i := 0; i < b.N; i++ { 1535 json.Valid(complicatedJSON) 1536 } 1537 } 1538 1539 func TestChaining(t *testing.T) { 1540 jsonStr := `{ 1541 "info": { 1542 "friends": [ 1543 {"first": "Dale", "last": "Murphy", "age": 44}, 1544 {"first": "Roger", "last": "Craig", "age": 68}, 1545 {"first": "Jane", "last": "Murphy", "age": 47} 1546 ] 1547 } 1548 }` 1549 res := Get(jsonStr, "info.friends|0|first").String() 1550 if res != "Dale" { 1551 t.Fatalf("expected '%v', got '%v'", "Dale", res) 1552 } 1553 res = Get(jsonStr, "info.friends|@reverse|0|age").String() 1554 if res != "47" { 1555 t.Fatalf("expected '%v', got '%v'", "47", res) 1556 } 1557 res = Get(jsonStr, "@ugly|i\\nfo|friends.0.first").String() 1558 if res != "Dale" { 1559 t.Fatalf("expected '%v', got '%v'", "Dale", res) 1560 } 1561 } 1562 1563 func TestSplitPipe(t *testing.T) { 1564 split := func(t *testing.T, path, el, er string, eo bool) { 1565 t.Helper() 1566 left, right, ok := splitPossiblePipe(path) 1567 // fmt.Printf("%-40s [%v] [%v] [%v]\n", path, left, right, ok) 1568 if left != el || right != er || ok != eo { 1569 t.Fatalf("expected '%v/%v/%v', got '%v/%v/%v", 1570 el, er, eo, left, right, ok) 1571 } 1572 } 1573 1574 split(t, "hello", "", "", false) 1575 split(t, "hello.world", "", "", false) 1576 split(t, "hello|world", "hello", "world", true) 1577 split(t, "hello\\|world", "", "", false) 1578 split(t, "hello.#", "", "", false) 1579 split(t, `hello.#[a|1="asdf\"|1324"]#\|that`, "", "", false) 1580 split(t, `hello.#[a|1="asdf\"|1324"]#|that.more|yikes`, 1581 `hello.#[a|1="asdf\"|1324"]#`, "that.more|yikes", true) 1582 split(t, `a.#[]#\|b`, "", "", false) 1583 1584 } 1585 1586 func TestArrayEx(t *testing.T) { 1587 jsonStr := ` 1588 [ 1589 { 1590 "c":[ 1591 {"a":10.11} 1592 ] 1593 }, { 1594 "c":[ 1595 {"a":11.11} 1596 ] 1597 } 1598 ]` 1599 res := Get(jsonStr, "@ugly|#.c.#[a=10.11]").String() 1600 if res != `[{"a":10.11}]` { 1601 t.Fatalf("expected '%v', got '%v'", `[{"a":10.11}]`, res) 1602 } 1603 res = Get(jsonStr, "@ugly|#.c.#").String() 1604 if res != `[1,1]` { 1605 t.Fatalf("expected '%v', got '%v'", `[1,1]`, res) 1606 } 1607 res = Get(jsonStr, "@reverse|0|c|0|a").String() 1608 if res != "11.11" { 1609 t.Fatalf("expected '%v', got '%v'", "11.11", res) 1610 } 1611 res = Get(jsonStr, "#.c|#").String() 1612 if res != "2" { 1613 t.Fatalf("expected '%v', got '%v'", "2", res) 1614 } 1615 } 1616 1617 func TestPipeDotMixing(t *testing.T) { 1618 jsonStr := `{ 1619 "info": { 1620 "friends": [ 1621 {"first": "Dale", "last": "Murphy", "age": 44}, 1622 {"first": "Roger", "last": "Craig", "age": 68}, 1623 {"first": "Jane", "last": "Murphy", "age": 47} 1624 ] 1625 } 1626 }` 1627 var res string 1628 res = Get(jsonStr, `info.friends.#[first="Dale"].last`).String() 1629 if res != "Murphy" { 1630 t.Fatalf("expected '%v', got '%v'", "Murphy", res) 1631 } 1632 res = Get(jsonStr, `info|friends.#[first="Dale"].last`).String() 1633 if res != "Murphy" { 1634 t.Fatalf("expected '%v', got '%v'", "Murphy", res) 1635 } 1636 res = Get(jsonStr, `info|friends.#[first="Dale"]|last`).String() 1637 if res != "Murphy" { 1638 t.Fatalf("expected '%v', got '%v'", "Murphy", res) 1639 } 1640 res = Get(jsonStr, `info|friends|#[first="Dale"]|last`).String() 1641 if res != "Murphy" { 1642 t.Fatalf("expected '%v', got '%v'", "Murphy", res) 1643 } 1644 res = Get(jsonStr, `@ugly|info|friends|#[first="Dale"]|last`).String() 1645 if res != "Murphy" { 1646 t.Fatalf("expected '%v', got '%v'", "Murphy", res) 1647 } 1648 res = Get(jsonStr, `@ugly|info.@ugly|friends|#[first="Dale"]|last`).String() 1649 if res != "Murphy" { 1650 t.Fatalf("expected '%v', got '%v'", "Murphy", res) 1651 } 1652 res = Get(jsonStr, `@ugly.info|@ugly.friends|#[first="Dale"]|last`).String() 1653 if res != "Murphy" { 1654 t.Fatalf("expected '%v', got '%v'", "Murphy", res) 1655 } 1656 } 1657 1658 func TestDeepSelectors(t *testing.T) { 1659 jsonStr := `{ 1660 "info": { 1661 "friends": [ 1662 { 1663 "first": "Dale", "last": "Murphy", 1664 "extra": [10,20,30], 1665 "details": { 1666 "city": "Tempe", 1667 "state": "Arizona" 1668 } 1669 }, 1670 { 1671 "first": "Roger", "last": "Craig", 1672 "extra": [40,50,60], 1673 "details": { 1674 "city": "Phoenix", 1675 "state": "Arizona" 1676 } 1677 } 1678 ] 1679 } 1680 }` 1681 var res string 1682 res = Get(jsonStr, `info.friends.#[first="Dale"].extra.0`).String() 1683 if res != "10" { 1684 t.Fatalf("expected '%v', got '%v'", "10", res) 1685 } 1686 res = Get(jsonStr, `info.friends.#[first="Dale"].extra|0`).String() 1687 if res != "10" { 1688 t.Fatalf("expected '%v', got '%v'", "10", res) 1689 } 1690 res = Get(jsonStr, `info.friends.#[first="Dale"]|extra|0`).String() 1691 if res != "10" { 1692 t.Fatalf("expected '%v', got '%v'", "10", res) 1693 } 1694 res = Get(jsonStr, `info.friends.#[details.city="Tempe"].last`).String() 1695 if res != "Murphy" { 1696 t.Fatalf("expected '%v', got '%v'", "Murphy", res) 1697 } 1698 res = Get(jsonStr, `info.friends.#[details.city="Phoenix"].last`).String() 1699 if res != "Craig" { 1700 t.Fatalf("expected '%v', got '%v'", "Craig", res) 1701 } 1702 res = Get(jsonStr, `info.friends.#[details.state="Arizona"].last`).String() 1703 if res != "Murphy" { 1704 t.Fatalf("expected '%v', got '%v'", "Murphy", res) 1705 } 1706 } 1707 1708 func TestMultiArrayEx(t *testing.T) { 1709 jsonStr := `{ 1710 "info": { 1711 "friends": [ 1712 { 1713 "first": "Dale", "last": "Murphy", "kind": "Person", 1714 "cust1": true, 1715 "extra": [10,20,30], 1716 "details": { 1717 "city": "Tempe", 1718 "state": "Arizona" 1719 } 1720 }, 1721 { 1722 "first": "Roger", "last": "Craig", "kind": "Person", 1723 "cust2": false, 1724 "extra": [40,50,60], 1725 "details": { 1726 "city": "Phoenix", 1727 "state": "Arizona" 1728 } 1729 } 1730 ] 1731 } 1732 }` 1733 1734 var res string 1735 1736 res = Get(jsonStr, `info.friends.#[kind="Person"]#.kind|0`).String() 1737 if res != "Person" { 1738 t.Fatalf("expected '%v', got '%v'", "Person", res) 1739 } 1740 res = Get(jsonStr, `info.friends.#.kind|0`).String() 1741 if res != "Person" { 1742 t.Fatalf("expected '%v', got '%v'", "Person", res) 1743 } 1744 1745 res = Get(jsonStr, `info.friends.#[kind="Person"]#.kind`).String() 1746 if res != `["Person","Person"]` { 1747 t.Fatalf("expected '%v', got '%v'", `["Person","Person"]`, res) 1748 } 1749 res = Get(jsonStr, `info.friends.#.kind`).String() 1750 if res != `["Person","Person"]` { 1751 t.Fatalf("expected '%v', got '%v'", `["Person","Person"]`, res) 1752 } 1753 1754 res = Get(jsonStr, `info.friends.#[kind="Person"]#|kind`).String() 1755 if res != `` { 1756 t.Fatalf("expected '%v', got '%v'", ``, res) 1757 } 1758 res = Get(jsonStr, `info.friends.#|kind`).String() 1759 if res != `` { 1760 t.Fatalf("expected '%v', got '%v'", ``, res) 1761 } 1762 1763 res = Get(jsonStr, `i*.f*.#[kind="Other"]#`).String() 1764 if res != `[]` { 1765 t.Fatalf("expected '%v', got '%v'", `[]`, res) 1766 } 1767 } 1768 1769 func TestQueries(t *testing.T) { 1770 jsonStr := `{ 1771 "info": { 1772 "friends": [ 1773 { 1774 "first": "Dale", "last": "Murphy", "kind": "Person", 1775 "cust1": true, 1776 "extra": [10,20,30], 1777 "details": { 1778 "city": "Tempe", 1779 "state": "Arizona" 1780 } 1781 }, 1782 { 1783 "first": "Roger", "last": "Craig", "kind": "Person", 1784 "cust2": false, 1785 "extra": [40,50,60], 1786 "details": { 1787 "city": "Phoenix", 1788 "state": "Arizona" 1789 } 1790 } 1791 ] 1792 } 1793 }` 1794 1795 // numbers 1796 assert(t, Get(jsonStr, "i*.f*.#[extra.0<11].first").Exists()) 1797 assert(t, Get(jsonStr, "i*.f*.#[extra.0<=11].first").Exists()) 1798 assert(t, !Get(jsonStr, "i*.f*.#[extra.0<10].first").Exists()) 1799 assert(t, Get(jsonStr, "i*.f*.#[extra.0<=10].first").Exists()) 1800 assert(t, Get(jsonStr, "i*.f*.#[extra.0=10].first").Exists()) 1801 assert(t, !Get(jsonStr, "i*.f*.#[extra.0=11].first").Exists()) 1802 assert(t, Get(jsonStr, "i*.f*.#[extra.0!=10].first").String() == "Roger") 1803 assert(t, Get(jsonStr, "i*.f*.#[extra.0>10].first").String() == "Roger") 1804 assert(t, Get(jsonStr, "i*.f*.#[extra.0>=10].first").String() == "Dale") 1805 1806 // strings 1807 assert(t, Get(jsonStr, `i*.f*.#[extra.0<"11"].first`).Exists()) 1808 assert(t, Get(jsonStr, `i*.f*.#[first>"Dale"].last`).String() == "Craig") 1809 assert(t, Get(jsonStr, `i*.f*.#[first>="Dale"].last`).String() == "Murphy") 1810 assert(t, Get(jsonStr, `i*.f*.#[first="Dale"].last`).String() == "Murphy") 1811 assert(t, Get(jsonStr, `i*.f*.#[first!="Dale"].last`).String() == "Craig") 1812 assert(t, !Get(jsonStr, `i*.f*.#[first<"Dale"].last`).Exists()) 1813 assert(t, Get(jsonStr, `i*.f*.#[first<="Dale"].last`).Exists()) 1814 assert(t, Get(jsonStr, `i*.f*.#[first%"Da*"].last`).Exists()) 1815 assert(t, Get(jsonStr, `i*.f*.#[first%"Dale"].last`).Exists()) 1816 assert(t, Get(jsonStr, `i*.f*.#[first%"*a*"]#|#`).String() == "1") 1817 assert(t, Get(jsonStr, `i*.f*.#[first%"*e*"]#|#`).String() == "2") 1818 assert(t, Get(jsonStr, `i*.f*.#[first!%"*e*"]#|#`).String() == "0") 1819 1820 // trues 1821 assert(t, Get(jsonStr, `i*.f*.#[cust1=true].first`).String() == "Dale") 1822 assert(t, Get(jsonStr, `i*.f*.#[cust2=false].first`).String() == "Roger") 1823 assert(t, Get(jsonStr, `i*.f*.#[cust1!=false].first`).String() == "Dale") 1824 assert(t, Get(jsonStr, `i*.f*.#[cust2!=true].first`).String() == "Roger") 1825 assert(t, !Get(jsonStr, `i*.f*.#[cust1>true].first`).Exists()) 1826 assert(t, Get(jsonStr, `i*.f*.#[cust1>=true].first`).Exists()) 1827 assert(t, !Get(jsonStr, `i*.f*.#[cust2<false].first`).Exists()) 1828 assert(t, Get(jsonStr, `i*.f*.#[cust2<=false].first`).Exists()) 1829 1830 } 1831 1832 func TestQueryArrayValues(t *testing.T) { 1833 jsonStr := `{ 1834 "artists": [ 1835 ["Bob Dylan"], 1836 "John Lennon", 1837 "Mick Jagger", 1838 "Elton John", 1839 "Michael Jackson", 1840 "John Smith", 1841 true, 1842 123, 1843 456, 1844 false, 1845 null 1846 ] 1847 }` 1848 assert(t, Get(jsonStr, `a*.#[0="Bob Dylan"]#|#`).String() == "1") 1849 assert(t, Get(jsonStr, `a*.#[0="Bob Dylan 2"]#|#`).String() == "0") 1850 assert(t, Get(jsonStr, `a*.#[%"John*"]#|#`).String() == "2") 1851 assert(t, Get(jsonStr, `a*.#[_%"John*"]#|#`).String() == "0") 1852 assert(t, Get(jsonStr, `a*.#[="123"]#|#`).String() == "1") 1853 } 1854 1855 func TestParenQueries(t *testing.T) { 1856 jsonStr := `{ 1857 "friends": [{"a":10},{"a":20},{"a":30},{"a":40}] 1858 }` 1859 assert(t, Get(jsonStr, "friends.#(a>9)#|#").Int() == 4) 1860 assert(t, Get(jsonStr, "friends.#(a>10)#|#").Int() == 3) 1861 assert(t, Get(jsonStr, "friends.#(a>40)#|#").Int() == 0) 1862 } 1863 1864 func TestSubSelectors(t *testing.T) { 1865 jsonStr := `{ 1866 "info": { 1867 "friends": [ 1868 { 1869 "first": "Dale", "last": "Murphy", "kind": "Person", 1870 "cust1": true, 1871 "extra": [10,20,30], 1872 "details": { 1873 "city": "Tempe", 1874 "state": "Arizona" 1875 } 1876 }, 1877 { 1878 "first": "Roger", "last": "Craig", "kind": "Person", 1879 "cust2": false, 1880 "extra": [40,50,60], 1881 "details": { 1882 "city": "Phoenix", 1883 "state": "Arizona" 1884 } 1885 } 1886 ] 1887 } 1888 }` 1889 assert(t, Get(jsonStr, "[]").String() == "[]") 1890 assert(t, Get(jsonStr, "{}").String() == "{}") 1891 res := Get(jsonStr, `{`+ 1892 `abc:info.friends.0.first,`+ 1893 `info.friends.1.last,`+ 1894 `"a`+"\r"+`a":info.friends.0.kind,`+ 1895 `"abc":info.friends.1.kind,`+ 1896 `{123:info.friends.1.cust2},`+ 1897 `[info.friends.#[details.city="Phoenix"]#|#]`+ 1898 `}.@pretty.@ugly`).String() 1899 // println(res) 1900 // {"abc":"Dale","last":"Craig","\"a\ra\"":"Person","_":{"123":false},"_":[1]} 1901 assert(t, Get(res, "abc").String() == "Dale") 1902 assert(t, Get(res, "last").String() == "Craig") 1903 assert(t, Get(res, "\"a\ra\"").String() == "Person") 1904 assert(t, Get(res, "@reverse.abc").String() == "Person") 1905 assert(t, Get(res, "_.123").String() == "false") 1906 assert(t, Get(res, "@reverse._.0").String() == "1") 1907 assert(t, Get(jsonStr, "info.friends.[0.first,1.extra.0]").String() == 1908 `["Dale",40]`) 1909 assert(t, Get(jsonStr, "info.friends.#.[first,extra.0]").String() == 1910 `[["Dale",10],["Roger",40]]`) 1911 } 1912 1913 func TestArrayCountRawOutput(t *testing.T) { 1914 assert(t, Get(`[1,2,3,4]`, "#").Raw == "4") 1915 } 1916 1917 func TestParseQuery(t *testing.T) { 1918 var path, op, value, remain string 1919 var ok bool 1920 1921 path, op, value, remain, _, _, ok = 1922 parseQuery(`#(service_roles.#(=="one").()==asdf).cap`) 1923 assert(t, ok && 1924 path == `service_roles.#(=="one").()` && 1925 op == "=" && 1926 value == `asdf` && 1927 remain == `.cap`) 1928 1929 path, op, value, remain, _, _, ok = parseQuery(`#(first_name%"Murphy").last`) 1930 assert(t, ok && 1931 path == `first_name` && 1932 op == `%` && 1933 value == `"Murphy"` && 1934 remain == `.last`) 1935 1936 path, op, value, remain, _, _, ok = parseQuery(`#( first_name !% "Murphy" ).last`) 1937 assert(t, ok && 1938 path == `first_name` && 1939 op == `!%` && 1940 value == `"Murphy"` && 1941 remain == `.last`) 1942 1943 path, op, value, remain, _, _, ok = parseQuery(`#(service_roles.#(=="one"))`) 1944 assert(t, ok && 1945 path == `service_roles.#(=="one")` && 1946 op == `` && 1947 value == `` && 1948 remain == ``) 1949 1950 path, op, value, remain, _, _, ok = 1951 parseQuery(`#(a\("\"(".#(=="o\"(ne")%"ab\")").remain`) 1952 assert(t, ok && 1953 path == `a\("\"(".#(=="o\"(ne")` && 1954 op == "%" && 1955 value == `"ab\")"` && 1956 remain == `.remain`) 1957 } 1958 1959 func TestParentSubQuery(t *testing.T) { 1960 var jsonStr = `{ 1961 "topology": { 1962 "instances": [ 1963 { 1964 "service_version": "1.2.3", 1965 "service_locale": {"lang": "en"}, 1966 "service_roles": ["one", "two"] 1967 }, 1968 { 1969 "service_version": "1.2.4", 1970 "service_locale": {"lang": "th"}, 1971 "service_roles": ["three", "four"] 1972 }, 1973 { 1974 "service_version": "1.2.2", 1975 "service_locale": {"lang": "en"}, 1976 "service_roles": ["one"] 1977 } 1978 ] 1979 } 1980 }` 1981 res := Get(jsonStr, `topology.instances.#( service_roles.#(=="one"))#.service_version`) 1982 // should return two instances 1983 assert(t, res.String() == `["1.2.3","1.2.2"]`) 1984 } 1985 1986 func TestSingleModifier(t *testing.T) { 1987 var data = `{"@key": "value"}` 1988 assert(t, Get(data, "@key").String() == "value") 1989 assert(t, Get(data, "\\@key").String() == "value") 1990 } 1991 1992 func TestModifiersInMultipaths(t *testing.T) { 1993 AddModifier("case", func(jsonStr, arg string) string { 1994 if arg == "upper" { 1995 return strings.ToUpper(jsonStr) 1996 } 1997 if arg == "lower" { 1998 return strings.ToLower(jsonStr) 1999 } 2000 return jsonStr 2001 }) 2002 jsonStr := `{"friends": [ 2003 {"age": 44, "first": "Dale", "last": "Murphy"}, 2004 {"age": 68, "first": "Roger", "last": "Craig"}, 2005 {"age": 47, "first": "Jane", "last": "Murphy"} 2006 ]}` 2007 2008 res := Get(jsonStr, `friends.#.{age,first|@case:upper}|@ugly`) 2009 exp := `[{"age":44,"@case:upper":"DALE"},{"age":68,"@case:upper":"ROGER"},{"age":47,"@case:upper":"JANE"}]` 2010 assert(t, res.Raw == exp) 2011 2012 res = Get(jsonStr, `{friends.#.{age,first:first|@case:upper}|0.first}`) 2013 exp = `{"first":"DALE"}` 2014 assert(t, res.Raw == exp) 2015 2016 res = Get(readmeJSON, `{"children":children|@case:upper,"name":name.first,"age":age}`) 2017 exp = `{"children":["SARA","ALEX","JACK"],"name":"Tom","age":37}` 2018 assert(t, res.Raw == exp) 2019 } 2020 2021 func TestIssue141(t *testing.T) { 2022 jsonStr := `{"data": [{"q": 11, "w": 12}, {"q": 21, "w": 22}, {"q": 31, "w": 32} ], "sql": "some stuff here"}` 2023 assert(t, Get(jsonStr, "data.#").Int() == 3) 2024 assert(t, Get(jsonStr, "data.#.{q}|@ugly").Raw == `[{"q":11},{"q":21},{"q":31}]`) 2025 assert(t, Get(jsonStr, "data.#.q|@ugly").Raw == `[11,21,31]`) 2026 } 2027 2028 func TestChainedModifierStringArgs(t *testing.T) { 2029 // issue #143 2030 AddModifier("push", func(jsonStr, arg string) string { 2031 jsonStr = strings.TrimSpace(jsonStr) 2032 if len(jsonStr) < 2 || !Parse(jsonStr).IsArray() { 2033 return jsonStr 2034 } 2035 jsonStr = strings.TrimSpace(jsonStr[1 : len(jsonStr)-1]) 2036 if len(jsonStr) == 0 { 2037 return "[" + arg + "]" 2038 } 2039 return "[" + jsonStr + "," + arg + "]" 2040 }) 2041 res := Get("[]", `@push:"2"|@push:"3"|@push:{"a":"b","c":["e","f"]}|@push:true|@push:10.23`) 2042 assert(t, res.String() == `["2","3",{"a":"b","c":["e","f"]},true,10.23]`) 2043 } 2044 2045 func TestFlatten(t *testing.T) { 2046 jsonStr := `[1,[2],[3,4],[5,[6,[7]]],{"hi":"there"},8,[9]]` 2047 assert(t, Get(jsonStr, "@flatten").String() == `[1,2,3,4,5,[6,[7]],{"hi":"there"},8,9]`) 2048 assert(t, Get(jsonStr, `@flatten:{"deep":true}`).String() == `[1,2,3,4,5,6,7,{"hi":"there"},8,9]`) 2049 assert(t, Get(`{"9999":1234}`, "@flatten").String() == `{"9999":1234}`) 2050 } 2051 2052 func TestJoin(t *testing.T) { 2053 assert(t, Get(`[{},{}]`, "@join").String() == `{}`) 2054 assert(t, Get(`[{"a":1},{"b":2}]`, "@join").String() == `{"a":1,"b":2}`) 2055 assert(t, Get(`[{"a":1,"b":1},{"b":2}]`, "@join").String() == `{"a":1,"b":2}`) 2056 assert(t, Get(`[{"a":1,"b":1},{"b":2},5,{"c":3}]`, "@join").String() == `{"a":1,"b":2,"c":3}`) 2057 assert(t, Get(`[{"a":1,"b":1},{"b":2},5,{"c":3}]`, `@join:{"preserve":true}`).String() == `{"a":1,"b":1,"b":2,"c":3}`) 2058 assert(t, Get(`[{"a":1,"b":1},{"b":2},5,{"c":3}]`, `@join:{"preserve":true}.b`).String() == `1`) 2059 assert(t, Get(`{"9999":1234}`, "@join").String() == `{"9999":1234}`) 2060 } 2061 2062 func TestValid(t *testing.T) { 2063 assert(t, Get("[{}", "@valid").Exists() == false) 2064 assert(t, Get("[{}]", "@valid").Exists() == true) 2065 } 2066 2067 // https://github.com/tidwall/gjsonStr/issues/152 2068 func TestJoin152(t *testing.T) { 2069 var jsonStr = `{ 2070 "distance": 1374.0, 2071 "validFrom": "2005-11-14", 2072 "historical": { 2073 "type": "Day", 2074 "name": "last25Hours", 2075 "summary": { 2076 "units": { 2077 "temperature": "C", 2078 "wind": "m/s", 2079 "snow": "cm", 2080 "precipitation": "mm" 2081 }, 2082 "days": [ 2083 { 2084 "time": "2020-02-08", 2085 "hours": [ 2086 { 2087 "temperature": { 2088 "min": -2.0, 2089 "max": -1.6, 2090 "value": -1.6 2091 }, 2092 "wind": {}, 2093 "precipitation": {}, 2094 "humidity": { 2095 "value": 92.0 2096 }, 2097 "snow": { 2098 "depth": 49.0 2099 }, 2100 "time": "2020-02-08T16:00:00+01:00" 2101 }, 2102 { 2103 "temperature": { 2104 "min": -1.7, 2105 "max": -1.3, 2106 "value": -1.3 2107 }, 2108 "wind": {}, 2109 "precipitation": {}, 2110 "humidity": { 2111 "value": 92.0 2112 }, 2113 "snow": { 2114 "depth": 49.0 2115 }, 2116 "time": "2020-02-08T17:00:00+01:00" 2117 }, 2118 { 2119 "temperature": { 2120 "min": -1.3, 2121 "max": -0.9, 2122 "value": -1.2 2123 }, 2124 "wind": {}, 2125 "precipitation": {}, 2126 "humidity": { 2127 "value": 91.0 2128 }, 2129 "snow": { 2130 "depth": 49.0 2131 }, 2132 "time": "2020-02-08T18:00:00+01:00" 2133 } 2134 ] 2135 }, 2136 { 2137 "time": "2020-02-09", 2138 "hours": [ 2139 { 2140 "temperature": { 2141 "min": -1.7, 2142 "max": -0.9, 2143 "value": -1.5 2144 }, 2145 "wind": {}, 2146 "precipitation": {}, 2147 "humidity": { 2148 "value": 91.0 2149 }, 2150 "snow": { 2151 "depth": 49.0 2152 }, 2153 "time": "2020-02-09T00:00:00+01:00" 2154 }, 2155 { 2156 "temperature": { 2157 "min": -1.5, 2158 "max": 0.9, 2159 "value": 0.2 2160 }, 2161 "wind": {}, 2162 "precipitation": {}, 2163 "humidity": { 2164 "value": 67.0 2165 }, 2166 "snow": { 2167 "depth": 49.0 2168 }, 2169 "time": "2020-02-09T01:00:00+01:00" 2170 } 2171 ] 2172 } 2173 ] 2174 } 2175 } 2176 }` 2177 2178 res := Get(jsonStr, "historical.summary.days.#.hours|@flatten|#.humidity.value") 2179 assert(t, res.Raw == `[92.0,92.0,91.0,91.0,67.0]`) 2180 } 2181 2182 func TestVariousFuzz(t *testing.T) { 2183 // Issue #192 assert(t, squash(`"000"hello`) == `"000"`) 2184 assert(t, squash(`"000"`) == `"000"`) 2185 assert(t, squash(`"000`) == `"000`) 2186 assert(t, squash(`"`) == `"`) 2187 2188 assert(t, squash(`[000]hello`) == `[000]`) 2189 assert(t, squash(`[000]`) == `[000]`) 2190 assert(t, squash(`[000`) == `[000`) 2191 assert(t, squash(`[`) == `[`) 2192 assert(t, squash(`]`) == `]`) 2193 2194 testJSON := `0.#[[{}]].@valid:"000` 2195 Get(testJSON, testJSON) 2196 2197 // Issue #195 2198 testJSON = `\************************************` + 2199 `**********{**",**,,**,**,**,**,"",**,**,**,**,**,**,**,**,**,**]` 2200 Get(testJSON, testJSON) 2201 2202 // Issue #196 2203 testJSON = `[#.@pretty.@join:{""[]""preserve"3,"][{]]]` 2204 Get(testJSON, testJSON) 2205 2206 // Issue #237 2207 testJSON1 := `["*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,,,,,,"]` 2208 testJSON2 := `#[%"*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,,,,,,""*,*"]` 2209 Get(testJSON1, testJSON2) 2210 2211 } 2212 2213 func TestSubpathsWithMultipaths(t *testing.T) { 2214 const jsonStr = ` 2215 [ 2216 {"a": 1}, 2217 {"a": 2, "values": ["a", "b", "c", "d", "e"]}, 2218 true, 2219 ["a", "b", "c", "d", "e"], 2220 4 2221 ] 2222 ` 2223 assert(t, Get(jsonStr, `1.values.@ugly`).Raw == `["a","b","c","d","e"]`) 2224 assert(t, Get(jsonStr, `1.values.[0,3]`).Raw == `["a","d"]`) 2225 assert(t, Get(jsonStr, `3.@ugly`).Raw == `["a","b","c","d","e"]`) 2226 assert(t, Get(jsonStr, `3.[0,3]`).Raw == `["a","d"]`) 2227 assert(t, Get(jsonStr, `#.@ugly`).Raw == `[{"a":1},{"a":2,"values":["a","b","c","d","e"]},true,["a","b","c","d","e"],4]`) 2228 assert(t, Get(jsonStr, `#.[0,3]`).Raw == `[[],[],[],["a","d"],[]]`) 2229 } 2230 2231 func TestFlattenRemoveNonExist(t *testing.T) { 2232 raw := Get("[[1],[2,[[],[3]],[4,[5],[],[[[6]]]]]]", `@flatten:{"deep":true}`).Raw 2233 assert(t, raw == "[1,2,3,4,5,6]") 2234 } 2235 2236 func TestPipeEmptyArray(t *testing.T) { 2237 raw := Get("[]", `#(hello)#`).Raw 2238 assert(t, raw == "[]") 2239 } 2240 2241 func TestEncodedQueryString(t *testing.T) { 2242 jsonStr := `{ 2243 "friends": [ 2244 {"first": "Dale", "last": "Mur\nphy", "age": 44}, 2245 {"first": "Roger", "last": "Craig", "age": 68}, 2246 {"first": "Jane", "last": "Murphy", "age": 47} 2247 ] 2248 }` 2249 assert(t, Get(jsonStr, `friends.#(last=="Mur\nphy").age`).Int() == 44) 2250 assert(t, Get(jsonStr, `friends.#(last=="Murphy").age`).Int() == 47) 2251 } 2252 2253 func TestBoolConvertQuery(t *testing.T) { 2254 jsonStr := `{ 2255 "vals": [ 2256 { "a": 1, "b": true }, 2257 { "a": 2, "b": true }, 2258 { "a": 3, "b": false }, 2259 { "a": 4, "b": "0" }, 2260 { "a": 5, "b": 0 }, 2261 { "a": 6, "b": "1" }, 2262 { "a": 7, "b": 1 }, 2263 { "a": 8, "b": "true" }, 2264 { "a": 9, "b": false }, 2265 { "a": 10, "b": null }, 2266 { "a": 11 } 2267 ] 2268 }` 2269 trues := Get(jsonStr, `vals.#(b==~true)#.a`).Raw 2270 falses := Get(jsonStr, `vals.#(b==~false)#.a`).Raw 2271 assert(t, trues == "[1,2,6,7,8]") 2272 assert(t, falses == "[3,4,5,9,10,11]") 2273 } 2274 2275 func TestModifierDoubleQuotes(t *testing.T) { 2276 josn := `{ 2277 "data": [ 2278 { 2279 "name": "Product P4", 2280 "productId": "1bb3", 2281 "vendorId": "10de" 2282 }, 2283 { 2284 "name": "Product P4", 2285 "productId": "1cc3", 2286 "vendorId": "20de" 2287 }, 2288 { 2289 "name": "Product P4", 2290 "productId": "1dd3", 2291 "vendorId": "30de" 2292 } 2293 ] 2294 }` 2295 AddModifier("string", func(josn, arg string) string { 2296 return strconv.Quote(josn) 2297 }) 2298 2299 res := Get(josn, "data.#.{name,value:{productId,vendorId}.@string.@ugly}") 2300 2301 assert(t, res.Raw == `[`+ 2302 `{"name":"Product P4","value":"{\"productId\":\"1bb3\",\"vendorId\":\"10de\"}"},`+ 2303 `{"name":"Product P4","value":"{\"productId\":\"1cc3\",\"vendorId\":\"20de\"}"},`+ 2304 `{"name":"Product P4","value":"{\"productId\":\"1dd3\",\"vendorId\":\"30de\"}"}`+ 2305 `]`) 2306 2307 } 2308 2309 func TestIndexes(t *testing.T) { 2310 var exampleJSON = `{ 2311 "vals": [ 2312 [1,66,{test: 3}], 2313 [4,5,[6]] 2314 ], 2315 "objectArray":[ 2316 {"first": "Dale", "age": 44}, 2317 {"first": "Roger", "age": 68}, 2318 ] 2319 }` 2320 2321 testCases := []struct { 2322 path string 2323 expected []string 2324 }{ 2325 { 2326 `vals.#.1`, 2327 []string{`6`, "5"}, 2328 }, 2329 { 2330 `vals.#.2`, 2331 []string{"{", "["}, 2332 }, 2333 { 2334 `objectArray.#(age>43)#.first`, 2335 []string{`"`, `"`}, 2336 }, 2337 { 2338 `objectArray.@reverse.#.first`, 2339 nil, 2340 }, 2341 } 2342 2343 for _, tc := range testCases { 2344 r := Get(exampleJSON, tc.path) 2345 2346 assert(t, len(r.Indexes) == len(tc.expected)) 2347 2348 for i, a := range r.Indexes { 2349 assert(t, string(exampleJSON[a]) == tc.expected[i]) 2350 } 2351 } 2352 } 2353 2354 func TestIndexesMatchesRaw(t *testing.T) { 2355 var exampleJSON = `{ 2356 "objectArray":[ 2357 {"first": "Jason", "age": 41}, 2358 {"first": "Dale", "age": 44}, 2359 {"first": "Roger", "age": 68}, 2360 {"first": "Mandy", "age": 32} 2361 ] 2362 }` 2363 r := Get(exampleJSON, `objectArray.#(age>43)#.first`) 2364 assert(t, len(r.Indexes) == 2) 2365 assert(t, Parse(exampleJSON[r.Indexes[0]:]).String() == "Dale") 2366 assert(t, Parse(exampleJSON[r.Indexes[1]:]).String() == "Roger") 2367 r = Get(exampleJSON, `objectArray.#(age>43)#`) 2368 assert(t, Parse(exampleJSON[r.Indexes[0]:]).Get("first").String() == "Dale") 2369 assert(t, Parse(exampleJSON[r.Indexes[1]:]).Get("first").String() == "Roger") 2370 } 2371 2372 func TestIssue240(t *testing.T) { 2373 nonArrayData := `{"jsonrpc":"2.0","method":"subscription","params": 2374 {"channel":"funny_channel","data": 2375 {"name":"Jason","company":"good_company","number":12345} 2376 } 2377 }` 2378 parsed := Parse(nonArrayData) 2379 assert(t, len(parsed.Get("params.data").Array()) == 1) 2380 2381 arrayData := `{"jsonrpc":"2.0","method":"subscription","params": 2382 {"channel":"funny_channel","data":[ 2383 {"name":"Jason","company":"good_company","number":12345} 2384 ]} 2385 }` 2386 parsed = Parse(arrayData) 2387 assert(t, len(parsed.Get("params.data").Array()) == 1) 2388 } 2389 2390 func TestKeysValuesModifier(t *testing.T) { 2391 var jsonStr = `{ 2392 "1300014": { 2393 "code": "1300014", 2394 "price": 59.18, 2395 "symbol": "300014", 2396 "update": "2020/04/15 15:59:54", 2397 }, 2398 "1300015": { 2399 "code": "1300015", 2400 "price": 43.31, 2401 "symbol": "300015", 2402 "update": "2020/04/15 15:59:54", 2403 } 2404 }` 2405 assert(t, Get(jsonStr, `@keys`).String() == `["1300014","1300015"]`) 2406 assert(t, Get(``, `@keys`).String() == `[]`) 2407 assert(t, Get(`"hello"`, `@keys`).String() == `[null]`) 2408 assert(t, Get(`[]`, `@keys`).String() == `[]`) 2409 assert(t, Get(`[1,2,3]`, `@keys`).String() == `[null,null,null]`) 2410 2411 assert(t, Get(jsonStr, `@values.#.code`).String() == `["1300014","1300015"]`) 2412 assert(t, Get(``, `@values`).String() == `[]`) 2413 assert(t, Get(`"hello"`, `@values`).String() == `["hello"]`) 2414 assert(t, Get(`[]`, `@values`).String() == `[]`) 2415 assert(t, Get(`[1,2,3]`, `@values`).String() == `[1,2,3]`) 2416 } 2417 2418 func TestNaNInf(t *testing.T) { 2419 jsonStr := `[+Inf,-Inf,Inf,iNF,-iNF,+iNF,NaN,nan,nAn,-0,+0]` 2420 raws := []string{"+Inf", "-Inf", "Inf", "iNF", "-iNF", "+iNF", "NaN", "nan", 2421 "nAn", "-0", "+0"} 2422 nums := []float64{math.Inf(+1), math.Inf(-1), math.Inf(0), math.Inf(0), 2423 math.Inf(-1), math.Inf(+1), math.NaN(), math.NaN(), math.NaN(), 2424 math.Copysign(0, -1), 0} 2425 2426 assert(t, int(Get(jsonStr, `#`).Int()) == len(raws)) 2427 for i := 0; i < len(raws); i++ { 2428 r := Get(jsonStr, fmt.Sprintf("%d", i)) 2429 assert(t, r.Raw == raws[i]) 2430 assert(t, r.Num == nums[i] || (math.IsNaN(r.Num) && math.IsNaN(nums[i]))) 2431 assert(t, r.Type == Number) 2432 } 2433 2434 var i int 2435 Parse(jsonStr).ForEach(func(_, r Result) bool { 2436 assert(t, r.Raw == raws[i]) 2437 assert(t, r.Num == nums[i] || (math.IsNaN(r.Num) && math.IsNaN(nums[i]))) 2438 assert(t, r.Type == Number) 2439 i++ 2440 return true 2441 }) 2442 2443 // Parse should also return valid numbers 2444 assert(t, math.IsNaN(Parse("nan").Float())) 2445 assert(t, math.IsNaN(Parse("NaN").Float())) 2446 assert(t, math.IsNaN(Parse(" NaN").Float())) 2447 assert(t, math.IsInf(Parse("+inf").Float(), +1)) 2448 assert(t, math.IsInf(Parse("-inf").Float(), -1)) 2449 assert(t, math.IsInf(Parse("+INF").Float(), +1)) 2450 assert(t, math.IsInf(Parse("-INF").Float(), -1)) 2451 assert(t, math.IsInf(Parse(" +INF").Float(), +1)) 2452 assert(t, math.IsInf(Parse(" -INF").Float(), -1)) 2453 } 2454 2455 func TestEmptyValueQuery(t *testing.T) { 2456 // issue: https://github.com/tidwall/gjson/issues/246 2457 assert(t, Get( 2458 `["ig","","tw","fb","tw","ig","tw"]`, 2459 `#(!="")#`).Raw == 2460 `["ig","tw","fb","tw","ig","tw"]`) 2461 assert(t, Get( 2462 `["ig","","tw","fb","tw","ig","tw"]`, 2463 `#(!=)#`).Raw == 2464 `["ig","tw","fb","tw","ig","tw"]`) 2465 } 2466 2467 func TestParseIndex(t *testing.T) { 2468 assert(t, Parse(`{}`).Index == 0) 2469 assert(t, Parse(` {}`).Index == 1) 2470 assert(t, Parse(` []`).Index == 1) 2471 assert(t, Parse(` true`).Index == 1) 2472 assert(t, Parse(` false`).Index == 1) 2473 assert(t, Parse(` null`).Index == 1) 2474 assert(t, Parse(` +inf`).Index == 1) 2475 assert(t, Parse(` -inf`).Index == 1) 2476 } 2477 2478 func TestRevSquash(t *testing.T) { 2479 assert(t, revSquash(` {}`) == `{}`) 2480 assert(t, revSquash(` }`) == ` }`) 2481 assert(t, revSquash(` [123]`) == `[123]`) 2482 assert(t, revSquash(` ,123,123]`) == ` ,123,123]`) 2483 assert(t, revSquash(` hello,[[true,false],[0,1,2,3,5],[123]]`) == `[[true,false],[0,1,2,3,5],[123]]`) 2484 assert(t, revSquash(` "hello"`) == `"hello"`) 2485 assert(t, revSquash(` "hel\\lo"`) == `"hel\\lo"`) 2486 assert(t, revSquash(` "hel\\"lo"`) == `"lo"`) 2487 assert(t, revSquash(` "hel\\\"lo"`) == `"hel\\\"lo"`) 2488 assert(t, revSquash(`hel\\\"lo"`) == `hel\\\"lo"`) 2489 assert(t, revSquash(`\"hel\\\"lo"`) == `\"hel\\\"lo"`) 2490 assert(t, revSquash(`\\\"hel\\\"lo"`) == `\\\"hel\\\"lo"`) 2491 assert(t, revSquash(`\\\\"hel\\\"lo"`) == `"hel\\\"lo"`) 2492 assert(t, revSquash(`hello"`) == `hello"`) 2493 jsonStr := `true,[0,1,"sadf\"asdf",{"hi":["hello","t\"\"u",{"a":"b"}]},9]` 2494 assert(t, revSquash(jsonStr) == jsonStr[5:]) 2495 assert(t, revSquash(jsonStr[:len(jsonStr)-3]) == `{"hi":["hello","t\"\"u",{"a":"b"}]}`) 2496 assert(t, revSquash(jsonStr[:len(jsonStr)-4]) == `["hello","t\"\"u",{"a":"b"}]`) 2497 assert(t, revSquash(jsonStr[:len(jsonStr)-5]) == `{"a":"b"}`) 2498 assert(t, revSquash(jsonStr[:len(jsonStr)-6]) == `"b"`) 2499 assert(t, revSquash(jsonStr[:len(jsonStr)-10]) == `"a"`) 2500 assert(t, revSquash(jsonStr[:len(jsonStr)-15]) == `"t\"\"u"`) 2501 assert(t, revSquash(jsonStr[:len(jsonStr)-24]) == `"hello"`) 2502 assert(t, revSquash(jsonStr[:len(jsonStr)-33]) == `"hi"`) 2503 assert(t, revSquash(jsonStr[:len(jsonStr)-39]) == `"sadf\"asdf"`) 2504 } 2505 2506 const readmeJSON = ` 2507 { 2508 "name": {"first": "Tom", "last": "Anderson"}, 2509 "age":37, 2510 "children": ["Sara","Alex","Jack"], 2511 "fav.movie": "Deer Hunter", 2512 "friends": [ 2513 {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]}, 2514 {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]}, 2515 {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]} 2516 ] 2517 } 2518 ` 2519 2520 func TestQueryGetPath(t *testing.T) { 2521 assert(t, strings.Join( 2522 Get(readmeJSON, "friends.#.first").Paths(readmeJSON), " ") == 2523 "friends.0.first friends.1.first friends.2.first") 2524 assert(t, strings.Join( 2525 Get(readmeJSON, "friends.#(last=Murphy)").Paths(readmeJSON), " ") == 2526 "") 2527 assert(t, Get(readmeJSON, "friends.#(last=Murphy)").Path(readmeJSON) == 2528 "friends.0") 2529 assert(t, strings.Join( 2530 Get(readmeJSON, "friends.#(last=Murphy)#").Paths(readmeJSON), " ") == 2531 "friends.0 friends.2") 2532 arr := Get(readmeJSON, "friends.#.first").Array() 2533 for i := 0; i < len(arr); i++ { 2534 assert(t, arr[i].Path(readmeJSON) == fmt.Sprintf("friends.%d.first", i)) 2535 } 2536 } 2537 2538 func TestStaticJSON(t *testing.T) { 2539 jsonStr := `{ 2540 "name": {"first": "Tom", "last": "Anderson"} 2541 }` 2542 assert(t, Get(jsonStr, 2543 `"bar"`).Raw == 2544 ``) 2545 assert(t, Get(jsonStr, 2546 `!"bar"`).Raw == 2547 `"bar"`) 2548 assert(t, Get(jsonStr, 2549 `!{"name":{"first":"Tom"}}.{name.first}.first`).Raw == 2550 `"Tom"`) 2551 assert(t, Get(jsonStr, 2552 `{name.last,"foo":!"bar"}`).Raw == 2553 `{"last":"Anderson","foo":"bar"}`) 2554 assert(t, Get(jsonStr, 2555 `{name.last,"foo":!{"a":"b"},"that"}`).Raw == 2556 `{"last":"Anderson","foo":{"a":"b"}}`) 2557 assert(t, Get(jsonStr, 2558 `{name.last,"foo":!{"c":"d"},!"that"}`).Raw == 2559 `{"last":"Anderson","foo":{"c":"d"},"_":"that"}`) 2560 assert(t, Get(jsonStr, 2561 `[!true,!false,!null,!inf,!nan,!hello,{"name":!"andy",name.last},+inf,!["any","thing"]]`).Raw == 2562 `[true,false,null,inf,nan,{"name":"andy","last":"Anderson"},["any","thing"]]`, 2563 ) 2564 } 2565 2566 func TestArrayKeys(t *testing.T) { 2567 N := 100 2568 jsonStr := "[" 2569 for i := 0; i < N; i++ { 2570 if i > 0 { 2571 jsonStr += "," 2572 } 2573 jsonStr += fmt.Sprint(i) 2574 } 2575 jsonStr += "]" 2576 var i int 2577 Parse(jsonStr).ForEach(func(key, value Result) bool { 2578 assert(t, key.String() == fmt.Sprint(i)) 2579 assert(t, key.Int() == int64(i)) 2580 i++ 2581 return true 2582 }) 2583 assert(t, i == N) 2584 }