node_test.gno

31.81 Kb ยท 1392 lines
   1package json
   2
   3import (
   4	"bytes"
   5	"sort"
   6	"strconv"
   7	"strings"
   8	"testing"
   9
  10	"gno.land/p/demo/ufmt"
  11)
  12
  13var (
  14	nilKey   *string
  15	dummyKey = "key"
  16)
  17
  18type _args struct {
  19	prev *Node
  20	buf  *buffer
  21	typ  ValueType
  22	key  **string
  23}
  24
  25type simpleNode struct {
  26	name string
  27	node *Node
  28}
  29
  30func 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
  83func TestNode_Value(t *testing.T) {
  84	tests := []struct {
  85		name        string
  86		data        []byte
  87		_type       ValueType
  88		expected    any
  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
 129func 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
 163func 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
 184func 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
 216func 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
 237func 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
 271func 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
 288func TestNode_GetBool_NotSucceed(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
 303func 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
 318func 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
 342var nullJson = []byte(`null`)
 343
 344func 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
 360func TestNode_GetNull_NotSucceed(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
 375func 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
 387func 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
 404func 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
 421func 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
 438func TestNode_GetNumeric_NotSucceed(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
 454func 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
 470func TestNode_GetString_NotSucceed(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
 486func 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
 515func 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
 549var sampleArr = []byte(`[-1, 2, 3, 4, 5, 6]`)
 550
 551func 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
 580func TestNode_GetArray_NotSucceed(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
 596func 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
 608func 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
 679func 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
 709func 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
 725func 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
 739func TestNode_Index_NotSucceed(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
 759func 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
 780func 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
 792func 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
 827func 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
 857func TestNode_GetKey_NotSucceed(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
 872func 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
 943func 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
 966func 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
 980func 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
1001func TestNode_GetObject_NotSucceed(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
1017func 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
1079func 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
1106func 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
1164func 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
1175func 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
1211func 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
1244func 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
1285func 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.
1299func 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
1348func 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}