...

Source file src/github.com/bytedance/sonic/ast/node_test.go

Documentation: github.com/bytedance/sonic/ast

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

View as plain text