github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/examples/gno.land/p/demo/json/node_test.gno (about) 1 package json 2 3 import ( 4 "bytes" 5 "sort" 6 "strconv" 7 "strings" 8 "testing" 9 10 "gno.land/p/demo/ufmt" 11 ) 12 13 var ( 14 nilKey *string 15 dummyKey = "key" 16 ) 17 18 type _args struct { 19 prev *Node 20 buf *buffer 21 typ ValueType 22 key **string 23 } 24 25 type simpleNode struct { 26 name string 27 node *Node 28 } 29 30 func TestNode_CreateNewNode(t *testing.T) { 31 rel := &dummyKey 32 33 tests := []struct { 34 name string 35 args _args 36 expectCurr *Node 37 expectErr bool 38 expectPanic bool 39 }{ 40 { 41 name: "child for non container type", 42 args: _args{ 43 prev: BoolNode("", true), 44 buf: newBuffer(make([]byte, 10)), 45 typ: Boolean, 46 key: &rel, 47 }, 48 expectCurr: nil, 49 expectErr: true, 50 }, 51 } 52 53 for _, tt := range tests { 54 t.Run(tt.name, func(t *testing.T) { 55 defer func() { 56 if r := recover(); r != nil { 57 if tt.expectPanic { 58 return 59 } 60 t.Errorf("%s panic occurred when not expected: %v", tt.name, r) 61 } else if tt.expectPanic { 62 t.Errorf("%s expected panic but didn't occur", tt.name) 63 } 64 }() 65 66 got, err := NewNode(tt.args.prev, tt.args.buf, tt.args.typ, tt.args.key) 67 if (err != nil) != tt.expectErr { 68 t.Errorf("%s error = %v, expect error %v", tt.name, err, tt.expectErr) 69 return 70 } 71 72 if tt.expectErr { 73 return 74 } 75 76 if !compareNodes(got, tt.expectCurr) { 77 t.Errorf("%s got = %v, want %v", tt.name, got, tt.expectCurr) 78 } 79 }) 80 } 81 } 82 83 func TestNode_Value(t *testing.T) { 84 tests := []struct { 85 name string 86 data []byte 87 _type ValueType 88 expected interface{} 89 errExpected bool 90 }{ 91 {name: "null", data: []byte("null"), _type: Null, expected: nil}, 92 {name: "1", data: []byte("1"), _type: Number, expected: float64(1)}, 93 {name: ".1", data: []byte(".1"), _type: Number, expected: float64(.1)}, 94 {name: "-.1e1", data: []byte("-.1e1"), _type: Number, expected: float64(-1)}, 95 {name: "string", data: []byte("\"foo\""), _type: String, expected: "foo"}, 96 {name: "space", data: []byte("\"foo bar\""), _type: String, expected: "foo bar"}, 97 {name: "true", data: []byte("true"), _type: Boolean, expected: true}, 98 {name: "invalid true", data: []byte("tru"), _type: Unknown, errExpected: true}, 99 {name: "invalid false", data: []byte("fals"), _type: Unknown, errExpected: true}, 100 {name: "false", data: []byte("false"), _type: Boolean, expected: false}, 101 {name: "e1", data: []byte("e1"), _type: Unknown, errExpected: true}, 102 {name: "1a", data: []byte("1a"), _type: Unknown, errExpected: true}, 103 {name: "string error", data: []byte("\"foo\nbar\""), _type: String, errExpected: true}, 104 } 105 106 for _, tt := range tests { 107 t.Run(tt.name, func(t *testing.T) { 108 curr := &Node{ 109 data: tt.data, 110 nodeType: tt._type, 111 borders: [2]int{0, len(tt.data)}, 112 } 113 114 got, err := curr.Value() 115 if err != nil { 116 if !tt.errExpected { 117 t.Errorf("%s error = %v, expect error %v", tt.name, err, tt.errExpected) 118 } 119 return 120 } 121 122 if got != tt.expected { 123 t.Errorf("%s got = %v, want %v", tt.name, got, tt.expected) 124 } 125 }) 126 } 127 } 128 129 func TestNode_Delete(t *testing.T) { 130 root := Must(Unmarshal([]byte(`{"foo":"bar"}`))) 131 if err := root.Delete(); err != nil { 132 t.Errorf("Delete returns error: %v", err) 133 } 134 135 if value, err := Marshal(root); err != nil { 136 t.Errorf("Marshal returns error: %v", err) 137 } else if string(value) != `{"foo":"bar"}` { 138 t.Errorf("Marshal returns wrong value: %s", string(value)) 139 } 140 141 foo := root.MustKey("foo") 142 if err := foo.Delete(); err != nil { 143 t.Errorf("Delete returns error while handling foo: %v", err) 144 } 145 146 if value, err := Marshal(root); err != nil { 147 t.Errorf("Marshal returns error: %v", err) 148 } else if string(value) != `{}` { 149 t.Errorf("Marshal returns wrong value: %s", string(value)) 150 } 151 152 if value, err := Marshal(foo); err != nil { 153 t.Errorf("Marshal returns error: %v", err) 154 } else if string(value) != `"bar"` { 155 t.Errorf("Marshal returns wrong value: %s", string(value)) 156 } 157 158 if foo.prev != nil { 159 t.Errorf("foo.prev should be nil") 160 } 161 } 162 163 func TestNode_ObjectNode(t *testing.T) { 164 objs := map[string]*Node{ 165 "key1": NullNode("null"), 166 "key2": NumberNode("answer", 42), 167 "key3": StringNode("string", "foobar"), 168 "key4": BoolNode("bool", true), 169 } 170 171 node := ObjectNode("test", objs) 172 173 if len(node.next) != len(objs) { 174 t.Errorf("ObjectNode: want %v got %v", len(objs), len(node.next)) 175 } 176 177 for k, v := range objs { 178 if node.next[k] == nil { 179 t.Errorf("ObjectNode: want %v got %v", v, node.next[k]) 180 } 181 } 182 } 183 184 func TestNode_AppendObject(t *testing.T) { 185 if err := Must(Unmarshal([]byte(`{"foo":"bar","baz":null}`))).AppendObject("biz", NullNode("")); err != nil { 186 t.Errorf("AppendArray should return error") 187 } 188 189 root := Must(Unmarshal([]byte(`{"foo":"bar"}`))) 190 if err := root.AppendObject("baz", NullNode("")); err != nil { 191 t.Errorf("AppendObject should not return error: %s", err) 192 } 193 194 if value, err := Marshal(root); err != nil { 195 t.Errorf("Marshal returns error: %v", err) 196 } else if isSameObject(string(value), `"{"foo":"bar","baz":null}"`) { 197 t.Errorf("Marshal returns wrong value: %s", string(value)) 198 } 199 200 // FIXME: this may fail if execute test in more than 3 times in a row. 201 if err := root.AppendObject("biz", NumberNode("", 42)); err != nil { 202 t.Errorf("AppendObject returns error: %v", err) 203 } 204 205 val, err := Marshal(root) 206 if err != nil { 207 t.Errorf("Marshal returns error: %v", err) 208 } 209 210 // FIXME: this may fail if execute test in more than 3 times in a row. 211 if isSameObject(string(val), `"{"foo":"bar","baz":null,"biz":42}"`) { 212 t.Errorf("Marshal returns wrong value: %s", string(val)) 213 } 214 } 215 216 func TestNode_ArrayNode(t *testing.T) { 217 arr := []*Node{ 218 NullNode("nil"), 219 NumberNode("num", 42), 220 StringNode("str", "foobar"), 221 BoolNode("bool", true), 222 } 223 224 node := ArrayNode("test", arr) 225 226 if len(node.next) != len(arr) { 227 t.Errorf("ArrayNode: want %v got %v", len(arr), len(node.next)) 228 } 229 230 for i, v := range arr { 231 if node.next[strconv.Itoa(i)] == nil { 232 t.Errorf("ArrayNode: want %v got %v", v, node.next[strconv.Itoa(i)]) 233 } 234 } 235 } 236 237 func TestNode_AppendArray(t *testing.T) { 238 if err := Must(Unmarshal([]byte(`[{"foo":"bar"}]`))).AppendArray(NullNode("")); err != nil { 239 t.Errorf("should return error") 240 } 241 242 root := Must(Unmarshal([]byte(`[{"foo":"bar"}]`))) 243 if err := root.AppendArray(NullNode("")); err != nil { 244 t.Errorf("should not return error: %s", err) 245 } 246 247 if value, err := Marshal(root); err != nil { 248 t.Errorf("Marshal returns error: %v", err) 249 } else if string(value) != `[{"foo":"bar"},null]` { 250 t.Errorf("Marshal returns wrong value: %s", string(value)) 251 } 252 253 if err := root.AppendArray( 254 NumberNode("", 1), 255 StringNode("", "foo"), 256 Must(Unmarshal([]byte(`[0,1,null,true,"example"]`))), 257 Must(Unmarshal([]byte(`{"foo": true, "bar": null, "baz": 123}`))), 258 ); err != nil { 259 t.Errorf("AppendArray returns error: %v", err) 260 } 261 262 if value, err := Marshal(root); err != nil { 263 t.Errorf("Marshal returns error: %v", err) 264 } else if string(value) != `[{"foo":"bar"},null,1,"foo",[0,1,null,true,"example"],{"foo": true, "bar": null, "baz": 123}]` { 265 t.Errorf("Marshal returns wrong value: %s", string(value)) 266 } 267 } 268 269 /******** value getter ********/ 270 271 func TestNode_GetBool(t *testing.T) { 272 root, err := Unmarshal([]byte(`true`)) 273 if err != nil { 274 t.Errorf("Error on Unmarshal(): %s", err.Error()) 275 return 276 } 277 278 value, err := root.GetBool() 279 if err != nil { 280 t.Errorf("Error on root.GetBool(): %s", err.Error()) 281 } 282 283 if !value { 284 t.Errorf("root.GetBool() is corrupted") 285 } 286 } 287 288 func TestNode_GetBool_Fail(t *testing.T) { 289 tests := []simpleNode{ 290 {"nil node", (*Node)(nil)}, 291 {"literally null node", NullNode("")}, 292 } 293 294 for _, tt := range tests { 295 t.Run(tt.name, func(t *testing.T) { 296 if _, err := tt.node.GetBool(); err == nil { 297 t.Errorf("%s should be an error", tt.name) 298 } 299 }) 300 } 301 } 302 303 func TestNode_IsBool(t *testing.T) { 304 tests := []simpleNode{ 305 {"true", BoolNode("", true)}, 306 {"false", BoolNode("", false)}, 307 } 308 309 for _, tt := range tests { 310 t.Run(tt.name, func(t *testing.T) { 311 if !tt.node.IsBool() { 312 t.Errorf("%s should be a bool", tt.name) 313 } 314 }) 315 } 316 } 317 318 func TestNode_IsBool_With_Unmarshal(t *testing.T) { 319 tests := []struct { 320 name string 321 json []byte 322 want bool 323 }{ 324 {"true", []byte("true"), true}, 325 {"false", []byte("false"), true}, 326 } 327 328 for _, tt := range tests { 329 t.Run(tt.name, func(t *testing.T) { 330 root, err := Unmarshal(tt.json) 331 if err != nil { 332 t.Errorf("Error on Unmarshal(): %s", err.Error()) 333 } 334 335 if root.IsBool() != tt.want { 336 t.Errorf("%s should be a bool", tt.name) 337 } 338 }) 339 } 340 } 341 342 var nullJson = []byte(`null`) 343 344 func TestNode_GetNull(t *testing.T) { 345 root, err := Unmarshal(nullJson) 346 if err != nil { 347 t.Errorf("Error on Unmarshal(): %s", err.Error()) 348 } 349 350 value, err := root.GetNull() 351 if err != nil { 352 t.Errorf("error occurred while getting null, %s", err) 353 } 354 355 if value != nil { 356 t.Errorf("value is not matched. expected: nil, got: %v", value) 357 } 358 } 359 360 func TestNode_GetNull_Fail(t *testing.T) { 361 tests := []simpleNode{ 362 {"nil node", (*Node)(nil)}, 363 {"number node is null", NumberNode("", 42)}, 364 } 365 366 for _, tt := range tests { 367 t.Run(tt.name, func(t *testing.T) { 368 if _, err := tt.node.GetNull(); err == nil { 369 t.Errorf("%s should be an error", tt.name) 370 } 371 }) 372 } 373 } 374 375 func TestNode_MustNull(t *testing.T) { 376 root, err := Unmarshal(nullJson) 377 if err != nil { 378 t.Errorf("Error on Unmarshal(): %s", err.Error()) 379 } 380 381 value := root.MustNull() 382 if value != nil { 383 t.Errorf("value is not matched. expected: nil, got: %v", value) 384 } 385 } 386 387 func TestNode_GetNumeric_Float(t *testing.T) { 388 root, err := Unmarshal([]byte(`123.456`)) 389 if err != nil { 390 t.Errorf("Error on Unmarshal(): %s", err) 391 return 392 } 393 394 value, err := root.GetNumeric() 395 if err != nil { 396 t.Errorf("Error on root.GetNumeric(): %s", err) 397 } 398 399 if value != float64(123.456) { 400 t.Errorf(ufmt.Sprintf("value is not matched. expected: 123.456, got: %v", value)) 401 } 402 } 403 404 func TestNode_GetNumeric_Scientific_Notation(t *testing.T) { 405 root, err := Unmarshal([]byte(`1e3`)) 406 if err != nil { 407 t.Errorf("Error on Unmarshal(): %s", err) 408 return 409 } 410 411 value, err := root.GetNumeric() 412 if err != nil { 413 t.Errorf("Error on root.GetNumeric(): %s", err) 414 } 415 416 if value != float64(1000) { 417 t.Errorf(ufmt.Sprintf("value is not matched. expected: 1000, got: %v", value)) 418 } 419 } 420 421 func TestNode_GetNumeric_With_Unmarshal(t *testing.T) { 422 root, err := Unmarshal([]byte(`123`)) 423 if err != nil { 424 t.Errorf("Error on Unmarshal(): %s", err) 425 return 426 } 427 428 value, err := root.GetNumeric() 429 if err != nil { 430 t.Errorf("Error on root.GetNumeric(): %s", err) 431 } 432 433 if value != float64(123) { 434 t.Errorf(ufmt.Sprintf("value is not matched. expected: 123, got: %v", value)) 435 } 436 } 437 438 func TestNode_GetNumeric_Fail(t *testing.T) { 439 tests := []simpleNode{ 440 {"nil node", (*Node)(nil)}, 441 {"null node", NullNode("")}, 442 {"string node", StringNode("", "123")}, 443 } 444 445 for _, tt := range tests { 446 t.Run(tt.name, func(t *testing.T) { 447 if _, err := tt.node.GetNumeric(); err == nil { 448 t.Errorf("%s should be an error", tt.name) 449 } 450 }) 451 } 452 } 453 454 func TestNode_GetString(t *testing.T) { 455 root, err := Unmarshal([]byte(`"123foobar 3456"`)) 456 if err != nil { 457 t.Errorf("Error on Unmarshal(): %s", err) 458 } 459 460 value, err := root.GetString() 461 if err != nil { 462 t.Errorf("Error on root.GetString(): %s", err) 463 } 464 465 if value != "123foobar 3456" { 466 t.Errorf(ufmt.Sprintf("value is not matched. expected: 123, got: %s", value)) 467 } 468 } 469 470 func TestNode_GetString_Fail(t *testing.T) { 471 tests := []simpleNode{ 472 {"nil node", (*Node)(nil)}, 473 {"null node", NullNode("")}, 474 {"number node", NumberNode("", 123)}, 475 } 476 477 for _, tt := range tests { 478 t.Run(tt.name, func(t *testing.T) { 479 if _, err := tt.node.GetString(); err == nil { 480 t.Errorf("%s should be an error", tt.name) 481 } 482 }) 483 } 484 } 485 486 func TestNode_MustString(t *testing.T) { 487 tests := []struct { 488 name string 489 data []byte 490 }{ 491 {"foo", []byte(`"foo"`)}, 492 {"foo bar", []byte(`"foo bar"`)}, 493 {"", []byte(`""`)}, 494 {"안녕하세요", []byte(`"안녕하세요"`)}, 495 {"こんにちは", []byte(`"こんにちは"`)}, 496 {"你好", []byte(`"你好"`)}, 497 {"one \"encoded\" string", []byte(`"one \"encoded\" string"`)}, 498 } 499 500 for _, tt := range tests { 501 t.Run(tt.name, func(t *testing.T) { 502 root, err := Unmarshal(tt.data) 503 if err != nil { 504 t.Errorf("Error on Unmarshal(): %s", err) 505 } 506 507 value := root.MustString() 508 if value != tt.name { 509 t.Errorf("value is not matched. expected: %s, got: %s", tt.name, value) 510 } 511 }) 512 } 513 } 514 515 func TestUnmarshal_Array(t *testing.T) { 516 root, err := Unmarshal([]byte(" [1,[\"1\",[1,[1,2,3]]]]\r\n")) 517 if err != nil { 518 t.Errorf("Error on Unmarshal: %s", err.Error()) 519 } 520 521 if root == nil { 522 t.Errorf("Error on Unmarshal: root is nil") 523 } 524 525 if root.Type() != Array { 526 t.Errorf("Error on Unmarshal: wrong type") 527 } 528 529 array, err := root.GetArray() 530 if err != nil { 531 t.Errorf("error occurred while getting array, %s", err) 532 } else if len(array) != 2 { 533 t.Errorf("expected 2 elements, got %d", len(array)) 534 } else if val, err := array[0].GetNumeric(); err != nil { 535 t.Errorf("value of array[0] is not numeric. got: %v", array[0].value) 536 } else if val != 1 { 537 t.Errorf("Error on array[0].GetNumeric(): expected to be '1', got: %v", val) 538 } else if val, err := array[1].GetArray(); err != nil { 539 t.Errorf("error occurred while getting array, %s", err.Error()) 540 } else if len(val) != 2 { 541 t.Errorf("Error on array[1].GetArray(): expected 2 elements, got %d", len(val)) 542 } else if el, err := val[0].GetString(); err != nil { 543 t.Errorf("error occurred while getting string, %s", err.Error()) 544 } else if el != "1" { 545 t.Errorf("Error on val[0].GetString(): expected to be '1', got: %s", el) 546 } 547 } 548 549 var sampleArr = []byte(`[-1, 2, 3, 4, 5, 6]`) 550 551 func TestNode_GetArray(t *testing.T) { 552 root, err := Unmarshal(sampleArr) 553 if err != nil { 554 t.Errorf("Error on Unmarshal(): %s", err) 555 return 556 } 557 558 array, err := root.GetArray() 559 if err != nil { 560 t.Errorf("Error on root.GetArray(): %s", err) 561 } 562 563 if len(array) != 6 { 564 t.Errorf(ufmt.Sprintf("length is not matched. expected: 3, got: %d", len(array))) 565 } 566 567 for i, node := range array { 568 for j, val := range []int{-1, 2, 3, 4, 5, 6} { 569 if i == j { 570 if v, err := node.GetNumeric(); err != nil { 571 t.Errorf(ufmt.Sprintf("Error on node.GetNumeric(): %s", err)) 572 } else if v != float64(val) { 573 t.Errorf(ufmt.Sprintf("value is not matched. expected: %d, got: %v", val, v)) 574 } 575 } 576 } 577 } 578 } 579 580 func TestNode_GetArray_Fail(t *testing.T) { 581 tests := []simpleNode{ 582 {"nil node", (*Node)(nil)}, 583 {"null node", NullNode("")}, 584 {"number node", NumberNode("", 123)}, 585 } 586 587 for _, tt := range tests { 588 t.Run(tt.name, func(t *testing.T) { 589 if _, err := tt.node.GetArray(); err == nil { 590 t.Errorf("%s should be an error", tt.name) 591 } 592 }) 593 } 594 } 595 596 func TestNode_IsArray(t *testing.T) { 597 root, err := Unmarshal(sampleArr) 598 if err != nil { 599 t.Errorf("Error on Unmarshal(): %s", err) 600 return 601 } 602 603 if root.Type() != Array { 604 t.Errorf(ufmt.Sprintf("Must be an array. got: %s", root.Type().String())) 605 } 606 } 607 608 func TestNode_ArrayEach(t *testing.T) { 609 tests := []struct { 610 name string 611 json string 612 expected []int 613 }{ 614 { 615 name: "empty array", 616 json: `[]`, 617 expected: []int{}, 618 }, 619 { 620 name: "single element", 621 json: `[42]`, 622 expected: []int{42}, 623 }, 624 { 625 name: "multiple elements", 626 json: `[1, 2, 3, 4, 5]`, 627 expected: []int{1, 2, 3, 4, 5}, 628 }, 629 { 630 name: "multiple elements but all values are same", 631 json: `[1, 1, 1, 1, 1]`, 632 expected: []int{1, 1, 1, 1, 1}, 633 }, 634 { 635 name: "multiple elements with non-numeric values", 636 json: `["a", "b", "c", "d", "e"]`, 637 expected: []int{}, 638 }, 639 { 640 name: "non-array node", 641 json: `{"not": "an array"}`, 642 expected: []int{}, 643 }, 644 { 645 name: "array containing numeric and non-numeric elements", 646 json: `["1", 2, 3, "4", 5, "6"]`, 647 expected: []int{2, 3, 5}, 648 }, 649 } 650 651 for _, tc := range tests { 652 t.Run(tc.name, func(t *testing.T) { 653 root, err := Unmarshal([]byte(tc.json)) 654 if err != nil { 655 t.Fatalf("Unmarshal failed: %v", err) 656 } 657 658 var result []int // callback result 659 root.ArrayEach(func(index int, element *Node) { 660 if val, err := strconv.Atoi(element.String()); err == nil { 661 result = append(result, val) 662 } 663 }) 664 665 if len(result) != len(tc.expected) { 666 t.Errorf("%s: expected %d elements, got %d", tc.name, len(tc.expected), len(result)) 667 return 668 } 669 670 for i, val := range result { 671 if val != tc.expected[i] { 672 t.Errorf("%s: expected value at index %d to be %d, got %d", tc.name, i, tc.expected[i], val) 673 } 674 } 675 }) 676 } 677 } 678 679 func TestNode_Key(t *testing.T) { 680 root, err := Unmarshal([]byte(`{"foo": true, "bar": null, "baz": 123, "biz": [1,2,3]}`)) 681 if err != nil { 682 t.Errorf("Error on Unmarshal(): %s", err.Error()) 683 } 684 685 obj := root.MustObject() 686 for key, node := range obj { 687 if key != node.Key() { 688 t.Errorf("Key() = %v, want %v", node.Key(), key) 689 } 690 } 691 692 keys := []string{"foo", "bar", "baz", "biz"} 693 for _, key := range keys { 694 if obj[key].Key() != key { 695 t.Errorf("Key() = %v, want %v", obj[key].Key(), key) 696 } 697 } 698 699 // TODO: resolve stack overflow 700 // if root.MustKey("foo").Clone().Key() != "" { 701 // t.Errorf("wrong key found for cloned key") 702 // } 703 704 if (*Node)(nil).Key() != "" { 705 t.Errorf("wrong key found for nil node") 706 } 707 } 708 709 func TestNode_Size(t *testing.T) { 710 root, err := Unmarshal(sampleArr) 711 if err != nil { 712 t.Errorf("error occurred while unmarshal") 713 } 714 715 size := root.Size() 716 if size != 6 { 717 t.Errorf(ufmt.Sprintf("Size() must be 6. got: %v", size)) 718 } 719 720 if (*Node)(nil).Size() != 0 { 721 t.Errorf(ufmt.Sprintf("Size() must be 0. got: %v", (*Node)(nil).Size())) 722 } 723 } 724 725 func TestNode_Index(t *testing.T) { 726 root, err := Unmarshal([]byte(`[1, 2, 3, 4, 5, 6]`)) 727 if err != nil { 728 t.Error("error occurred while unmarshal") 729 } 730 731 arr := root.MustArray() 732 for i, node := range arr { 733 if i != node.Index() { 734 t.Errorf(ufmt.Sprintf("Index() must be nil. got: %v", i)) 735 } 736 } 737 } 738 739 func TestNode_Index_Fail(t *testing.T) { 740 tests := []struct { 741 name string 742 node *Node 743 want int 744 }{ 745 {"nil node", (*Node)(nil), -1}, 746 {"null node", NullNode(""), -1}, 747 {"object node", ObjectNode("", nil), -1}, 748 } 749 750 for _, tt := range tests { 751 t.Run(tt.name, func(t *testing.T) { 752 if got := tt.node.Index(); got != tt.want { 753 t.Errorf("Index() = %v, want %v", got, tt.want) 754 } 755 }) 756 } 757 } 758 759 func TestNode_GetIndex(t *testing.T) { 760 root := Must(Unmarshal([]byte(`[1, 2, 3, 4, 5, 6]`))) 761 expected := []int{1, 2, 3, 4, 5, 6} 762 763 if len(expected) != root.Size() { 764 t.Errorf("length is not matched. expected: %d, got: %d", len(expected), root.Size()) 765 } 766 767 // TODO: if length exceeds, stack overflow occurs. need to fix 768 for i, v := range expected { 769 val, err := root.GetIndex(i) 770 if err != nil { 771 t.Errorf("error occurred while getting index %d, %s", i, err) 772 } 773 774 if val.MustNumeric() != float64(v) { 775 t.Errorf("value is not matched. expected: %d, got: %v", v, val.MustNumeric()) 776 } 777 } 778 } 779 780 func TestNode_GetIndex_InputIndex_Exceed_Original_Node_Index(t *testing.T) { 781 root, err := Unmarshal([]byte(`[1, 2, 3, 4, 5, 6]`)) 782 if err != nil { 783 t.Errorf("error occurred while unmarshal") 784 } 785 786 _, err = root.GetIndex(10) 787 if err == nil { 788 t.Errorf("GetIndex should return error") 789 } 790 } 791 792 func TestNode_DeleteIndex(t *testing.T) { 793 tests := []struct { 794 name string 795 expected string 796 index int 797 ok bool 798 }{ 799 {`null`, ``, 0, false}, 800 {`1`, ``, 0, false}, 801 {`{}`, ``, 0, false}, 802 {`{"foo":"bar"}`, ``, 0, false}, 803 {`true`, ``, 0, false}, 804 {`[]`, ``, 0, false}, 805 {`[]`, ``, -1, false}, 806 {`[1]`, `[]`, 0, true}, 807 {`[{}]`, `[]`, 0, true}, 808 {`[{}, [], 42]`, `[{}, []]`, -1, true}, 809 {`[{}, [], 42]`, `[[], 42]`, 0, true}, 810 {`[{}, [], 42]`, `[{}, 42]`, 1, true}, 811 {`[{}, [], 42]`, `[{}, []]`, 2, true}, 812 {`[{}, [], 42]`, ``, 10, false}, 813 {`[{}, [], 42]`, ``, -10, false}, 814 } 815 816 for _, tt := range tests { 817 t.Run(tt.name, func(t *testing.T) { 818 root := Must(Unmarshal([]byte(tt.name))) 819 err := root.DeleteIndex(tt.index) 820 if err != nil && tt.ok { 821 t.Errorf("DeleteIndex returns error: %v", err) 822 } 823 }) 824 } 825 } 826 827 func TestNode_GetKey(t *testing.T) { 828 root, err := Unmarshal([]byte(`{"foo": true, "bar": null}`)) 829 if err != nil { 830 t.Error("error occurred while unmarshal") 831 } 832 833 value, err := root.GetKey("foo") 834 if err != nil { 835 t.Errorf("error occurred while getting key, %s", err) 836 } 837 838 if value.MustBool() != true { 839 t.Errorf("value is not matched. expected: true, got: %v", value.MustBool()) 840 } 841 842 value, err = root.GetKey("bar") 843 if err != nil { 844 t.Errorf("error occurred while getting key, %s", err) 845 } 846 847 _, err = root.GetKey("baz") 848 if err == nil { 849 t.Errorf("key baz is not exist. must be failed") 850 } 851 852 if value.MustNull() != nil { 853 t.Errorf("value is not matched. expected: nil, got: %v", value.MustNull()) 854 } 855 } 856 857 func TestNode_GetKey_Fail(t *testing.T) { 858 tests := []simpleNode{ 859 {"nil node", (*Node)(nil)}, 860 {"null node", NullNode("")}, 861 } 862 863 for _, tt := range tests { 864 t.Run(tt.name, func(t *testing.T) { 865 if _, err := tt.node.GetKey(""); err == nil { 866 t.Errorf("%s should be an error", tt.name) 867 } 868 }) 869 } 870 } 871 872 func TestNode_GetUniqueKeyList(t *testing.T) { 873 tests := []struct { 874 name string 875 json string 876 expected []string 877 }{ 878 { 879 name: "simple foo/bar", 880 json: `{"foo": true, "bar": null}`, 881 expected: []string{"foo", "bar"}, 882 }, 883 { 884 name: "empty object", 885 json: `{}`, 886 expected: []string{}, 887 }, 888 { 889 name: "nested object", 890 json: `{ 891 "outer": { 892 "inner": { 893 "key": "value" 894 }, 895 "array": [1, 2, 3] 896 }, 897 "another": "item" 898 }`, 899 expected: []string{"outer", "inner", "key", "array", "another"}, 900 }, 901 { 902 name: "complex object", 903 json: `{ 904 "Image": { 905 "Width": 800, 906 "Height": 600, 907 "Title": "View from 15th Floor", 908 "Thumbnail": { 909 "Url": "http://www.example.com/image/481989943", 910 "Height": 125, 911 "Width": 100 912 }, 913 "Animated": false, 914 "IDs": [116, 943, 234, 38793] 915 } 916 }`, 917 expected: []string{"Image", "Width", "Height", "Title", "Thumbnail", "Url", "Animated", "IDs"}, 918 }, 919 } 920 921 for _, tt := range tests { 922 t.Run(tt.name, func(t *testing.T) { 923 root, err := Unmarshal([]byte(tt.json)) 924 if err != nil { 925 t.Errorf("error occurred while unmarshal") 926 } 927 928 value := root.UniqueKeyLists() 929 if len(value) != len(tt.expected) { 930 t.Errorf("%s length must be %v. got: %v. retrieved keys: %s", tt.name, len(tt.expected), len(value), value) 931 } 932 933 for _, key := range value { 934 if !contains(tt.expected, key) { 935 t.Errorf("EachKey() must be in %v. got: %v", tt.expected, key) 936 } 937 } 938 }) 939 } 940 } 941 942 // TODO: resolve stack overflow 943 func TestNode_IsEmpty(t *testing.T) { 944 tests := []struct { 945 name string 946 node *Node 947 expected bool 948 }{ 949 {"nil node", (*Node)(nil), false}, // nil node is not empty. 950 // {"null node", NullNode(""), true}, 951 {"empty object", ObjectNode("", nil), true}, 952 {"empty array", ArrayNode("", nil), true}, 953 {"non-empty object", ObjectNode("", map[string]*Node{"foo": BoolNode("foo", true)}), false}, 954 {"non-empty array", ArrayNode("", []*Node{BoolNode("0", true)}), false}, 955 } 956 957 for _, tt := range tests { 958 t.Run(tt.name, func(t *testing.T) { 959 if got := tt.node.Empty(); got != tt.expected { 960 t.Errorf("%s = %v, want %v", tt.name, got, tt.expected) 961 } 962 }) 963 } 964 } 965 966 func TestNode_Index_EmptyList(t *testing.T) { 967 root, err := Unmarshal([]byte(`[]`)) 968 if err != nil { 969 t.Errorf("error occurred while unmarshal") 970 } 971 972 array := root.MustArray() 973 for i, node := range array { 974 if i != node.Index() { 975 t.Errorf(ufmt.Sprintf("Index() must be nil. got: %v", i)) 976 } 977 } 978 } 979 980 func TestNode_GetObject(t *testing.T) { 981 root, err := Unmarshal([]byte(`{"foo": true,"bar": null}`)) 982 if err != nil { 983 t.Errorf("Error on Unmarshal(): %s", err.Error()) 984 return 985 } 986 987 value, err := root.GetObject() 988 if err != nil { 989 t.Errorf("Error on root.GetObject(): %s", err.Error()) 990 } 991 992 if _, ok := value["foo"]; !ok { 993 t.Errorf("root.GetObject() is corrupted: foo") 994 } 995 996 if _, ok := value["bar"]; !ok { 997 t.Errorf("root.GetObject() is corrupted: bar") 998 } 999 } 1000 1001 func TestNode_GetObject_Fail(t *testing.T) { 1002 tests := []simpleNode{ 1003 {"nil node", (*Node)(nil)}, 1004 {"get object from null node", NullNode("")}, 1005 {"not object node", NumberNode("", 123)}, 1006 } 1007 1008 for _, tt := range tests { 1009 t.Run(tt.name, func(t *testing.T) { 1010 if _, err := tt.node.GetObject(); err == nil { 1011 t.Errorf("%s should be an error", tt.name) 1012 } 1013 }) 1014 } 1015 } 1016 1017 func TestNode_ObjectEach(t *testing.T) { 1018 tests := []struct { 1019 name string 1020 json string 1021 expected map[string]int 1022 }{ 1023 { 1024 name: "empty object", 1025 json: `{}`, 1026 expected: make(map[string]int), 1027 }, 1028 { 1029 name: "single key-value pair", 1030 json: `{"key": 42}`, 1031 expected: map[string]int{"key": 42}, 1032 }, 1033 { 1034 name: "multiple key-value pairs", 1035 json: `{"one": 1, "two": 2, "three": 3}`, 1036 expected: map[string]int{"one": 1, "two": 2, "three": 3}, 1037 }, 1038 { 1039 name: "multiple key-value pairs with some non-numeric values", 1040 json: `{"one": 1, "two": "2", "three": 3, "four": "4"}`, 1041 expected: map[string]int{"one": 1, "three": 3}, 1042 }, 1043 { 1044 name: "non-object node", 1045 json: `["not", "an", "object"]`, 1046 expected: make(map[string]int), 1047 }, 1048 } 1049 1050 for _, tc := range tests { 1051 t.Run(tc.name, func(t *testing.T) { 1052 root, err := Unmarshal([]byte(tc.json)) 1053 if err != nil { 1054 t.Fatalf("Unmarshal failed: %v", err) 1055 } 1056 1057 result := make(map[string]int) 1058 root.ObjectEach(func(key string, value *Node) { 1059 // extract integer values from the object 1060 if val, err := strconv.Atoi(value.String()); err == nil { 1061 result[key] = val 1062 } 1063 }) 1064 1065 if len(result) != len(tc.expected) { 1066 t.Errorf("%s: expected %d key-value pairs, got %d", tc.name, len(tc.expected), len(result)) 1067 return 1068 } 1069 1070 for key, val := range tc.expected { 1071 if result[key] != val { 1072 t.Errorf("%s: expected value for key %s to be %d, got %d", tc.name, key, val, result[key]) 1073 } 1074 } 1075 }) 1076 } 1077 } 1078 1079 func TestNode_ExampleMust(t *testing.T) { 1080 data := []byte(`{ 1081 "Image": { 1082 "Width": 800, 1083 "Height": 600, 1084 "Title": "View from 15th Floor", 1085 "Thumbnail": { 1086 "Url": "http://www.example.com/image/481989943", 1087 "Height": 125, 1088 "Width": 100 1089 }, 1090 "Animated" : false, 1091 "IDs": [116, 943, 234, 38793] 1092 } 1093 }`) 1094 1095 root := Must(Unmarshal(data)) 1096 if root.Size() != 1 { 1097 t.Errorf("root.Size() must be 1. got: %v", root.Size()) 1098 } 1099 1100 ufmt.Sprintf("Object has %d inheritors inside", root.Size()) 1101 // Output: 1102 // Object has 1 inheritors inside 1103 } 1104 1105 // Calculate AVG price from different types of objects, JSON from: https://goessner.net/articles/JsonPath/index.html#e3 1106 func TestExampleUnmarshal(t *testing.T) { 1107 data := []byte(`{ "store": { 1108 "book": [ 1109 { "category": "reference", 1110 "author": "Nigel Rees", 1111 "title": "Sayings of the Century", 1112 "price": 8.95 1113 }, 1114 { "category": "fiction", 1115 "author": "Evelyn Waugh", 1116 "title": "Sword of Honour", 1117 "price": 12.99 1118 }, 1119 { "category": "fiction", 1120 "author": "Herman Melville", 1121 "title": "Moby Dick", 1122 "isbn": "0-553-21311-3", 1123 "price": 8.99 1124 }, 1125 { "category": "fiction", 1126 "author": "J. R. R. Tolkien", 1127 "title": "The Lord of the Rings", 1128 "isbn": "0-395-19395-8", 1129 "price": 22.99 1130 } 1131 ], 1132 "bicycle": { "color": "red", 1133 "price": 19.95 1134 }, 1135 "tools": null 1136 } 1137 }`) 1138 1139 root, err := Unmarshal(data) 1140 if err != nil { 1141 t.Errorf("error occurred when unmarshal") 1142 } 1143 1144 store := root.MustKey("store").MustObject() 1145 1146 var prices float64 1147 size := 0 1148 for _, objects := range store { 1149 if objects.IsArray() && objects.Size() > 0 { 1150 size += objects.Size() 1151 for _, object := range objects.MustArray() { 1152 prices += object.MustKey("price").MustNumeric() 1153 } 1154 } else if objects.IsObject() && objects.HasKey("price") { 1155 size++ 1156 prices += objects.MustKey("price").MustNumeric() 1157 } 1158 } 1159 1160 result := int(prices / float64(size)) 1161 ufmt.Sprintf("AVG price: %d", result) 1162 } 1163 1164 func TestNode_ExampleMust_panic(t *testing.T) { 1165 defer func() { 1166 if r := recover(); r == nil { 1167 t.Errorf("The code did not panic") 1168 } 1169 }() 1170 data := []byte(`{]`) 1171 root := Must(Unmarshal(data)) 1172 ufmt.Sprintf("Object has %d inheritors inside", root.Size()) 1173 } 1174 1175 func TestNode_Path(t *testing.T) { 1176 data := []byte(`{ 1177 "Image": { 1178 "Width": 800, 1179 "Height": 600, 1180 "Title": "View from 15th Floor", 1181 "Thumbnail": { 1182 "Url": "http://www.example.com/image/481989943", 1183 "Height": 125, 1184 "Width": 100 1185 }, 1186 "Animated" : false, 1187 "IDs": [116, 943, 234, 38793] 1188 } 1189 }`) 1190 1191 root, err := Unmarshal(data) 1192 if err != nil { 1193 t.Errorf("Error on Unmarshal(): %s", err.Error()) 1194 return 1195 } 1196 1197 if root.Path() != "$" { 1198 t.Errorf("Wrong root.Path()") 1199 } 1200 1201 element := root.MustKey("Image").MustKey("Thumbnail").MustKey("Url") 1202 if element.Path() != "$['Image']['Thumbnail']['Url']" { 1203 t.Errorf("Wrong path found: %s", element.Path()) 1204 } 1205 1206 if (*Node)(nil).Path() != "" { 1207 t.Errorf("Wrong (nil).Path()") 1208 } 1209 } 1210 1211 func TestNode_Path2(t *testing.T) { 1212 tests := []struct { 1213 name string 1214 node *Node 1215 want string 1216 }{ 1217 { 1218 name: "Node with key", 1219 node: &Node{ 1220 prev: &Node{}, 1221 key: func() *string { s := "key"; return &s }(), 1222 }, 1223 want: "$['key']", 1224 }, 1225 { 1226 name: "Node with index", 1227 node: &Node{ 1228 prev: &Node{}, 1229 index: func() *int { i := 1; return &i }(), 1230 }, 1231 want: "$[1]", 1232 }, 1233 } 1234 1235 for _, tt := range tests { 1236 t.Run(tt.name, func(t *testing.T) { 1237 if got := tt.node.Path(); got != tt.want { 1238 t.Errorf("Path() = %v, want %v", got, tt.want) 1239 } 1240 }) 1241 } 1242 } 1243 1244 func TestNode_Root(t *testing.T) { 1245 root := &Node{} 1246 child := &Node{prev: root} 1247 grandChild := &Node{prev: child} 1248 1249 tests := []struct { 1250 name string 1251 node *Node 1252 want *Node 1253 }{ 1254 { 1255 name: "Root node", 1256 node: root, 1257 want: root, 1258 }, 1259 { 1260 name: "Child node", 1261 node: child, 1262 want: root, 1263 }, 1264 { 1265 name: "Grandchild node", 1266 node: grandChild, 1267 want: root, 1268 }, 1269 { 1270 name: "Node is nil", 1271 node: nil, 1272 want: nil, 1273 }, 1274 } 1275 1276 for _, tt := range tests { 1277 t.Run(tt.name, func(t *testing.T) { 1278 if got := tt.node.root(); got != tt.want { 1279 t.Errorf("root() = %v, want %v", got, tt.want) 1280 } 1281 }) 1282 } 1283 } 1284 1285 func contains(slice []string, item string) bool { 1286 for _, a := range slice { 1287 if a == item { 1288 return true 1289 } 1290 } 1291 1292 return false 1293 } 1294 1295 // ignore the sequence of keys by ordering them. 1296 // need to avoid import encoding/json and reflect package. 1297 // because gno does not support them for now. 1298 // TODO: use encoding/json to compare the result after if possible in gno. 1299 func isSameObject(a, b string) bool { 1300 aPairs := strings.Split(strings.Trim(a, "{}"), ",") 1301 bPairs := strings.Split(strings.Trim(b, "{}"), ",") 1302 1303 aMap := make(map[string]string) 1304 bMap := make(map[string]string) 1305 for _, pair := range aPairs { 1306 kv := strings.Split(pair, ":") 1307 key := strings.Trim(kv[0], `"`) 1308 value := strings.Trim(kv[1], `"`) 1309 aMap[key] = value 1310 } 1311 for _, pair := range bPairs { 1312 kv := strings.Split(pair, ":") 1313 key := strings.Trim(kv[0], `"`) 1314 value := strings.Trim(kv[1], `"`) 1315 bMap[key] = value 1316 } 1317 1318 aKeys := make([]string, 0, len(aMap)) 1319 bKeys := make([]string, 0, len(bMap)) 1320 for k := range aMap { 1321 aKeys = append(aKeys, k) 1322 } 1323 1324 for k := range bMap { 1325 bKeys = append(bKeys, k) 1326 } 1327 1328 sort.Strings(aKeys) 1329 sort.Strings(bKeys) 1330 1331 if len(aKeys) != len(bKeys) { 1332 return false 1333 } 1334 1335 for i := range aKeys { 1336 if aKeys[i] != bKeys[i] { 1337 return false 1338 } 1339 1340 if aMap[aKeys[i]] != bMap[bKeys[i]] { 1341 return false 1342 } 1343 } 1344 1345 return true 1346 } 1347 1348 func compareNodes(n1, n2 *Node) bool { 1349 if n1 == nil || n2 == nil { 1350 return n1 == n2 1351 } 1352 1353 if n1.key != n2.key { 1354 return false 1355 } 1356 1357 if !bytes.Equal(n1.data, n2.data) { 1358 return false 1359 } 1360 1361 if n1.index != n2.index { 1362 return false 1363 } 1364 1365 if n1.borders != n2.borders { 1366 return false 1367 } 1368 1369 if n1.modified != n2.modified { 1370 return false 1371 } 1372 1373 if n1.nodeType != n2.nodeType { 1374 return false 1375 } 1376 1377 if !compareNodes(n1.prev, n2.prev) { 1378 return false 1379 } 1380 1381 if len(n1.next) != len(n2.next) { 1382 return false 1383 } 1384 1385 for k, v := range n1.next { 1386 if !compareNodes(v, n2.next[k]) { 1387 return false 1388 } 1389 } 1390 1391 return true 1392 }