PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/onbloc/json/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
onbloc / json
Files
24 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/onbloc/json/v0
gno
0.9

Files (24)

  • README.mdmarkdown
  • gnomod.tomltoml
  • buffer.gnogno
  • builder.gnogno
  • decode.gnogno
  • encode.gnogno
  • errors.gnogno
  • escape.gnogno
  • indent.gnogno
  • internal.gnogno
  • node.gnogno
  • parser.gnogno
  • path.gnogno
  • token.gnogno
  • buffer_test.gnogno
  • builder_test.gnogno
  • decode_test.gnogno
  • encode_test.gnogno
  • escape_test.gnogno
  • indent_test.gnogno
  • node_test.gnogno
  • parser_test.gnogno
  • path_test.gnogno
  • LICENSEother
  • node_test.gnogno
    1package json23import (4	"bytes"5	"sort"6	"strconv"7	"strings"8

    Functions

    not supported for pure packages by the node (vm/qfuncs)

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    "testing"
    9
    10 "gno.land/p/nt/ufmt/v0"
    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 Example_TestNode_Must() {
    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 ufmt.Printf("root.Size() must be 1. got: %v\n", root.Size())
    1098 return
    1099 }
    1100
    1101 ufmt.Printf("Object has %d inheritors inside\n", root.Size())
    1102 // Output:
    1103 // Object has 1 inheritors inside
    1104}
    1105
    1106// Calculate AVG price from different types of objects, JSON from: https://goessner.net/articles/JsonPath/index.html#e3
    1107func TestExampleUnmarshal(t *testing.T) {
    1108 data := []byte(`{ "store": {
    1109 "book": [
    1110 { "category": "reference",
    1111 "author": "Nigel Rees",
    1112 "title": "Sayings of the Century",
    1113 "price": 8.95
    1114 },
    1115 { "category": "fiction",
    1116 "author": "Evelyn Waugh",
    1117 "title": "Sword of Honour",
    1118 "price": 12.99
    1119 },
    1120 { "category": "fiction",
    1121 "author": "Herman Melville",
    1122 "title": "Moby Dick",
    1123 "isbn": "0-553-21311-3",
    1124 "price": 8.99
    1125 },
    1126 { "category": "fiction",
    1127 "author": "J. R. R. Tolkien",
    1128 "title": "The Lord of the Rings",
    1129 "isbn": "0-395-19395-8",
    1130 "price": 22.99
    1131 }
    1132 ],
    1133 "bicycle": { "color": "red",
    1134 "price": 19.95
    1135 },
    1136 "tools": null
    1137 }
    1138}`)
    1139
    1140 root, err := Unmarshal(data)
    1141 if err != nil {
    1142 t.Errorf("error occurred when unmarshal")
    1143 }
    1144
    1145 store := root.MustKey("store").MustObject()
    1146
    1147 var prices float64
    1148 size := 0
    1149 for _, objects := range store {
    1150 if objects.IsArray() && objects.Size() > 0 {
    1151 size += objects.Size()
    1152 for _, object := range objects.MustArray() {
    1153 prices += object.MustKey("price").MustNumeric()
    1154 }
    1155 } else if objects.IsObject() && objects.HasKey("price") {
    1156 size++
    1157 prices += objects.MustKey("price").MustNumeric()
    1158 }
    1159 }
    1160
    1161 result := int(prices / float64(size))
    1162 ufmt.Sprintf("AVG price: %d", result)
    1163}
    1164
    1165func TestNode_ExampleMust_panic(t *testing.T) {
    1166 defer func() {
    1167 if r := recover(); r == nil {
    1168 t.Errorf("The code did not panic")
    1169 }
    1170 }()
    1171 data := []byte(`{]`)
    1172 root := Must(Unmarshal(data))
    1173 ufmt.Sprintf("Object has %d inheritors inside", root.Size())
    1174}
    1175
    1176func TestNode_Path(t *testing.T) {
    1177 data := []byte(`{
    1178 "Image": {
    1179 "Width": 800,
    1180 "Height": 600,
    1181 "Title": "View from 15th Floor",
    1182 "Thumbnail": {
    1183 "Url": "http://www.example.com/image/481989943",
    1184 "Height": 125,
    1185 "Width": 100
    1186 },
    1187 "Animated" : false,
    1188 "IDs": [116, 943, 234, 38793]
    1189 }
    1190 }`)
    1191
    1192 root, err := Unmarshal(data)
    1193 if err != nil {
    1194 t.Errorf("Error on Unmarshal(): %s", err.Error())
    1195 return
    1196 }
    1197
    1198 if root.Path() != "$" {
    1199 t.Errorf("Wrong root.Path()")
    1200 }
    1201
    1202 element := root.MustKey("Image").MustKey("Thumbnail").MustKey("Url")
    1203 if element.Path() != "$['Image']['Thumbnail']['Url']" {
    1204 t.Errorf("Wrong path found: %s", element.Path())
    1205 }
    1206
    1207 if (*Node)(nil).Path() != "" {
    1208 t.Errorf("Wrong (nil).Path()")
    1209 }
    1210}
    1211
    1212func TestNode_Path2(t *testing.T) {
    1213 tests := []struct {
    1214 name string
    1215 node *Node
    1216 want string
    1217 }{
    1218 {
    1219 name: "Node with key",
    1220 node: &Node{
    1221 prev: &Node{},
    1222 key: func() *string { s := "key"; return &s }(),
    1223 },
    1224 want: "$['key']",
    1225 },
    1226 {
    1227 name: "Node with index",
    1228 node: &Node{
    1229 prev: &Node{},
    1230 index: func() *int { i := 1; return &i }(),
    1231 },
    1232 want: "$[1]",
    1233 },
    1234 }
    1235
    1236 for _, tt := range tests {
    1237 t.Run(tt.name, func(t *testing.T) {
    1238 if got := tt.node.Path(); got != tt.want {
    1239 t.Errorf("Path() = %v, want %v", got, tt.want)
    1240 }
    1241 })
    1242 }
    1243}
    1244
    1245func TestNode_Root(t *testing.T) {
    1246 root := &Node{}
    1247 child := &Node{prev: root}
    1248 grandChild := &Node{prev: child}
    1249
    1250 tests := []struct {
    1251 name string
    1252 node *Node
    1253 want *Node
    1254 }{
    1255 {
    1256 name: "Root node",
    1257 node: root,
    1258 want: root,
    1259 },
    1260 {
    1261 name: "Child node",
    1262 node: child,
    1263 want: root,
    1264 },
    1265 {
    1266 name: "Grandchild node",
    1267 node: grandChild,
    1268 want: root,
    1269 },
    1270 {
    1271 name: "Node is nil",
    1272 node: nil,
    1273 want: nil,
    1274 },
    1275 }
    1276
    1277 for _, tt := range tests {
    1278 t.Run(tt.name, func(t *testing.T) {
    1279 if got := tt.node.root(); got != tt.want {
    1280 t.Errorf("root() = %v, want %v", got, tt.want)
    1281 }
    1282 })
    1283 }
    1284}
    1285
    1286func contains(slice []string, item string) bool {
    1287 for _, a := range slice {
    1288 if a == item {
    1289 return true
    1290 }
    1291 }
    1292
    1293 return false
    1294}
    1295
    1296// ignore the sequence of keys by ordering them.
    1297// need to avoid import encoding/json and reflect package.
    1298// because gno does not support them for now.
    1299// TODO: use encoding/json to compare the result after if possible in gno.
    1300func isSameObject(a, b string) bool {
    1301 aPairs := strings.Split(strings.Trim(a, "{}"), ",")
    1302 bPairs := strings.Split(strings.Trim(b, "{}"), ",")
    1303
    1304 aMap := make(map[string]string)
    1305 bMap := make(map[string]string)
    1306 for _, pair := range aPairs {
    1307 kv := strings.Split(pair, ":")
    1308 key := strings.Trim(kv[0], `"`)
    1309 value := strings.Trim(kv[1], `"`)
    1310 aMap[key] = value
    1311 }
    1312 for _, pair := range bPairs {
    1313 kv := strings.Split(pair, ":")
    1314 key := strings.Trim(kv[0], `"`)
    1315 value := strings.Trim(kv[1], `"`)
    1316 bMap[key] = value
    1317 }
    1318
    1319 aKeys := make([]string, 0, len(aMap))
    1320 bKeys := make([]string, 0, len(bMap))
    1321 for k := range aMap {
    1322 aKeys = append(aKeys, k)
    1323 }
    1324
    1325 for k := range bMap {
    1326 bKeys = append(bKeys, k)
    1327 }
    1328
    1329 sort.Strings(aKeys)
    1330 sort.Strings(bKeys)
    1331
    1332 if len(aKeys) != len(bKeys) {
    1333 return false
    1334 }
    1335
    1336 for i := range aKeys {
    1337 if aKeys[i] != bKeys[i] {
    1338 return false
    1339 }
    1340
    1341 if aMap[aKeys[i]] != bMap[bKeys[i]] {
    1342 return false
    1343 }
    1344 }
    1345
    1346 return true
    1347}
    1348
    1349func compareNodes(n1, n2 *Node) bool {
    1350 if n1 == nil || n2 == nil {
    1351 return n1 == n2
    1352 }
    1353
    1354 if n1.key != n2.key {
    1355 return false
    1356 }
    1357
    1358 if !bytes.Equal(n1.data, n2.data) {
    1359 return false
    1360 }
    1361
    1362 if n1.index != n2.index {
    1363 return false
    1364 }
    1365
    1366 if n1.borders != n2.borders {
    1367 return false
    1368 }
    1369
    1370 if n1.modified != n2.modified {
    1371 return false
    1372 }
    1373
    1374 if n1.nodeType != n2.nodeType {
    1375 return false
    1376 }
    1377
    1378 if !compareNodes(n1.prev, n2.prev) {
    1379 return false
    1380 }
    1381
    1382 if len(n1.next) != len(n2.next) {
    1383 return false
    1384 }
    1385
    1386 for k, v := range n1.next {
    1387 if !compareNodes(v, n2.next[k]) {
    1388 return false
    1389 }
    1390 }
    1391
    1392 return true
    1393}
    1394