github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/ast/node_test.go (about)

     1  /*
     2   * Copyright 2021 ByteDance Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package ast
    18  
    19  import (
    20      `bytes`
    21      `encoding/json`
    22      `errors`
    23      `fmt`
    24      `reflect`
    25      `strconv`
    26      `testing`
    27  
    28      `github.com/bytedance/sonic/internal/native/types`
    29      `github.com/bytedance/sonic/internal/rt`
    30      `github.com/stretchr/testify/assert`
    31      `github.com/stretchr/testify/require`
    32  )
    33  
    34  func TestNodeSortKeys(t *testing.T) {
    35      var src = `{"b":1,"a":2,"c":3}`
    36      root, err := NewSearcher(src).GetByPath()
    37      if err != nil {
    38          t.Fatal(err)
    39      }
    40      obj, err := root.MapUseNumber()
    41      if err != nil {
    42          t.Fatal(err)
    43      }
    44      exp, err := json.Marshal(obj)
    45      if err != nil {
    46          t.Fatal(err)
    47      }
    48      if err := root.SortKeys(true); err != nil {
    49          t.Fatal(err)
    50      }
    51      act, err := root.MarshalJSON()
    52      if err != nil {
    53          t.Fatal(err)
    54      }
    55      assert.Equal(t, len(exp), len(act))
    56      assert.Equal(t, string(exp), string(act))
    57  
    58      src = `[[1], {"b":1,"a":2,"c":3}, [], {}, [{"b":1,"a":2,"c":3,"d":[],"e":{}}]]`
    59      root, err = NewSearcher(src).GetByPath()
    60      if err != nil {
    61          t.Fatal(err)
    62      }
    63      vv, err := root.Interface()
    64      if err != nil {
    65          t.Fatal(err)
    66      }
    67      exp, err = json.Marshal(vv)
    68      if err != nil {
    69          t.Fatal(err)
    70      }
    71      if err := root.SortKeys(true); err != nil {
    72          t.Fatal(err)
    73      }
    74      act, err = root.MarshalJSON()
    75      if err != nil {
    76          t.Fatal(err)
    77      }
    78      assert.Equal(t, string(exp), string(act))
    79  
    80  }
    81  
    82  func BenchmarkNodeSortKeys(b *testing.B) {
    83      root, err := NewSearcher(_TwitterJson).GetByPath()
    84      if err != nil {
    85          b.Fatal(err)
    86      }
    87      // if err := root.LoadAll(); err != nil {
    88      //     b.Fatal(err)
    89      // }
    90  
    91      b.Run("single", func(b *testing.B) {
    92          r := root.Get("statuses")
    93          if r.Check() != nil {
    94              b.Fatal(r.Error())
    95          }
    96          b.SetBytes(int64(len(_TwitterJson)))
    97          b.ResetTimer()
    98          for i := 0; i < b.N; i++ {
    99              _ = root.SortKeys(false)
   100          }
   101      })
   102      b.Run("recurse", func(b *testing.B) {
   103          b.SetBytes(int64(len(_TwitterJson)))
   104          b.ResetTimer()
   105          for i := 0; i < b.N; i++ {
   106              _ = root.SortKeys(true)
   107          }
   108      })
   109  }
   110  
   111  func TestNodeSortKeys2(t *testing.T) {
   112      root, err := NewSearcher(_TwitterJson).GetByPath()
   113      if err != nil {
   114          t.Fatal(err)
   115      }
   116      // if err := root.LoadAll(); err != nil {
   117      //     b.Fatal(err)
   118      // }
   119      t.Run("single", func(t *testing.T) {
   120          r := root.Get("statuses")
   121          if r.Check() != nil {
   122              t.Fatal(r.Error())
   123          }
   124          require.NoError(t, root.SortKeys(false))
   125      })
   126      t.Run("recurse", func(t *testing.T) {
   127          require.NoError(t, root.SortKeys(true))
   128      })
   129  }
   130  //go:noinline
   131  func stackObj() interface{} {
   132      var a int = 1
   133      return rt.UnpackEface(a).Pack()
   134  }
   135  
   136  func TestLoadAll(t *testing.T) {
   137      e := Node{}
   138      err := e.Load()
   139      if err != nil {
   140          t.Fatal(err)
   141      }
   142      err = e.LoadAll()
   143      if err != nil {
   144          t.Fatal(err)
   145      }
   146  
   147      root, err := NewSearcher(`{"a":{"1":[1],"2":2},"b":[{"1":1},2],"c":[1,2]}`).GetByPath()
   148      if err != nil {
   149          t.Fatal(err)
   150      }
   151      if err = root.Load(); err != nil {
   152          t.Fatal(err)
   153      }
   154      if root.len() != 3 {
   155          t.Fatal(root.len())
   156      }
   157  
   158      c := root.Get("c")
   159      if !c.IsRaw() {
   160          t.Fatal(err)
   161      }
   162      err = c.LoadAll()
   163      if err != nil {
   164          t.Fatal(err)
   165      }
   166      if c.len() != 2 {
   167          t.Fatal(c.len())
   168      }
   169      c1 := c.nodeAt(0)
   170      if n, err := c1.Int64(); err != nil || n != 1 {
   171          t.Fatal(n, err)
   172      }
   173  
   174      a := root.pairAt(0)
   175      if a.Key != "a" {
   176          t.Fatal(a.Key)
   177      } else if !a.Value.IsRaw() {
   178          t.Fatal(a.Value.itype())
   179      } else if n, err := a.Value.Len(); n != 0 || err != nil {
   180          t.Fatal(n, err)
   181      }
   182      if err := a.Value.Load(); err != nil {
   183          t.Fatal(err)
   184      }
   185      if a.Value.len() != 2 {
   186          t.Fatal(a.Value.len())
   187      }
   188      a1 := a.Value.Get("1")
   189      if !a1.IsRaw() {
   190          t.Fatal(a1)
   191      }
   192      a.Value.LoadAll()
   193      if a1.t != types.V_ARRAY || a1.len() != 1 {
   194          t.Fatal(a1.t, a1.len())
   195      }
   196  
   197      b := root.pairAt(1)
   198      if b.Key != "b" {
   199          t.Fatal(b.Key)
   200      } else if !b.Value.IsRaw() {
   201          t.Fatal(b.Value.itype())
   202      } else if n, err := b.Value.Len(); n != 0 || err != nil {
   203          t.Fatal(n, err)
   204      }
   205      if err := b.Value.Load(); err != nil {
   206          t.Fatal(err)
   207      }
   208      if b.Value.len() != 2 {
   209          t.Fatal(b.Value.len())
   210      }
   211      b1 := b.Value.Index(0)
   212      if !b1.IsRaw() {
   213          t.Fatal(b1)
   214      }
   215      b.Value.LoadAll()
   216      if b1.t != types.V_OBJECT || b1.len() != 1 {
   217          t.Fatal(a1.t, a1.len())
   218      }
   219  }
   220  
   221  func TestIndexPair(t *testing.T) {
   222      root, _ := NewParser(`{"a":1,"b":2}`).Parse()
   223      a := root.IndexPair(0)
   224      if a == nil || a.Key != "a" {
   225          t.Fatal(a)
   226      }
   227      b := root.IndexPair(1)
   228      if b == nil || b.Key != "b" {
   229          t.Fatal(b)
   230      }
   231      c := root.IndexPair(2)
   232      if c != nil {
   233          t.Fatal(c)
   234      }
   235  }
   236  
   237  func TestIndexOrGet(t *testing.T) {
   238      root, _ := NewParser(`{"a":1,"b":2}`).Parse()
   239      a := root.IndexOrGet(0, "a")
   240      if v, err := a.Int64(); err != nil || v != int64(1) {
   241          t.Fatal(a)
   242      }
   243      a = root.IndexOrGet(0, "b")
   244      if v, err := a.Int64(); err != nil || v != int64(2) {
   245          t.Fatal(a)
   246      }
   247      a = root.IndexOrGet(0, "c")
   248      if a.Valid() {
   249          t.Fatal(a)
   250      }
   251  }
   252  
   253  func TestIndexOrGetWithIdx(t *testing.T) {
   254      root, _ := NewParser(`{"a":1,"b":2}`).Parse()
   255      b, idx := root.IndexOrGetWithIdx(0, "b")
   256      if v, err := b.Int64(); err != nil || v != int64(2) {
   257          t.Fatal(b, idx)
   258      }
   259      if idx != 1 {
   260          t.Fatal(b, idx)
   261      }
   262  }
   263  
   264  func TestTypeCast(t *testing.T) {
   265      type tcase struct {
   266          method string
   267          node   Node
   268          exp    interface{}
   269          err    error
   270      }
   271      var nonEmptyErr error = errors.New("")
   272      a1 := NewAny(1)
   273      lazyArray, _ := NewParser("[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]").Parse()
   274      lazyObject, _ := NewParser(`{"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16}`).Parse()
   275      var cases = []tcase{
   276          {"Interface", Node{}, interface{}(nil), ErrUnsupportType},
   277          {"Interface", NewAny(NewNumber("1")), float64(1), nil},
   278          {"Interface", NewAny(int64(1)), int64(1), nil},
   279          {"Interface", NewNumber("1"), float64(1), nil},
   280          {"InterfaceUseNode", Node{}, Node{}, nil},
   281          {"InterfaceUseNode", a1, a1, nil},
   282          {"InterfaceUseNode", NewNumber("1"), NewNumber("1"), nil},
   283          {"InterfaceUseNumber", Node{}, interface{}(nil), ErrUnsupportType},
   284          {"InterfaceUseNumber", NewAny(1), 1, nil},
   285          {"InterfaceUseNumber", NewNumber("1"), json.Number("1"), nil},
   286          {"Map", Node{}, map[string]interface{}(nil), ErrUnsupportType},
   287          {"Map", NewAny(map[string]Node{"a": NewNumber("1")}), map[string]interface{}(nil), ErrUnsupportType},
   288          {"Map", NewAny(map[string]interface{}{"a": 1}), map[string]interface{}{"a": 1}, nil},
   289          {"Map", NewObject([]Pair{{"a", NewNumber("1")}}), map[string]interface{}{"a": float64(1.0)}, nil},
   290          {"MapUseNode", Node{}, map[string]Node(nil), ErrUnsupportType},
   291          {"MapUseNode", NewAny(map[string]interface{}{"a": 1}), map[string]Node(nil), ErrUnsupportType},
   292          {"MapUseNode", NewAny(map[string]Node{"a": NewNumber("1")}), map[string]Node{"a": NewNumber("1")}, nil},
   293          {"MapUseNode", NewObject([]Pair{{"a", NewNumber("1")}}), map[string]Node{"a": NewNumber("1")}, nil},
   294          {"MapUseNumber", Node{}, map[string]interface{}(nil), ErrUnsupportType},
   295          {"MapUseNumber", NewAny(map[string]interface{}{"a": 1}), map[string]interface{}{"a": 1}, nil},
   296          {"MapUseNumber", NewObject([]Pair{{"a", NewNumber("1")}}), map[string]interface{}{"a": json.Number("1")}, nil},
   297          {"Array", Node{}, []interface{}(nil), ErrUnsupportType},
   298          {"Array", NewAny([]interface{}{1}), []interface{}{1}, nil},
   299          {"Array", NewArray([]Node{NewNumber("1")}), []interface{}{float64(1.0)}, nil},
   300          {"ArrayUseNode", Node{}, []Node(nil), ErrUnsupportType},
   301          {"ArrayUseNode", NewAny([]interface{}{1}), []Node(nil), ErrUnsupportType},
   302          {"ArrayUseNode", NewAny([]Node{NewNumber("1")}), []Node{NewNumber("1")}, nil},
   303          {"ArrayUseNode", NewArray([]Node{NewNumber("1")}), []Node{NewNumber("1")}, nil},
   304          {"ArrayUseNumber", Node{}, []interface{}(nil), ErrUnsupportType},
   305          {"ArrayUseNumber", NewAny([]interface{}{1}), []interface{}{1}, nil},
   306          {"ArrayUseNumber", NewAny([]Node{NewNumber("1")}), []interface{}(nil), ErrUnsupportType},
   307          {"ArrayUseNumber", NewArray([]Node{NewNumber("1")}), []interface{}{json.Number("1")}, nil},
   308          {"Raw", Node{}, "", ErrNotExist},
   309          {"Raw", NewRaw(" "), "", nonEmptyErr},
   310          {"Raw", NewRaw(" [ ] "), "[ ]", nil},
   311          {"Raw", NewRaw("[ ]"), "[ ]", nil},
   312          {"Raw", NewRaw(` { "a" : [ true, -1.2e34 ] } `), `{ "a" : [ true, -1.2e34 ] }`, nil},
   313          {"Raw", NewRaw(` { "a" : [ true, -1.2e34 ] `), "", nonEmptyErr},
   314          {"Raw", NewRaw(` { "a" : [ true, -1.2e34 }`), "", nonEmptyErr},
   315          {"Raw", NewBool(true), "true", nil},
   316          {"Raw", NewNumber("-0.0"), "-0.0", nil},
   317          {"Raw", NewString(""), `""`, nil},
   318          {"Raw", NewBytes([]byte("hello, world")), `"aGVsbG8sIHdvcmxk"`, nil},
   319          {"Bool", Node{}, false, ErrUnsupportType},
   320          {"Bool", NewAny(true), true, nil},
   321          {"Bool", NewAny(false), false, nil},
   322          {"Bool", NewAny(int(0)), false, nil},
   323          {"Bool", NewAny(int8(1)), true, nil},
   324          {"Bool", NewAny(int16(1)), true, nil},
   325          {"Bool", NewAny(int32(1)), true, nil},
   326          {"Bool", NewAny(int64(1)), true, nil},
   327          {"Bool", NewAny(uint(1)), true, nil},
   328          {"Bool", NewAny(uint16(1)), true, nil},
   329          {"Bool", NewAny(uint32(1)), true, nil},
   330          {"Bool", NewAny(uint64(1)), true, nil},
   331          {"Bool", NewAny(float64(0)), false, nil},
   332          {"Bool", NewAny(float32(1)), true, nil},
   333          {"Bool", NewAny(float64(1)), true, nil},
   334          {"Bool", NewAny(json.Number("0")), false, nil},
   335          {"Bool", NewAny(json.Number("1")), true, nil},
   336          {"Bool", NewAny(json.Number("1.1")), true, nil},
   337          {"Bool", NewAny(json.Number("+x1.1")), false, nonEmptyErr},
   338          {"Bool", NewAny(string("0")), false, nil},
   339          {"Bool", NewAny(string("t")), true, nil},
   340          {"Bool", NewAny([]byte{0}), false, nonEmptyErr},
   341          {"Bool", NewRaw("true"), true, nil},
   342          {"Bool", NewRaw("false"), false, nil},
   343          {"Bool", NewRaw("null"), false, nil},
   344          {"Bool", NewString(`true`), true, nil},
   345          {"Bool", NewString(`false`), false, nil},
   346          {"Bool", NewString(``), false, nonEmptyErr},
   347          {"Bool", NewNumber("2"), true, nil},
   348          {"Bool", NewNumber("-2.1"), true, nil},
   349          {"Bool", NewNumber("-x-2.1"), false, nonEmptyErr},
   350          {"Int64", NewRaw("true"), int64(1), nil},
   351          {"Int64", NewRaw("false"), int64(0), nil},
   352          {"Int64", NewRaw("\"1\""), int64(1), nil},
   353          {"Int64", NewRaw("\"1.1\""), int64(1), nil},
   354          {"Int64", NewRaw("\"1.0\""), int64(1), nil},
   355          {"Int64", NewNumber("+x.0"), int64(0), nonEmptyErr},
   356          {"Int64", NewAny(false), int64(0), nil},
   357          {"Int64", NewAny(true), int64(1), nil},
   358          {"Int64", NewAny(int(1)), int64(1), nil},
   359          {"Int64", NewAny(int8(1)), int64(1), nil},
   360          {"Int64", NewAny(int16(1)), int64(1), nil},
   361          {"Int64", NewAny(int32(1)), int64(1), nil},
   362          {"Int64", NewAny(int64(1)), int64(1), nil},
   363          {"Int64", NewAny(uint(1)), int64(1), nil},
   364          {"Int64", NewAny(uint8(1)), int64(1), nil},
   365          {"Int64", NewAny(uint32(1)), int64(1), nil},
   366          {"Int64", NewAny(uint64(1)), int64(1), nil},
   367          {"Int64", NewAny(float32(1)), int64(1), nil},
   368          {"Int64", NewAny(float64(1)), int64(1), nil},
   369          {"Int64", NewAny("1"), int64(1), nil},
   370          {"Int64", NewAny("1.1"), int64(1), nil},
   371          {"Int64", NewAny("+1x.1"), int64(0), nonEmptyErr},
   372          {"Int64", NewAny(json.Number("1")), int64(1), nil},
   373          {"Int64", NewAny(json.Number("1.1")), int64(1), nil},
   374          {"Int64", NewAny(json.Number("+1x.1")), int64(0), nonEmptyErr},
   375          {"Int64", NewAny([]byte{0}), int64(0), ErrUnsupportType},
   376          {"Int64", Node{}, int64(0), ErrUnsupportType},
   377          {"Int64", NewRaw("0"), int64(0), nil},
   378          {"Int64", NewRaw("null"), int64(0), nil},
   379          {"StrictInt64", NewRaw("true"), int64(0), ErrUnsupportType},
   380          {"StrictInt64", NewRaw("false"), int64(0), ErrUnsupportType},
   381          {"StrictInt64", NewAny(int(0)), int64(0), nil},
   382          {"StrictInt64", NewAny(int8(0)), int64(0), nil},
   383          {"StrictInt64", NewAny(int16(0)), int64(0), nil},
   384          {"StrictInt64", NewAny(int32(0)), int64(0), nil},
   385          {"StrictInt64", NewAny(int64(0)), int64(0), nil},
   386          {"StrictInt64", NewAny(uint(0)), int64(0), nil},
   387          {"StrictInt64", NewAny(uint8(0)), int64(0), nil},
   388          {"StrictInt64", NewAny(uint32(0)), int64(0), nil},
   389          {"StrictInt64", NewAny(uint64(0)), int64(0), nil},
   390          {"StrictInt64", Node{}, int64(0), ErrUnsupportType},
   391          {"StrictInt64", NewRaw("0"), int64(0), nil},
   392          {"StrictInt64", NewRaw("null"), int64(0), ErrUnsupportType},
   393          {"Float64", NewRaw("true"), float64(1), nil},
   394          {"Float64", NewRaw("false"), float64(0), nil},
   395          {"Float64", NewRaw("\"1.0\""), float64(1.0), nil},
   396          {"Float64", NewRaw("\"xx\""), float64(0), nonEmptyErr},
   397          {"Float64", Node{}, float64(0), ErrUnsupportType},
   398          {"Float64", NewAny(false), float64(0), nil},
   399          {"Float64", NewAny(true), float64(1), nil},
   400          {"Float64", NewAny(int(1)), float64(1), nil},
   401          {"Float64", NewAny(int8(1)), float64(1), nil},
   402          {"Float64", NewAny(int16(1)), float64(1), nil},
   403          {"Float64", NewAny(int32(1)), float64(1), nil},
   404          {"Float64", NewAny(int64(1)), float64(1), nil},
   405          {"Float64", NewAny(uint(1)), float64(1), nil},
   406          {"Float64", NewAny(uint8(1)), float64(1), nil},
   407          {"Float64", NewAny(uint32(1)), float64(1), nil},
   408          {"Float64", NewAny(uint64(1)), float64(1), nil},
   409          {"Float64", NewAny(float32(1)), float64(1), nil},
   410          {"Float64", NewAny(float64(1)), float64(1), nil},
   411          {"Float64", NewAny("1.1"), float64(1.1), nil},
   412          {"Float64", NewAny("+1x.1"), float64(0), nonEmptyErr},
   413          {"Float64", NewAny(json.Number("0")), float64(0), nil},
   414          {"Float64", NewAny(json.Number("x")), float64(0), nonEmptyErr},
   415          {"Float64", NewAny([]byte{0}), float64(0), ErrUnsupportType},
   416          {"Float64", NewRaw("0.0"), float64(0.0), nil},
   417          {"Float64", NewRaw("1"), float64(1.0), nil},
   418          {"Float64", NewRaw("null"), float64(0.0), nil},
   419          {"StrictFloat64", NewRaw("true"), float64(0), ErrUnsupportType},
   420          {"StrictFloat64", NewRaw("false"), float64(0), ErrUnsupportType},
   421          {"StrictFloat64", Node{}, float64(0), ErrUnsupportType},
   422          {"StrictFloat64", NewAny(float32(0)), float64(0), nil},
   423          {"StrictFloat64", NewAny(float64(0)), float64(0), nil},
   424          {"StrictFloat64", NewRaw("0.0"), float64(0.0), nil},
   425          {"StrictFloat64", NewRaw("null"), float64(0.0), ErrUnsupportType},
   426          {"Number", Node{}, json.Number(""), ErrUnsupportType},
   427          {"Number", NewAny(false), json.Number("0"), nil},
   428          {"Number", NewAny(true), json.Number("1"), nil},
   429          {"Number", NewAny(int(1)), json.Number("1"), nil},
   430          {"Number", NewAny(int8(1)), json.Number("1"), nil},
   431          {"Number", NewAny(int16(1)), json.Number("1"), nil},
   432          {"Number", NewAny(int32(1)), json.Number("1"), nil},
   433          {"Number", NewAny(int64(1)), json.Number("1"), nil},
   434          {"Number", NewAny(uint(1)), json.Number("1"), nil},
   435          {"Number", NewAny(uint8(1)), json.Number("1"), nil},
   436          {"Number", NewAny(uint32(1)), json.Number("1"), nil},
   437          {"Number", NewAny(uint64(1)), json.Number("1"), nil},
   438          {"Number", NewAny(float32(1)), json.Number("1"), nil},
   439          {"Number", NewAny(float64(1)), json.Number("1"), nil},
   440          {"Number", NewAny("1.1"), json.Number("1.1"), nil},
   441          {"Number", NewAny("+1x.1"), json.Number(""), nonEmptyErr},
   442          {"Number", NewAny(json.Number("0")), json.Number("0"), nil},
   443          {"Number", NewAny(json.Number("x")), json.Number("x"), nil},
   444          {"Number", NewAny(json.Number("+1x.1")), json.Number("+1x.1"), nil},
   445          {"Number", NewAny([]byte{0}), json.Number(""), ErrUnsupportType},
   446          {"Number", NewRaw("x"), json.Number(""), nonEmptyErr},
   447          {"Number", NewRaw("0.0"), json.Number("0.0"), nil},
   448          {"Number", NewRaw("\"1\""), json.Number("1"), nil},
   449          {"Number", NewRaw("\"1.1\""), json.Number("1.1"), nil},
   450          {"Number", NewRaw("\"0.x0\""), json.Number(""), nonEmptyErr},
   451          {"Number", NewRaw("{]"), json.Number(""), nonEmptyErr},
   452          {"Number", NewRaw("true"), json.Number("1"), nil},
   453          {"Number", NewRaw("false"), json.Number("0"), nil},
   454          {"Number", NewRaw("null"), json.Number("0"), nil},
   455          {"StrictNumber", NewRaw("true"), json.Number(""), ErrUnsupportType},
   456          {"StrictNumber", NewRaw("false"), json.Number(""), ErrUnsupportType},
   457          {"StrictNumber", Node{}, json.Number(""), ErrUnsupportType},
   458          {"StrictNumber", NewAny(json.Number("0")), json.Number("0"), nil},
   459          {"StrictNumber", NewRaw("0.0"), json.Number("0.0"), nil},
   460          {"StrictNumber", NewRaw("null"), json.Number(""), ErrUnsupportType},
   461          {"String", Node{}, "", ErrUnsupportType},
   462          {"String", NewAny(`\u263a`), `\u263a`, nil},
   463          {"String", NewRaw(`"\u263a"`), `☺`, nil},
   464          {"String", NewString(`\u263a`), `\u263a`, nil},
   465          {"String", NewRaw(`0.0`), "0.0", nil},
   466          {"String", NewRaw(`true`), "true", nil},
   467          {"String", NewRaw(`false`), "false", nil},
   468          {"String", NewRaw(`null`), "", nil},
   469          {"String", NewAny(false), "false", nil},
   470          {"String", NewAny(true), "true", nil},
   471          {"String", NewAny(int(1)), "1", nil},
   472          {"String", NewAny(int8(1)), "1", nil},
   473          {"String", NewAny(int16(1)), "1", nil},
   474          {"String", NewAny(int32(1)), "1", nil},
   475          {"String", NewAny(int64(1)), "1", nil},
   476          {"String", NewAny(uint(1)), "1", nil},
   477          {"String", NewAny(uint8(1)), "1", nil},
   478          {"String", NewAny(uint32(1)), "1", nil},
   479          {"String", NewAny(uint64(1)), "1", nil},
   480          {"String", NewAny(float32(1)), "1", nil},
   481          {"String", NewAny(float64(1)), "1", nil},
   482          {"String", NewAny("1.1"), "1.1", nil},
   483          {"String", NewAny("+1x.1"), "+1x.1", nil},
   484          {"String", NewAny(json.Number("0")), ("0"), nil},
   485          {"String", NewAny(json.Number("x")), ("x"), nil},
   486          {"String", NewAny([]byte{0}), (""), ErrUnsupportType},
   487          {"StrictString", Node{}, "", ErrUnsupportType},
   488          {"StrictString", NewAny(`\u263a`), `\u263a`, nil},
   489          {"StrictString", NewRaw(`"\u263a"`), `☺`, nil},
   490          {"StrictString", NewString(`\u263a`), `\u263a`, nil},
   491          {"StrictString", NewRaw(`0.0`), "", ErrUnsupportType},
   492          {"StrictString", NewRaw(`true`), "", ErrUnsupportType},
   493          {"StrictString", NewRaw(`false`), "", ErrUnsupportType},
   494          {"StrictString", NewRaw(`null`), "", ErrUnsupportType},
   495          {"Len", Node{}, 0, nil},
   496          {"Len", NewAny(0), 0, ErrUnsupportType},
   497          {"Len", NewNull(), 0, nil},
   498          {"Len", NewRaw(`"1"`), 1, nil},
   499          {"Len", NewRaw(`[1]`), 0, nil},
   500          {"Len", NewArray([]Node{NewNull()}), 1, nil},
   501          {"Len", lazyArray, 0, nil},
   502          {"Len", NewRaw(`{"a":1}`), 0, nil},
   503          {"Len", lazyObject, 0, nil},
   504          {"Cap", Node{}, 0, nil},
   505          {"Cap", NewAny(0), 0, ErrUnsupportType},
   506          {"Cap", NewNull(), 0, nil},
   507          {"Cap", NewRaw(`[1]`), _DEFAULT_NODE_CAP, nil},
   508          {"Cap", NewObject([]Pair{{"", NewNull()}}), _DEFAULT_NODE_CAP, nil},
   509          {"Cap", NewRaw(`{"a":1}`), _DEFAULT_NODE_CAP, nil},
   510      }
   511      lazyArray.skipAllIndex()
   512      lazyObject.skipAllKey()
   513      cases = append(cases,
   514          tcase{"Len", lazyArray, 17, nil},
   515          tcase{"Len", lazyObject, 17, nil},
   516          tcase{"Cap", lazyArray, _DEFAULT_NODE_CAP * 3, nil},
   517          tcase{"Cap", lazyObject, _DEFAULT_NODE_CAP * 3, nil},
   518      )
   519  
   520      for i, c := range cases {
   521          fmt.Println(i, c)
   522          rt := reflect.ValueOf(&c.node)
   523          m := rt.MethodByName(c.method)
   524          rets := m.Call([]reflect.Value{})
   525          if len(rets) != 2 {
   526              t.Error(i, rets)
   527          }
   528          if !reflect.DeepEqual(rets[0].Interface(), c.exp) {
   529              t.Error(i, rets[0].Interface(), c.exp)
   530          }
   531          v := rets[1].Interface()
   532          if c.err == nonEmptyErr {
   533              if reflect.ValueOf(v).IsNil() {
   534                  t.Error(i, v)
   535              }
   536          } else if v != c.err {
   537              t.Error(i, v)
   538          }
   539      }
   540  }
   541  
   542  func TestCheckError_Nil(t *testing.T) {
   543      nill := (*Node)(nil)
   544      if nill.Valid() || nill.Check() == nil {
   545          t.Fail()
   546      }
   547      if nill.Get("").Check() == nil {
   548          t.Fatal()
   549      }
   550      if nill.GetByPath("").Check() == nil {
   551          t.Fatal()
   552      }
   553      if nill.Index(1).Check() == nil {
   554          t.Fatal()
   555      }
   556      if nill.IndexOrGet(1, "a").Check() == nil {
   557          t.Fatal()
   558      }
   559      if nill.IndexPair(1) != nil {
   560          t.Fatal()
   561      }
   562      if _, err := nill.Set("", Node{}); err == nil {
   563          t.Fatal()
   564      }
   565      if _, err := nill.SetByIndex(1, Node{}); err == nil {
   566          t.Fatal()
   567      }
   568      if _, err := nill.SetAny("", 1); err == nil {
   569          t.Fatal()
   570      }
   571      if _, err := nill.SetAnyByIndex(1, 1); err == nil {
   572          t.Fatal()
   573      }
   574      if _, err := nill.Unset(""); err == nil {
   575          t.Fatal()
   576      }
   577      if _, err := nill.UnsetByIndex(1); err == nil {
   578          t.Fatal()
   579      }
   580      if err := nill.Add(Node{}); err == nil {
   581          t.Fatal()
   582      }
   583      if err := nill.AddAny(1); err == nil {
   584          t.Fatal()
   585      }
   586  }
   587  
   588  func TestCheckError_None(t *testing.T) {
   589      nill := Node{}
   590      if !nill.Valid() || nill.Check() != nil {
   591          t.Fail()
   592      }
   593      if nill.Get("").Check() == nil {
   594          t.Fatal()
   595      }
   596      if nill.GetByPath("").Check() == nil {
   597          t.Fatal()
   598      }
   599      if nill.Index(1).Check() == nil {
   600          t.Fatal()
   601      }
   602      if nill.IndexOrGet(1, "a").Check() == nil {
   603          t.Fatal()
   604      }
   605      if nill.IndexPair(1) != nil {
   606          t.Fatal()
   607      }
   608      nill = Node{}
   609      if _, err := nill.Set("a", Node{}); err != nil {
   610          t.Fatal()
   611      }
   612      nill = Node{}
   613      if _, err := nill.SetByIndex(0, Node{}); err != nil {
   614          t.Fatal()
   615      }
   616      nill = Node{}
   617      if _, err := nill.SetByIndex(1, Node{}); err == nil {
   618          t.Fatal()
   619      }
   620      nill = Node{}
   621      if _, err := nill.SetAny("a", 1); err != nil {
   622          t.Fatal()
   623      }
   624      nill = Node{}
   625      if _, err := nill.SetAnyByIndex(0, 1); err != nil {
   626          t.Fatal()
   627      }
   628      nill = Node{}
   629      if _, err := nill.SetAnyByIndex(1, 1); err == nil {
   630          t.Fatal()
   631      }
   632      nill = Node{}
   633      if _, err := nill.Unset(""); err == nil {
   634          t.Fatal()
   635      }
   636      nill = Node{}
   637      if _, err := nill.UnsetByIndex(1); err == nil {
   638          t.Fatal()
   639      }
   640      nill = Node{}
   641      if err := nill.Add(Node{}); err != nil {
   642          t.Fatal()
   643      }
   644      nill = Node{}
   645      if err := nill.AddAny(1); err != nil {
   646          t.Fatal()
   647      }
   648  }
   649  
   650  func TestCheckError_Error(t *testing.T) {
   651      nill := newError(types.ERR_EOF, "")
   652      if nill.Valid() || nill.Check() == nil {
   653          t.Fail()
   654      }
   655      if nill.Get("").Check() == nil {
   656          t.Fatal()
   657      }
   658      if nill.GetByPath("").Check() == nil {
   659          t.Fatal()
   660      }
   661      if nill.Index(1).Check() == nil {
   662          t.Fatal()
   663      }
   664      if nill.IndexOrGet(1, "a").Check() == nil {
   665          t.Fatal()
   666      }
   667      if nill.IndexPair(1) != nil {
   668          t.Fatal()
   669      }
   670      if _, err := nill.Set("", Node{}); err == nil {
   671          t.Fatal()
   672      }
   673      if _, err := nill.SetByIndex(1, Node{}); err == nil {
   674          t.Fatal()
   675      }
   676      if _, err := nill.SetAny("", 1); err == nil {
   677          t.Fatal()
   678      }
   679      if _, err := nill.SetAnyByIndex(1, 1); err == nil {
   680          t.Fatal()
   681      }
   682      if _, err := nill.Unset(""); err == nil {
   683          t.Fatal()
   684      }
   685      if _, err := nill.UnsetByIndex(1); err == nil {
   686          t.Fatal()
   687      }
   688      if err := nill.Add(Node{}); err == nil {
   689          t.Fatal()
   690      }
   691      if err := nill.AddAny(1); err == nil {
   692          t.Fatal()
   693      }
   694  }
   695  
   696  func TestCheckError_Empty(t *testing.T) {
   697      empty := Node{}
   698      if !empty.Valid() || empty.Check() != nil || empty.Error() != "" {
   699          t.Fatal()
   700      }
   701  
   702      n := newRawNode("[hello]", types.V_ARRAY)
   703      n.parseRaw(false)
   704      if n.Check() != nil {
   705          t.Fatal(n.Check())
   706      }
   707      n = newRawNode("[hello]", types.V_ARRAY)
   708      n.parseRaw(true)
   709      p := NewParser("[hello]")
   710      p.noLazy = true
   711      p.skipValue = false
   712      _, x := p.Parse()
   713      if n.Error() != newSyntaxError(p.syntaxError(x)).Error() {
   714          t.Fatal(n.Check())
   715      }
   716  
   717      s, err := NewParser(`{"a":{}, "b":talse, "c":{}}`).Parse()
   718      if err != 0 {
   719          t.Fatal(err)
   720      }
   721  
   722      root := s.GetByPath()
   723      // fmt.Println(root.Check())
   724      a := root.Get("a")
   725      if a.Check() != nil {
   726          t.Fatal(a.Check())
   727      }
   728      c := root.Get("c")
   729      if c.Check() == nil {
   730          t.Fatal()
   731      }
   732      fmt.Println(c.Check())
   733  
   734      _, e := a.Properties()
   735      if e != nil {
   736          t.Fatal(e)
   737      }
   738      exist, e := a.Set("d", newRawNode("x", types.V_OBJECT))
   739      if exist || e != nil {
   740          t.Fatal(err)
   741      }
   742      if a.len() != 1 {
   743          t.Fail()
   744      }
   745      d := a.Get("d").Get("")
   746      if d.Check() == nil {
   747          t.Fatal(d)
   748      }
   749      exist, e = a.Set("e", newRawNode("[}", types.V_ARRAY))
   750      if e != nil {
   751          t.Fatal(e)
   752      }
   753      if a.len() != 2 {
   754          t.Fail()
   755      }
   756      d = a.Index(1).Index(0)
   757      if d.Check() == nil {
   758          t.Fatal(d)
   759      }
   760  
   761      it, e := root.Interface()
   762      if e == nil {
   763          t.Fatal(it)
   764      }
   765      fmt.Println(e)
   766  }
   767  
   768  func TestIndex(t *testing.T) {
   769      root, derr := NewParser(_TwitterJson).Parse()
   770      if derr != 0 {
   771          t.Fatalf("decode failed: %v", derr.Error())
   772      }
   773      status := root.GetByPath("statuses", 0)
   774      x, _ := status.Index(4).String()
   775      y, _ := status.Get("id_str").String()
   776      if x != y {
   777          t.Fail()
   778      }
   779  }
   780  
   781  func TestUnset(t *testing.T) {
   782      root, derr := NewParser(_TwitterJson).Parse()
   783      if derr != 0 {
   784          t.Fatalf("decode failed: %v", derr.Error())
   785      }
   786      entities := root.GetByPath("statuses", 0, "entities")
   787      if !entities.Exists() || entities.Check() != nil {
   788          t.Fatal(entities.Check().Error())
   789      }
   790      exist, err := entities.Unset("urls")
   791      if !exist || err != nil {
   792          t.Fatal()
   793      }
   794      e := entities.Get("urls")
   795      if e.Exists() {
   796          t.Fatal()
   797      }
   798      if entities.len() != 2 {
   799          t.Fatal(entities.len())
   800      }
   801  
   802      es, err := entities.Interface()
   803      require.NoError(t, err)
   804      require.Equal(t, map[string]interface{}{
   805          "hashtags": []interface{}{
   806              map[string]interface{}{
   807                  "text": "freebandnames",
   808                  "indices": []interface{}{
   809                      float64(20), float64(34),
   810                  },
   811              },
   812          },
   813          "user_mentions": []interface{}{},
   814      }, es)
   815  
   816      out, err := entities.MarshalJSON()
   817      require.NoError(t, err)
   818      println(string(out))
   819      buf := bytes.NewBuffer(nil)
   820      require.NoError(t, json.Compact(buf, out))
   821      require.Equal(t,
   822          `{"hashtags":[{"text":"freebandnames","indices":[20,34]}],"user_mentions":[]}`, buf.String())
   823  
   824      entities.Set("urls", NewString("a"))
   825      e = entities.Get("urls")
   826      x, _ := e.String()
   827      if !e.Exists() || x != "a" {
   828          t.Fatal()
   829      }
   830  
   831      out, err = entities.MarshalJSON()
   832      require.NoError(t, err)
   833      buf = bytes.NewBuffer(nil)
   834      json.Compact(buf, out)
   835      require.Equal(t,
   836          `{"hashtags":[{"text":"freebandnames","indices":[20,34]}],"user_mentions":[],"urls":"a"}`, buf.String())
   837  
   838      // reload entities
   839      *entities = NewRaw(string(out))
   840  
   841      hashtags := entities.Get("hashtags").Index(0)
   842      hashtags.Set("text2", newRawNode(`{}`, types.V_OBJECT))
   843      exist, err = hashtags.Unset("indices") // NOTICE: Unset() won't change node.Len() here
   844      if !exist || err != nil || hashtags.len() != 2 {
   845          t.Fatal(hashtags.len())
   846      }
   847      y, _ := hashtags.Get("text").String()
   848      if y != "freebandnames" {
   849          t.Fatal()
   850      }
   851      if hashtags.Get("text2").Type() != V_OBJECT {
   852          t.Fatal()
   853      }
   854  
   855      entities.Load()
   856      exist, err = entities.UnsetByIndex(entities.len() - 1)
   857      if !exist || err != nil {
   858          t.Fatal()
   859      }
   860      if entities.len() != 2 {
   861          t.Fatal(entities.len())
   862      }
   863      e = entities.Index(entities.len())
   864      if e.Exists() {
   865          t.Fatal()
   866      }
   867  
   868      ums := entities.Get("user_mentions")
   869      ums.Add(NewNull())
   870      ums.Add(NewBool(false))
   871      ums.Add(NewBool(true))
   872      if ums.len() != 3 {
   873          t.Fatal()
   874      }
   875      exist, err = ums.UnsetByIndex(1)
   876      if !exist || err != nil {
   877          t.Fatal()
   878      }
   879      require.Equal(t, 2, ums.len())
   880      umses, err := ums.Interface()
   881      require.NoError(t, err)
   882      require.Equal(t, []interface{}{interface{}(nil), true}, umses)
   883  
   884      v1, _ := ums.Index(0).Interface()
   885      v2, _ := ums.Index(1).Interface() // NOTICE: unseted index 1 still can be find here
   886      v3, _ := ums.Index(2).Interface()
   887      if v1 != nil {
   888          t.Fatal()
   889      }
   890      if v2 != true {
   891          t.Fatal()
   892      }
   893      if v3 != nil {
   894          t.Fatal()
   895      }
   896      out, err = entities.MarshalJSON()
   897      require.NoError(t, err)
   898      require.Equal(t,
   899          `{"hashtags":[{"text":"freebandnames","text2":{}}],"user_mentions":[null,true]}`, string(out))
   900  
   901  }
   902  
   903  // func TestUnsafeNode(t *testing.T) {
   904  //     str, loop := getTestIteratorSample(_DEFAULT_NODE_CAP)
   905  
   906  //     root, err := NewSearcher(str).GetByPath("array")
   907  //     if err != nil {
   908  //         t.Fatal(err)
   909  //     }
   910  //     a, _ := root.UnsafeArray()
   911  //     if len(a) != loop {
   912  //         t.Fatalf("exp:%v, got:%v", loop, len(a))
   913  //     }
   914  //     for i := int64(0); i<int64(loop); i++{
   915  //         in := a[i]
   916  //         x, _ := in.Int64()
   917  //         if x != i {
   918  //             t.Fatalf("exp:%v, got:%v", i, x)
   919  //         }
   920  //     }
   921  
   922  //     root, err = NewSearcher(str).GetByPath("object")
   923  //     if err != nil {
   924  //         t.Fatal(err)
   925  //     }
   926  //     b, _ := root.UnsafeMap()
   927  //     if len(b) != loop {
   928  //         t.Fatalf("exp:%v, got:%v", loop, len(b))
   929  //     }
   930  //     for i := int64(0); i<int64(loop); i++ {
   931  //         k := `k`+strconv.Itoa(int(i))
   932  //         if k != b[i].Key {
   933  //             t.Fatalf("unexpected element: %#v", b[i])
   934  //         }
   935  //         x, _ := b[i].Value.Int64()
   936  //         if x != i {
   937  //             t.Fatalf("exp:%v, got:%v", i, x)
   938  //         }
   939  //     }
   940  // }
   941  
   942  func TestUseNode(t *testing.T) {
   943      str, loop := getTestIteratorSample(_DEFAULT_NODE_CAP)
   944      root, e := NewParser(str).Parse()
   945      if e != 0 {
   946          t.Fatal(e)
   947      }
   948      _, er := root.InterfaceUseNode()
   949      if er != nil {
   950          t.Fatal(er)
   951      }
   952  
   953      root, err := NewSearcher(str).GetByPath("array")
   954      if err != nil {
   955          t.Fatal(err)
   956      }
   957      a, _ := root.ArrayUseNode()
   958      if len(a) != loop {
   959          t.Fatalf("exp:%v, got:%v", loop, len(a))
   960      }
   961      for i := int64(0); i < int64(loop); i++ {
   962          in := a[i]
   963          a, _ := in.Int64()
   964          if a != i {
   965              t.Fatalf("exp:%v, got:%v", i, a)
   966          }
   967      }
   968  
   969      root, err = NewSearcher(str).GetByPath("array")
   970      if err != nil {
   971          t.Fatal(err)
   972      }
   973      x, _ := root.InterfaceUseNode()
   974      a = x.([]Node)
   975      if len(a) != loop {
   976          t.Fatalf("exp:%v, got:%v", loop, len(a))
   977      }
   978      for i := int64(0); i < int64(loop); i++ {
   979          in := a[i]
   980          a, _ := in.Int64()
   981          if a != i {
   982              t.Fatalf("exp:%v, got:%v", i, a)
   983          }
   984      }
   985  
   986      root, err = NewSearcher(str).GetByPath("object")
   987      if err != nil {
   988          t.Fatal(err)
   989      }
   990      b, _ := root.MapUseNode()
   991      if len(b) != loop {
   992          t.Fatalf("exp:%v, got:%v", loop, len(b))
   993      }
   994      for i := int64(0); i < int64(loop); i++ {
   995          k := `k` + strconv.Itoa(int(i))
   996          xn, ok := b[k]
   997          if !ok {
   998              t.Fatalf("unexpected element: %#v", xn)
   999          }
  1000          a, _ := xn.Int64()
  1001          if a != i {
  1002              t.Fatalf("exp:%v, got:%v", i, a)
  1003          }
  1004      }
  1005  
  1006      root, err = NewSearcher(str).GetByPath("object")
  1007      if err != nil {
  1008          t.Fatal(err)
  1009      }
  1010      x, _ = root.InterfaceUseNode()
  1011      b = x.(map[string]Node)
  1012      if len(b) != loop {
  1013          t.Fatalf("exp:%v, got:%v", loop, len(b))
  1014      }
  1015      for i := int64(0); i < int64(loop); i++ {
  1016          k := `k` + strconv.Itoa(int(i))
  1017          xn, ok := b[k]
  1018          if !ok {
  1019              t.Fatalf("unexpected element: %#v", xn)
  1020          }
  1021          a, _ := xn.Int64()
  1022          if a != i {
  1023              t.Fatalf("exp:%v, got:%v", i, a)
  1024          }
  1025      }
  1026  }
  1027  
  1028  func TestUseNumber(t *testing.T) {
  1029      str, _ := getTestIteratorSample(_DEFAULT_NODE_CAP)
  1030      root, e := NewParser(str).Parse()
  1031      if e != 0 {
  1032          t.Fatal(e)
  1033      }
  1034      _, er := root.InterfaceUseNumber()
  1035      if er != nil {
  1036          t.Fatal(er)
  1037      }
  1038  
  1039      node, err := NewParser("1061346755812312312313").Parse()
  1040      if err != 0 {
  1041          t.Fatal(err)
  1042      }
  1043      if node.Type() != V_NUMBER {
  1044          t.Fatalf("wrong type: %v", node.Type())
  1045      }
  1046      x, _ := node.InterfaceUseNumber()
  1047      iv := x.(json.Number)
  1048      if iv.String() != "1061346755812312312313" {
  1049          t.Fatalf("exp:%#v, got:%#v", "1061346755812312312313", iv.String())
  1050      }
  1051      x, _ = node.Interface()
  1052      ix := x.(float64)
  1053      if ix != float64(1061346755812312312313) {
  1054          t.Fatalf("exp:%#v, got:%#v", float64(1061346755812312312313), ix)
  1055      }
  1056      xj, _ := node.Number()
  1057      ij, _ := xj.Int64()
  1058      jj, _ := json.Number("1061346755812312312313").Int64()
  1059      if ij != jj {
  1060          t.Fatalf("exp:%#v, got:%#v", jj, ij)
  1061      }
  1062  }
  1063  
  1064  func TestMap(t *testing.T) {
  1065      node, err := NewParser(`{"a":-0, "b":1, "c":-1.2, "d":-1.2e-10}`).Parse()
  1066      if err != 0 {
  1067          t.Fatal(err)
  1068      }
  1069      m, _ := node.Map()
  1070      assert.Equal(t, m, map[string]interface{}{
  1071          "a": float64(0),
  1072          "b": float64(1),
  1073          "c": -1.2,
  1074          "d": -1.2e-10,
  1075      })
  1076      m1, _ := node.MapUseNumber()
  1077      assert.Equal(t, m1, map[string]interface{}{
  1078          "a": json.Number("-0"),
  1079          "b": json.Number("1"),
  1080          "c": json.Number("-1.2"),
  1081          "d": json.Number("-1.2e-10"),
  1082      })
  1083  }
  1084  
  1085  func TestArray(t *testing.T) {
  1086      node, err := NewParser(`[-0, 1, -1.2, -1.2e-10]`).Parse()
  1087      if err != 0 {
  1088          t.Fatal(err)
  1089      }
  1090      m, _ := node.Array()
  1091      assert.Equal(t, m, []interface{}{
  1092          float64(0),
  1093          float64(1),
  1094          -1.2,
  1095          -1.2e-10,
  1096      })
  1097      m1, _ := node.ArrayUseNumber()
  1098      assert.Equal(t, m1, []interface{}{
  1099          json.Number("-0"),
  1100          json.Number("1"),
  1101          json.Number("-1.2"),
  1102          json.Number("-1.2e-10"),
  1103      })
  1104  }
  1105  
  1106  func TestNodeRaw(t *testing.T) {
  1107      root, derr := NewSearcher(_TwitterJson).GetByPath("search_metadata")
  1108      if derr != nil {
  1109          t.Fatalf("decode failed: %v", derr.Error())
  1110      }
  1111      val, _ := root.Raw()
  1112      var comp = `{
  1113      "max_id": 250126199840518145,
  1114      "since_id": 24012619984051000,
  1115      "refresh_url": "?since_id=250126199840518145&q=%23freebandnames&result_type=mixed&include_entities=1",
  1116      "next_results": "?max_id=249279667666817023&q=%23freebandnames&count=4&include_entities=1&result_type=mixed",
  1117      "count": 4,
  1118      "completed_in": 0.035,
  1119      "since_id_str": "24012619984051000",
  1120      "query": "%23freebandnames",
  1121      "max_id_str": "250126199840518145"
  1122    }`
  1123      if val != comp {
  1124          t.Fatalf("exp: %+v, got: %+v", comp, val)
  1125      }
  1126  
  1127      root, derr = NewSearcher(_TwitterJson).GetByPath("statuses", 0, "entities", "hashtags")
  1128      if derr != nil {
  1129          t.Fatalf("decode failed: %v", derr.Error())
  1130      }
  1131      val, _ = root.Raw()
  1132      comp = `[
  1133            {
  1134              "text": "freebandnames",
  1135              "indices": [
  1136                20,
  1137                34
  1138              ]
  1139            }
  1140          ]`
  1141      if val != comp {
  1142          t.Fatalf("exp: \n%s\n, got: \n%s\n", comp, val)
  1143      }
  1144  
  1145      var data = `{"k1" :   { "a" : "bc"} , "k2" : [1,2 ] , "k3":{} , "k4":[]}`
  1146      root, derr = NewSearcher(data).GetByPath("k1")
  1147      if derr != nil {
  1148          t.Fatalf("decode failed: %v", derr.Error())
  1149      }
  1150      val, _ = root.Raw()
  1151      comp = `{ "a" : "bc"}`
  1152      if val != comp {
  1153          t.Fatalf("exp: %+v, got: %+v", comp, val)
  1154      }
  1155  
  1156      root, derr = NewSearcher(data).GetByPath("k2")
  1157      if derr != nil {
  1158          t.Fatalf("decode failed: %v", derr.Error())
  1159      }
  1160      val, _ = root.Raw()
  1161      comp = `[1,2 ]`
  1162      if val != comp {
  1163          t.Fatalf("exp: %+v, got: %+v", comp, val)
  1164      }
  1165  
  1166      root, derr = NewSearcher(data).GetByPath("k3")
  1167      if derr != nil {
  1168          t.Fatalf("decode failed: %v", derr.Error())
  1169      }
  1170      val, _ = root.Raw()
  1171      comp = `{}`
  1172      if val != comp {
  1173          t.Fatalf("exp: %+v, got: %+v", comp, val)
  1174      }
  1175  
  1176      root, derr = NewSearcher(data).GetByPath("k4")
  1177      if derr != nil {
  1178          t.Fatalf("decode failed: %v", derr.Error())
  1179      }
  1180      val, _ = root.Raw()
  1181      comp = `[]`
  1182      if val != comp {
  1183          t.Fatalf("exp: %+v, got: %+v", comp, val)
  1184      }
  1185  }
  1186  
  1187  func TestNodeGet(t *testing.T) {
  1188      root, derr := NewParser(_TwitterJson).Parse()
  1189      if derr != 0 {
  1190          t.Fatalf("decode failed: %v", derr.Error())
  1191      }
  1192      val, _ := root.Get("search_metadata").Get("max_id").Int64()
  1193      if val != int64(250126199840518145) {
  1194          t.Fatalf("exp: %+v, got: %+v", 250126199840518145, val)
  1195      }
  1196  }
  1197  
  1198  func TestNodeIndex(t *testing.T) {
  1199      root, derr := NewParser(_TwitterJson).Parse()
  1200      if derr != 0 {
  1201          t.Fatalf("decode failed: %v", derr.Error())
  1202      }
  1203      val, _ := root.Get("statuses").Index(3).Get("id_str").String()
  1204      if val != "249279667666817024" {
  1205          t.Fatalf("exp: %+v, got: %+v", "249279667666817024", val)
  1206      }
  1207  }
  1208  
  1209  func TestNodeGetByPath(t *testing.T) {
  1210      root, derr := NewParser(_TwitterJson).Parse()
  1211      if derr != 0 {
  1212          t.Fatalf("decode failed: %v", derr.Error())
  1213      }
  1214      val, _ := root.GetByPath("statuses", 3, "id_str").String()
  1215      if val != "249279667666817024" {
  1216          t.Fatalf("exp: %+v, got: %+v", "249279667666817024", val)
  1217      }
  1218  }
  1219  
  1220  func TestNodeSet(t *testing.T) {
  1221      arr := NewRaw(`[]`)
  1222      ex, ee := arr.Set("a", NewNumber("-1"))
  1223      if ex || ee == nil {
  1224          t.Fatal()
  1225      }
  1226      empty := Node{}
  1227      err := empty.Add(Node{})
  1228      if err != nil {
  1229          t.Fatal(err)
  1230      }
  1231      empty2 := empty.Index(0)
  1232      if empty2.Check() != nil {
  1233          t.Fatal(err)
  1234      }
  1235      exist, err := empty2.SetByIndex(1, Node{})
  1236      if exist || err == nil {
  1237          t.Fatal(exist, err)
  1238      }
  1239      empty3 := empty.Index(0)
  1240      if empty3.Check() != nil {
  1241          t.Fatal(err)
  1242      }
  1243      exist, err = empty3.Set("a", NewNumber("-1"))
  1244      if exist || err != nil {
  1245          t.Fatal(exist, err)
  1246      }
  1247      if n, e := empty.Index(0).Get("a").Int64(); e != nil || n != -1 {
  1248          t.Fatal(n, e)
  1249      }
  1250  
  1251      empty = NewNull()
  1252      err = empty.Add(NewNull())
  1253      if err != nil {
  1254          t.Fatal(err)
  1255      }
  1256      empty2 = empty.Index(0)
  1257      if empty2.Check() != nil {
  1258          t.Fatal(err)
  1259      }
  1260      exist, err = empty2.SetByIndex(1, NewNull())
  1261      if exist || err == nil {
  1262          t.Fatal(exist, err)
  1263      }
  1264      empty3 = empty.Index(0)
  1265      if empty3.Check() != nil {
  1266          t.Fatal(err)
  1267      }
  1268      exist, err = empty3.Set("a", NewNumber("-1"))
  1269      if exist || err != nil {
  1270          t.Fatal(exist, err)
  1271      }
  1272      if n, e := empty.Index(0).Get("a").Int64(); e != nil || n != -1 {
  1273          t.Fatal(n, e)
  1274      }
  1275  
  1276      root, derr := NewParser(_TwitterJson).Parse()
  1277      if derr != 0 {
  1278          t.Fatalf("decode failed: %v", derr.Error())
  1279      }
  1280      app, _ := NewParser("111").Parse()
  1281      root.GetByPath("statuses", 3).Set("id_str", app)
  1282      val, _ := root.GetByPath("statuses", 3, "id_str").Int64()
  1283      if val != 111 {
  1284          t.Fatalf("exp: %+v, got: %+v", 111, val)
  1285      }
  1286      for i, _ := root.GetByPath("statuses", 3).Cap(); i >= 0; i-- {
  1287          root.GetByPath("statuses", 3).Set("id_str"+strconv.Itoa(i), app)
  1288      }
  1289      val, _ = root.GetByPath("statuses", 3, "id_str0").Int64()
  1290      if val != 111 {
  1291          t.Fatalf("exp: %+v, got: %+v", 111, val)
  1292      }
  1293  
  1294      nroot, derr := NewParser(`{"a":[0.1,true,0,"name",{"b":"c"}]}`).Parse()
  1295      if derr != 0 {
  1296          t.Fatalf("decode failed: %v", derr.Error())
  1297      }
  1298      root.GetByPath("statuses", 3).Set("id_str2", nroot)
  1299      val2, _ := root.GetByPath("statuses", 3, "id_str2", "a", 4, "b").String()
  1300      if val2 != "c" {
  1301          t.Fatalf("exp:%+v, got:%+v", "c", val2)
  1302      }
  1303  }
  1304  
  1305  func TestNodeSetByIndex(t *testing.T) {
  1306      root, derr := NewParser(_TwitterJson).Parse()
  1307      if derr != 0 {
  1308          t.Fatalf("decode failed: %v", derr.Error())
  1309      }
  1310      app, _ := NewParser("111").Parse()
  1311      st := root.GetByPath("statuses")
  1312      st.SetByIndex(0, app)
  1313      st = root.GetByPath("statuses")
  1314      val := st.Index(0)
  1315      x, _ := val.Int64()
  1316      if x != 111 {
  1317          t.Fatalf("exp: %+v, got: %+v", 111, val)
  1318      }
  1319  
  1320      nroot, derr := NewParser(`{"a":[0.1,true,0,"name",{"b":"c"}]}`).Parse()
  1321      if derr != 0 {
  1322          t.Fatalf("decode failed: %v", derr.Error())
  1323      }
  1324      root.GetByPath("statuses").SetByIndex(0, nroot)
  1325      val2, _ := root.GetByPath("statuses", 0, "a", 4, "b").String()
  1326      if val2 != "c" {
  1327          t.Fatalf("exp:%+v, got:%+v", "c", val2)
  1328      }
  1329  }
  1330  
  1331  func TestNodeAdd(t *testing.T) {
  1332      root, derr := NewParser(_TwitterJson).Parse()
  1333      if derr != 0 {
  1334          t.Fatalf("decode failed: %v", derr.Error())
  1335      }
  1336      app, _ := NewParser("111").Parse()
  1337  
  1338      for i, _ := root.GetByPath("statuses").Cap(); i >= 0; i-- {
  1339          root.GetByPath("statuses").Add(app)
  1340      }
  1341      val, _ := root.GetByPath("statuses", 4).Int64()
  1342      if val != 111 {
  1343          t.Fatalf("exp: %+v, got: %+v", 111, val)
  1344      }
  1345      val, _ = root.GetByPath("statuses", root.GetByPath("statuses").len()-1).Int64()
  1346      if val != 111 {
  1347          t.Fatalf("exp: %+v, got: %+v", 111, val)
  1348      }
  1349  
  1350      nroot, derr := NewParser(`{"a":[0.1,true,0,"name",{"b":"c"}]}`).Parse()
  1351      if derr != 0 {
  1352          t.Fatalf("decode failed: %v", derr.Error())
  1353      }
  1354      root.GetByPath("statuses").Add(nroot)
  1355      val2, _ := root.GetByPath("statuses", root.GetByPath("statuses").len()-1, "a", 4, "b").String()
  1356      if val2 != "c" {
  1357          t.Fatalf("exp:%+v, got:%+v", "c", val2)
  1358      }
  1359  }
  1360  
  1361  func BenchmarkLoadNode(b *testing.B) {
  1362      b.Run("Interface()", func(b *testing.B) {
  1363          b.SetBytes(int64(len(_TwitterJson)))
  1364          b.ResetTimer()
  1365          for i := 0; i < b.N; i++ {
  1366              root, err := NewSearcher(_TwitterJson).GetByPath("statuses", 0)
  1367              if err != nil {
  1368                  b.Fatal(err)
  1369              }
  1370              _, _ = root.Interface()
  1371          }
  1372      })
  1373  
  1374      b.Run("LoadAll()", func(b *testing.B) {
  1375          b.SetBytes(int64(len(_TwitterJson)))
  1376          b.ResetTimer()
  1377          for i := 0; i < b.N; i++ {
  1378              root, err := NewSearcher(_TwitterJson).GetByPath("statuses", 0)
  1379              if err != nil {
  1380                  b.Fatal(err)
  1381              }
  1382              _ = root.LoadAll()
  1383          }
  1384      })
  1385  
  1386      b.Run("InterfaceUseNode()", func(b *testing.B) {
  1387          b.SetBytes(int64(len(_TwitterJson)))
  1388          b.ResetTimer()
  1389          for i := 0; i < b.N; i++ {
  1390              root, err := NewSearcher(_TwitterJson).GetByPath("statuses", 0)
  1391              if err != nil {
  1392                  b.Fatal(err)
  1393              }
  1394              _, _ = root.InterfaceUseNode()
  1395          }
  1396      })
  1397  
  1398      b.Run("Load()", func(b *testing.B) {
  1399          b.SetBytes(int64(len(_TwitterJson)))
  1400          b.ResetTimer()
  1401          for i := 0; i < b.N; i++ {
  1402              root, err := NewSearcher(_TwitterJson).GetByPath("statuses", 0)
  1403              if err != nil {
  1404                  b.Fatal(err)
  1405              }
  1406              _ = root.Load()
  1407          }
  1408      })
  1409  }
  1410  
  1411  func BenchmarkLoadNode_Parallel(b *testing.B) {
  1412      b.Run("Interface()", func(b *testing.B) {
  1413          b.SetBytes(int64(len(_TwitterJson)))
  1414          b.ResetTimer()
  1415          b.RunParallel(func(pb *testing.PB) {
  1416              for pb.Next() {
  1417                  root, err := NewSearcher(_TwitterJson).GetByPath("statuses", 0)
  1418                  if err != nil {
  1419                      b.Fatal(err)
  1420                  }
  1421                  _, _ = root.Interface()
  1422              }
  1423          })
  1424      })
  1425  
  1426      b.Run("LoadAll()", func(b *testing.B) {
  1427          b.SetBytes(int64(len(_TwitterJson)))
  1428          b.ResetTimer()
  1429          b.RunParallel(func(pb *testing.PB) {
  1430              for pb.Next() {
  1431                  root, err := NewSearcher(_TwitterJson).GetByPath("statuses", 0)
  1432                  if err != nil {
  1433                      b.Fatal(err)
  1434                  }
  1435                  _ = root.LoadAll()
  1436              }
  1437          })
  1438      })
  1439  
  1440      b.Run("InterfaceUseNode()", func(b *testing.B) {
  1441          b.SetBytes(int64(len(_TwitterJson)))
  1442          b.ResetTimer()
  1443          b.RunParallel(func(pb *testing.PB) {
  1444              for pb.Next() {
  1445                  root, err := NewSearcher(_TwitterJson).GetByPath("statuses", 0)
  1446                  if err != nil {
  1447                      b.Fatal(err)
  1448                  }
  1449                  _, _ = root.InterfaceUseNode()
  1450              }
  1451          })
  1452      })
  1453  
  1454      b.Run("Load()", func(b *testing.B) {
  1455          b.SetBytes(int64(len(_TwitterJson)))
  1456          b.ResetTimer()
  1457          b.RunParallel(func(pb *testing.PB) {
  1458              for pb.Next() {
  1459                  root, err := NewSearcher(_TwitterJson).GetByPath("statuses", 0)
  1460                  if err != nil {
  1461                      b.Fatal(err)
  1462                  }
  1463                  _ = root.Load()
  1464              }
  1465          })
  1466      })
  1467  }
  1468  
  1469  func BenchmarkNodeGetByPath(b *testing.B) {
  1470      root, derr := NewParser(_TwitterJson).Parse()
  1471      if derr != 0 {
  1472          b.Fatalf("decode failed: %v", derr.Error())
  1473      }
  1474      _, _ = root.GetByPath("statuses", 3, "entities", "hashtags", 0, "text").String()
  1475      b.ResetTimer()
  1476  
  1477      b.RunParallel(func(pb *testing.PB) {
  1478          for pb.Next() {
  1479              _, _ = root.GetByPath("statuses", 3, "entities", "hashtags", 0, "text").String()
  1480          }
  1481      })
  1482  }
  1483  
  1484  func BenchmarkStructGetByPath(b *testing.B) {
  1485      var root = _TwitterStruct{}
  1486      err := json.Unmarshal([]byte(_TwitterJson), &root)
  1487      if err != nil {
  1488          b.Fatalf("unmarshal failed: %v", err)
  1489      }
  1490  
  1491      b.ResetTimer()
  1492  
  1493      b.RunParallel(func(pb *testing.PB) {
  1494          for pb.Next() {
  1495              _ = root.Statuses[3].Entities.Hashtags[0].Text
  1496          }
  1497      })
  1498  }
  1499  
  1500  func BenchmarkNodeIndex(b *testing.B) {
  1501      root, derr := NewParser(_TwitterJson).Parse()
  1502      if derr != 0 {
  1503          b.Fatalf("decode failed: %v", derr.Error())
  1504      }
  1505      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags").Index(0)
  1506      node.Set("test1", NewNumber("1"))
  1507      node.Set("test2", NewNumber("2"))
  1508      node.Set("test3", NewNumber("3"))
  1509      node.Set("test4", NewNumber("4"))
  1510      node.Set("test5", NewNumber("5"))
  1511      b.ResetTimer()
  1512      for i := 0; i < b.N; i++ {
  1513          node.Index(2)
  1514      }
  1515  }
  1516  
  1517  func BenchmarkStructIndex(b *testing.B) {
  1518      type T struct {
  1519          A Node
  1520          B Node
  1521          C Node
  1522          D Node
  1523          E Node
  1524      }
  1525      var obj = new(T)
  1526      b.ResetTimer()
  1527      for i := 0; i < b.N; i++ {
  1528          _ = obj.C
  1529      }
  1530  }
  1531  
  1532  func BenchmarkSliceIndex(b *testing.B) {
  1533      var obj = []Node{Node{}, Node{}, Node{}, Node{}, Node{}}
  1534      b.ResetTimer()
  1535      for i := 0; i < b.N; i++ {
  1536          _ = obj[2]
  1537      }
  1538  }
  1539  
  1540  func BenchmarkMapIndex(b *testing.B) {
  1541      var obj = map[string]interface{}{"test1": Node{}, "test2": Node{}, "test3": Node{}, "test4": Node{}, "test5": Node{}}
  1542      b.ResetTimer()
  1543      for i := 0; i < b.N; i++ {
  1544          for k := range obj {
  1545              if k == "test3" {
  1546                  break
  1547              }
  1548          }
  1549      }
  1550  }
  1551  
  1552  func BenchmarkNodeGet(b *testing.B) {
  1553      var N = 5
  1554      var half = "test" + strconv.Itoa(N/2+1)
  1555      root, derr := NewParser(_TwitterJson).Parse()
  1556      if derr != 0 {
  1557          b.Fatalf("decode failed: %v", derr.Error())
  1558      }
  1559      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags").Index(0)
  1560      for i := 0; i < N; i++ {
  1561          node.Set("test"+strconv.Itoa(i), NewNumber(strconv.Itoa(i)))
  1562      }
  1563  
  1564      b.ResetTimer()
  1565      for i := 0; i < b.N; i++ {
  1566          _ = node.Get(half)
  1567      }
  1568  }
  1569  
  1570  func BenchmarkSliceGet(b *testing.B) {
  1571      var obj = []string{"test1", "test2", "test3", "test4", "test5"}
  1572      str := "test3"
  1573      b.ResetTimer()
  1574      for i := 0; i < b.N; i++ {
  1575          for _, k := range obj {
  1576              if k == str {
  1577                  break
  1578              }
  1579          }
  1580      }
  1581  }
  1582  
  1583  func BenchmarkMapGet(b *testing.B) {
  1584      root, derr := NewParser(_TwitterJson).Parse()
  1585      if derr != 0 {
  1586          b.Fatalf("decode failed: %v", derr.Error())
  1587      }
  1588      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags").Index(0)
  1589      node.Set("test1", NewNumber("1"))
  1590      node.Set("test2", NewNumber("2"))
  1591      node.Set("test3", NewNumber("3"))
  1592      node.Set("test4", NewNumber("4"))
  1593      node.Set("test5", NewNumber("5"))
  1594      m, _ := node.Map()
  1595      b.ResetTimer()
  1596      for i := 0; i < b.N; i++ {
  1597          _ = m["test3"]
  1598      }
  1599  }
  1600  
  1601  func BenchmarkNodeSet(b *testing.B) {
  1602      root, derr := NewParser(_TwitterJson).Parse()
  1603      if derr != 0 {
  1604          b.Fatalf("decode failed: %v", derr.Error())
  1605      }
  1606      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags").Index(0)
  1607      node.Set("test1", NewNumber("1"))
  1608      node.Set("test2", NewNumber("2"))
  1609      node.Set("test3", NewNumber("3"))
  1610      node.Set("test4", NewNumber("4"))
  1611      node.Set("test5", NewNumber("5"))
  1612      n := NewNull()
  1613      b.ResetTimer()
  1614      for i := 0; i < b.N; i++ {
  1615          node.Set("test3", n)
  1616      }
  1617  }
  1618  
  1619  func BenchmarkMapSet(b *testing.B) {
  1620      root, derr := NewParser(_TwitterJson).Parse()
  1621      if derr != 0 {
  1622          b.Fatalf("decode failed: %v", derr.Error())
  1623      }
  1624      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags").Index(0)
  1625      node.Set("test1", NewNumber("1"))
  1626      node.Set("test2", NewNumber("2"))
  1627      node.Set("test3", NewNumber("3"))
  1628      node.Set("test4", NewNumber("4"))
  1629      node.Set("test5", NewNumber("5"))
  1630      m, _ := node.Map()
  1631      n := NewNull()
  1632      b.ResetTimer()
  1633      for i := 0; i < b.N; i++ {
  1634          m["test3"] = n
  1635      }
  1636  }
  1637  
  1638  func BenchmarkNodeSetByIndex(b *testing.B) {
  1639      root, derr := NewParser(_TwitterJson).Parse()
  1640      if derr != 0 {
  1641          b.Fatalf("decode failed: %v", derr.Error())
  1642      }
  1643      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags")
  1644      node.Add(NewNumber("1"))
  1645      node.Add(NewNumber("2"))
  1646      node.Add(NewNumber("3"))
  1647      node.Add(NewNumber("4"))
  1648      node.Add(NewNumber("5"))
  1649      n := NewNull()
  1650      b.ResetTimer()
  1651      for i := 0; i < b.N; i++ {
  1652          node.SetByIndex(2, n)
  1653      }
  1654  }
  1655  
  1656  func BenchmarkSliceSetByIndex(b *testing.B) {
  1657      root, derr := NewParser(_TwitterJson).Parse()
  1658      if derr != 0 {
  1659          b.Fatalf("decode failed: %v", derr.Error())
  1660      }
  1661      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags")
  1662      node.Add(NewNumber("1"))
  1663      node.Add(NewNumber("2"))
  1664      node.Add(NewNumber("3"))
  1665      node.Add(NewNumber("4"))
  1666      node.Add(NewNumber("5"))
  1667      m, _ := node.Array()
  1668      n := NewNull()
  1669      b.ResetTimer()
  1670      for i := 0; i < b.N; i++ {
  1671          m[2] = n
  1672      }
  1673  }
  1674  
  1675  func BenchmarkStructSetByIndex(b *testing.B) {
  1676      type T struct {
  1677          A Node
  1678          B Node
  1679          C Node
  1680          D Node
  1681          E Node
  1682      }
  1683      var obj = new(T)
  1684      n := NewNull()
  1685      b.ResetTimer()
  1686      for i := 0; i < b.N; i++ {
  1687          obj.C = n
  1688      }
  1689  }
  1690  
  1691  func BenchmarkNodeUnset(b *testing.B) {
  1692      root, derr := NewParser(_TwitterJson).Parse()
  1693      if derr != 0 {
  1694          b.Fatalf("decode failed: %v", derr.Error())
  1695      }
  1696      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags").Index(0)
  1697      node.Set("test1", NewNumber("1"))
  1698      node.Set("test2", NewNumber("2"))
  1699      node.Set("test3", NewNumber("3"))
  1700      node.Set("test4", NewNumber("4"))
  1701      node.Set("test5", NewNumber("5"))
  1702      b.ResetTimer()
  1703      for i := 0; i < b.N; i++ {
  1704          node.Unset("test3")
  1705      }
  1706  }
  1707  
  1708  func BenchmarkMapUnset(b *testing.B) {
  1709      root, derr := NewParser(_TwitterJson).Parse()
  1710      if derr != 0 {
  1711          b.Fatalf("decode failed: %v", derr.Error())
  1712      }
  1713      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags").Index(0)
  1714      node.Set("test1", NewNumber("1"))
  1715      node.Set("test2", NewNumber("2"))
  1716      node.Set("test3", NewNumber("3"))
  1717      node.Set("test4", NewNumber("4"))
  1718      node.Set("test5", NewNumber("5"))
  1719      m, _ := node.Map()
  1720      b.ResetTimer()
  1721      for i := 0; i < b.N; i++ {
  1722          delete(m, "test3")
  1723      }
  1724  }
  1725  
  1726  func BenchmarkNodUnsetByIndex(b *testing.B) {
  1727      root, derr := NewParser(_TwitterJson).Parse()
  1728      if derr != 0 {
  1729          b.Fatalf("decode failed: %v", derr.Error())
  1730      }
  1731      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags")
  1732      node.Add(NewNumber("1"))
  1733      node.Add(NewNumber("2"))
  1734      node.Add(NewNumber("3"))
  1735      node.Add(NewNumber("4"))
  1736      node.Add(NewNumber("5"))
  1737      b.ResetTimer()
  1738      for i := 0; i < b.N; i++ {
  1739          node.UnsetByIndex(2)
  1740      }
  1741  }
  1742  
  1743  func BenchmarkSliceUnsetByIndex(b *testing.B) {
  1744      root, derr := NewParser(_TwitterJson).Parse()
  1745      if derr != 0 {
  1746          b.Fatalf("decode failed: %v", derr.Error())
  1747      }
  1748      node := root.Get("statuses").Index(3).Get("entities").Get("hashtags")
  1749      node.Add(NewNumber("1"))
  1750      node.Add(NewNumber("2"))
  1751      node.Add(NewNumber("3"))
  1752      node.Add(NewNumber("4"))
  1753      node.Add(NewNumber("5"))
  1754      m, _ := node.Array()
  1755      b.ResetTimer()
  1756      for i := 0; i < b.N; i++ {
  1757          for i := 3; i < 5; i++ {
  1758              m[i-1] = m[i]
  1759          }
  1760      }
  1761  }
  1762  
  1763  func BenchmarkNodeAdd(b *testing.B) {
  1764      n := NewObject([]Pair{{"test", NewNumber("1")}})
  1765      b.ResetTimer()
  1766      for i := 0; i < b.N; i++ {
  1767          node := NewArray([]Node{})
  1768          node.Add(n)
  1769      }
  1770  }
  1771  
  1772  func BenchmarkSliceAdd(b *testing.B) {
  1773      n := NewObject([]Pair{{"test", NewNumber("1")}})
  1774      b.ResetTimer()
  1775      for i := 0; i < b.N; i++ {
  1776          node := []Node{}
  1777          node = append(node, n)
  1778      }
  1779  }
  1780  
  1781  func BenchmarkMapAdd(b *testing.B) {
  1782      n := NewObject([]Pair{{"test", NewNumber("1")}})
  1783      b.ResetTimer()
  1784      for i := 0; i < b.N; i++ {
  1785          node := map[string]Node{}
  1786          node["test3"] = n
  1787      }
  1788  }
  1789  
  1790  func TestNode_Move(t *testing.T) {
  1791      var us = NewRaw(`["a","1","b","c"]`)
  1792      if ex, e := us.UnsetByIndex(1); !ex || e != nil {
  1793          t.Fail()
  1794      }
  1795      var us2 = NewRaw(`["a","b","c","1"]`)
  1796      if ex, e := us2.UnsetByIndex(3); !ex || e != nil {
  1797          t.Fail()
  1798      }
  1799      tests := []struct {
  1800          name    string
  1801          in      Node
  1802          src     int
  1803          dst     int
  1804          out     Node
  1805          wantErr bool
  1806      }{
  1807          {
  1808              name:    "over index",
  1809              in:      NewArray([]Node{}),
  1810              src:     0,
  1811              dst:     1,
  1812              out:     NewArray([]Node{}),
  1813              wantErr: false,
  1814          },
  1815          {
  1816              name:    "equal index",
  1817              in:      NewArray([]Node{NewBool(true)}),
  1818              src:     0,
  1819              dst:     0,
  1820              out:     NewArray([]Node{NewBool(true)}),
  1821              wantErr: false,
  1822          },
  1823          {
  1824              name:    "forward",
  1825              in:      NewArray([]Node{NewString("a"), NewString("b"), NewString("c")}),
  1826              src:     0,
  1827              dst:     2,
  1828              out:     NewArray([]Node{NewString("b"), NewString("c"), NewString("a")}),
  1829              wantErr: false,
  1830          },
  1831          {
  1832              name:    "backward",
  1833              in:      NewArray([]Node{NewString("a"), NewString("b"), NewString("c")}),
  1834              src:     2,
  1835              dst:     0,
  1836              out:     NewArray([]Node{NewString("c"), NewString("a"), NewString("b")}),
  1837              wantErr: false,
  1838          },
  1839          {
  1840              name:    "lazy",
  1841              in:      NewRaw(`["a","b","c"]`),
  1842              src:     2,
  1843              dst:     0,
  1844              out:     NewArray([]Node{NewString("c"), NewString("a"), NewString("b")}),
  1845              wantErr: false,
  1846          },
  1847          {
  1848              name:    "unset back",
  1849              in:      us,
  1850              src:     2,
  1851              dst:     0,
  1852              out:     NewArray([]Node{NewString("c"), NewString("a"), NewString("b")}),
  1853              wantErr: false,
  1854          },
  1855          {
  1856              name:    "unset forward",
  1857              in:      us2,
  1858              src:     0,
  1859              dst:     2,
  1860              out:     NewArray([]Node{NewString("b"), NewString("c"), NewString("a")}),
  1861              wantErr: false,
  1862          },
  1863      }
  1864      for _, tt := range tests {
  1865          t.Run(tt.name, func(t *testing.T) {
  1866              err := tt.in.Move(tt.dst, tt.src)
  1867              require.NoError(t, err)
  1868              ej, _ := tt.out.MarshalJSON()
  1869              aj, _ := tt.in.MarshalJSON()
  1870              require.Equal(t, string(ej), string(aj))
  1871          })
  1872      }
  1873  
  1874  }
  1875  
  1876  func TestNode_Pop(t *testing.T) {
  1877      var us = NewRaw(`[1,2,3]`)
  1878      if ex, e := us.UnsetByIndex(0); !ex || e != nil {
  1879          t.Fail()
  1880      }
  1881      var us2 = NewRaw(`[1,2,3]`)
  1882      if ex, e := us2.UnsetByIndex(2); !ex || e != nil {
  1883          t.Fail()
  1884      }
  1885      tests := []struct {
  1886          name  string
  1887          in  Node
  1888          out Node
  1889          wantErr bool
  1890      }{
  1891          {
  1892              name:  "empty",
  1893              in:    NewArray([]Node{}),
  1894              out:   NewArray([]Node{}),
  1895              wantErr: false,
  1896          },
  1897          {
  1898              name:  "one",
  1899              in:    NewArray([]Node{NewString("a")}),
  1900              out:   NewArray([]Node{}),
  1901              wantErr: false,
  1902          },
  1903          {
  1904              name:  "raw",
  1905              in:    NewRaw(`[1]`),
  1906              out:   NewArray([]Node{}),
  1907              wantErr: false,
  1908          },
  1909          {
  1910              name:  "unset head",
  1911              in:    us,
  1912              out:   NewRaw(`[2]`),
  1913              wantErr: false,
  1914          },
  1915          {
  1916              name:  "unset tail",
  1917              in:    us2,
  1918              out:   NewRaw(`[1]`),
  1919              wantErr: false,
  1920          },
  1921      }
  1922      for _, tt := range tests {
  1923          t.Run(tt.name, func(t *testing.T) {
  1924              if err := tt.in.Pop(); (err != nil) != tt.wantErr {
  1925                  t.Errorf("Node.Pop() error = %v, wantErr %v", err, tt.wantErr)
  1926              }
  1927              ej, _ := tt.out.MarshalJSON()
  1928              aj, _ := tt.in.MarshalJSON()
  1929              require.Equal(t, string(ej), string(aj))
  1930          })
  1931      }
  1932  }