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