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

     1  // +build amd64,go1.16,!go1.23
     2  
     3  /*
     4   * Copyright 2021 ByteDance Inc.
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   *     http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package sonic
    20  
    21  import (
    22      `bytes`
    23      `encoding/hex`
    24      `encoding/json`
    25      `fmt`
    26      `math/rand`
    27      `reflect`
    28      `strings`
    29      `testing`
    30      `time`
    31  
    32      `github.com/davecgh/go-spew/spew`
    33      `github.com/stretchr/testify/assert`
    34      `github.com/bytedance/sonic/ast`
    35  )
    36  
    37  func Parse(src string) (*ast.Node, error) {
    38      node, err := ast.NewParser(src).Parse()
    39      if err != 0 {
    40          return &node, fmt.Errorf("parsing error: %v", err)
    41      }
    42      return &node, nil
    43  }
    44  
    45  func assertCond(cond bool) {
    46      if !cond {
    47          panic("assertCond failed")
    48      }
    49  }
    50  
    51  func TestExampleSearch(t *testing.T) {
    52      data := []byte(` { "xx" : [] ,"yy" :{ }, "test" : [ true , 0.1 , "abc", ["h"], {"a":"bc"} ] } `)
    53  
    54      node, e := Get(data, "test", 0)
    55      x, _ := node.Bool()
    56      if e != nil || x != true {
    57          t.Fatalf("node: %v, err: %v", node, e)
    58      }
    59  
    60      node, e = Get(data, "test", 1)
    61      a, _ := node.Float64()
    62      if e != nil || a != 0.1 {
    63          t.Fatalf("node: %v, err: %v", node, e)
    64      }
    65  
    66      node, e = Get(data, "test", 2)
    67      b, _ := node.String()
    68      if e != nil || b != "abc" {
    69          t.Fatalf("node: %v, err: %v", node, e)
    70      }
    71  
    72      node, e = Get(data, "test", 3)
    73      arr, _ := node.Array()
    74      if e != nil || arr[0] != "h" {
    75          t.Fatalf("node: %v, err: %v", node, e)
    76      }
    77  
    78      node, e = Get(data, "test", 4, "a")
    79      c, _ := node.String()
    80      if e != nil || c != "bc" {
    81          t.Fatalf("node: %v, err: %v", node, e)
    82      }
    83  }
    84  
    85  func TestExampleSearchEscapedKey(t *testing.T) {
    86      data := []byte(`
    87  {
    88      "xx" : [] ,
    89      "yy" :{ }, 
    90      "test\"" : [
    91          true ,
    92          0.1 ,
    93          "abc",
    94          [
    95              "h"
    96          ], 
    97          {
    98              "a\u0008": {},
    99              "b\\\\": null,
   100              "\u2028\u2028": "\u2028\u2029",
   101              "\u0026":2,
   102              "0":1
   103          } 
   104      ],
   105      ",,,,,,,,,,(,,15": ",",
   106      ",,,,,,,,,,(,,,16": "a,]}",
   107      ",,,,,,,,,,(,,,,17": 1,
   108      ",,,,,,,,,,(,,,,,,,,,,,,,,,,(,,,,34": "c"
   109  } `)
   110  
   111      type getTest struct{
   112          path []interface{}
   113          expect interface{}
   114      }
   115  
   116      tests := []getTest {
   117          {[]interface{}{"test\"", 0}, true},
   118          {[]interface{}{"test\"", 1}, 0.1},
   119          {[]interface{}{"test\"", 2}, "abc"},
   120          {[]interface{}{"test\"", 3}, []interface{}{"h"}},
   121          {[]interface{}{"test\"", 4, "a\u0008"}, map[string]interface{}{}},
   122          {[]interface{}{"test\"", 4, "b\\\\"}, nil},
   123          {[]interface{}{"test\"", 4, "\u2028\u2028"}, "\u2028\u2029"},
   124          {[]interface{}{"test\"", 4, "0"}, float64(1)},
   125          {[]interface{}{",,,,,,,,,,(,,15"}, ","},
   126          {[]interface{}{",,,,,,,,,,(,,,16"}, "a,]}"},
   127          {[]interface{}{",,,,,,,,,,(,,,,17"}, float64(1)},
   128          {[]interface{}{",,,,,,,,,,(,,,,,,,,,,,,,,,,(,,,,34"}, "c"},
   129      }
   130  
   131      for _, test := range(tests) {
   132          node, err := Get(data, test.path...)
   133          assert.NoErrorf(t, err, "get return errors")
   134          got, err := node.Interface()
   135          assert.NoErrorf(t, err, "get convert errors")
   136          assert.Equalf(t, test.expect, got, "get result is wrong from path %#v", test.path)
   137      }
   138  }
   139  
   140  func TestExampleSearchErr(t *testing.T) {
   141      data := []byte(` { "xx" : [] ,"yy" :{ }, "test" : [ true , 0.1 , "abc", ["h"], {"a":"bc"} ] } `)
   142      node, e := Get(data, "zz")
   143      if e == nil {
   144          t.Fatalf("node: %v, err: %v", node, e)
   145      }
   146      fmt.Println(e)
   147  
   148      node, e = Get(data, "xx", 4)
   149      if e == nil {
   150          t.Fatalf("node: %v, err: %v", node, e)
   151      }
   152      fmt.Println(e)
   153  
   154      node, e = Get(data, "yy", "a")
   155      if e == nil {
   156          t.Fatalf("node: %v, err: %v", node, e)
   157      }
   158      fmt.Println(e)
   159  
   160      node, e = Get(data, "test", 4, "x")
   161      if e == nil {
   162          t.Fatalf("node: %v, err: %v", node, e)
   163      }
   164      fmt.Println(e)
   165  }
   166  
   167  func TestExampleSearchEscapedKeyError(t *testing.T) {
   168      data := []byte(` { "xx" : [] ,"yy" :{ }, "x\u0008" : [] ,"y\\\"y" :{ }, "test" : [ true , 0.1 , "abc", ["h"], {"a":"bc"} ] } `)
   169      node, e := Get(data, "zz")
   170      if e == nil {
   171          t.Fatalf("node: %v, err: %v", node, e)
   172      }
   173      fmt.Println(e)
   174  
   175      node, e = Get(data, "x\u0008", 4)
   176      if e == nil {
   177          t.Fatalf("node: %v, err: %v", node, e)
   178      }
   179      fmt.Println(e)
   180  
   181      node, e = Get(data, "yy", "a")
   182      if e == nil {
   183          t.Fatalf("node: %v, err: %v", node, e)
   184      }
   185      fmt.Println(e)
   186  
   187      node, e = Get(data, "test", 4, "x")
   188      if e == nil {
   189          t.Fatalf("node: %v, err: %v", node, e)
   190      }
   191  
   192      node, e = Get(data, "y\\\"y", 4, "x")
   193      if e == nil {
   194          t.Fatalf("node: %v, err: %v", node, e)
   195      }
   196      fmt.Println(e)
   197  }
   198  
   199  func TestRandomData(t *testing.T) {
   200      var lstr string
   201      defer func() {
   202          if v := recover(); v != nil {
   203              println("'" + hex.Dump([]byte(lstr)) + "'")
   204              println(lstr)
   205              panic(v)
   206          }
   207      }()
   208      data := []byte(`"�-mp�`)
   209      _, err := ast.NewParser(string(data)).Parse()
   210      if err != 0 {
   211          fmt.Println(hex.Dump(data))
   212          fmt.Println(string(data))
   213      }
   214      rand.Seed(time.Now().UnixNano())
   215      b := make([]byte, 200)
   216      for i := 0; i < 1000000; i++ {
   217          n, ee := rand.Read(b[:rand.Int()%len(b)])
   218          if ee != nil {
   219              t.Fatalf("get random bytes failed: %v,", ee)
   220              return
   221          }
   222          lstr = string(b[:n])
   223          _, _ = ast.NewParser(lstr).Parse()
   224      }
   225  }
   226  
   227  func TestRandomValidStrings(t *testing.T) {
   228      rand.Seed(time.Now().UnixNano())
   229      b := make([]byte, 200)
   230      for i := 0; i < 1000; i++ {
   231          n, err := rand.Read(b[:rand.Int()%len(b)])
   232          if err != nil {
   233              t.Fatal("get random data failed:", err)
   234          }
   235          sm, err := json.Marshal(string(b[:n]))
   236          if err != nil {
   237              t.Fatal("marshal data failed:",err)
   238          }
   239          var su string
   240          if err := json.Unmarshal(sm, &su); err != nil {
   241              t.Fatal("unmarshal data failed:",err)
   242          }
   243          token, err := GetFromString(`{"str":`+string(sm)+`}`, "str")
   244          if err != nil {
   245              spew.Dump(string(sm))
   246              t.Fatal("search data failed:",err)
   247          }
   248          x, _ := token.Interface()
   249          st, ok := x.(string)
   250          if !ok {
   251              t.Fatalf("type mismatch, exp: %v, got: %v", su, x)
   252          }
   253          if st != su {
   254              t.Fatalf("string mismatch, exp: %v, got: %v", su, x)
   255          }
   256      }
   257  }
   258  
   259  
   260  func TestEmoji(t *testing.T) {
   261      var input = []byte(`{"utf8":"Example emoji, KO: \ud83d\udd13, \ud83c\udfc3 ` +
   262          `OK: \u2764\ufe0f "}`)
   263      value, err := Get(input, "utf8")
   264      if err != nil {
   265          t.Fatal(err)
   266      }
   267      var v map[string]interface{}
   268      if err := json.Unmarshal(input, &v); err != nil {
   269          t.Fatal(err)
   270      }
   271      s, _ := v["utf8"].(string)
   272      x, _ := value.String()
   273      if x != s {
   274          t.Fatalf("expected '%v', got '%v'", s, x)
   275      }
   276  }
   277  
   278  func testEscapePath(t *testing.T, json, expect string, path ...interface{}) {
   279      n, e := Get([]byte(json), path...)
   280      if e != nil {
   281          t.Fatal(e)
   282      }
   283      x, _ := n.String()
   284      if x != expect {
   285          x, _ := n.Interface()
   286          t.Fatalf("expected '%v', got '%v'", expect, x)
   287      }
   288  }
   289  
   290  func TestEscapePath(t *testing.T) {
   291      data := `{
   292          "test":{
   293              "*":"valZ",
   294              "*v":"val0",
   295              "keyv*":"val1",
   296              "key*v":"val2",
   297              "keyv?":"val3",
   298              "key?v":"val4",
   299              "keyv.":"val5",
   300              "key.v":"val6",
   301              "keyk*":{"key?":"val7"}
   302          }
   303      }`
   304  
   305      testEscapePath(t, data, "valZ", "test", "*")
   306      testEscapePath(t, data, "val0", "test", "*v")
   307      testEscapePath(t, data, "val1", "test", "keyv*")
   308      testEscapePath(t, data, "val2", "test", "key*v")
   309      testEscapePath(t, data, "val3", "test", "keyv?")
   310      testEscapePath(t, data, "val4", "test", "key?v")
   311      testEscapePath(t, data, "val5", "test", "keyv.")
   312      testEscapePath(t, data, "val6", "test", "key.v")
   313      testEscapePath(t, data, "val7", "test", "keyk*", "key?")
   314  }
   315  
   316  func TestParseAny(t *testing.T) {
   317      n, e := Parse("100")
   318      assertCond(e == nil)
   319      if n == nil {
   320          panic("n is nil")
   321      }
   322      x, _ := n.Float64()
   323      assertCond(x == 100)
   324      n, e = Parse("true")
   325      assertCond(e == nil)
   326      if n == nil {
   327          panic("n is nil")
   328      }
   329  
   330      a, _ := n.Bool()
   331      assertCond(a)
   332      n, e = Parse("false")
   333      assertCond(e == nil)
   334      if n == nil {
   335          panic("n is nil")
   336      }
   337      b, _ := n.Bool()
   338      assertCond(b == false)
   339      n, e = Parse("yikes")
   340      assertCond(e != nil)
   341  }
   342  
   343  func TestTime(t *testing.T) {
   344      data := []byte(`{
   345        "code": 0,
   346        "msg": "",
   347        "data": {
   348          "sz002024": {
   349            "qfqday": [
   350              [
   351                "2014-01-02",
   352                "8.93",
   353                "9.03",
   354                "9.17",
   355                "8.88",
   356                "621143.00"
   357              ],
   358              [
   359                "2014-01-03",
   360                "9.03",
   361                "9.30",
   362                "9.47",
   363                "8.98",
   364                "1624438.00"
   365              ]
   366            ]
   367          }
   368        }
   369      }`)
   370  
   371      var num []string
   372      n, e := Get(data, "data", "sz002024", "qfqday", 0)
   373      if e != nil {
   374          t.Fatal(e)
   375      }
   376  
   377      arr, _ := n.Array()
   378      for _, v := range arr {
   379          s := v.(string)
   380          num = append(num, s)
   381      }
   382      if fmt.Sprintf("%v", num) != "[2014-01-02 8.93 9.03 9.17 8.88 621143.00]" {
   383          t.Fatalf("invalid result")
   384      }
   385  }
   386  
   387  var exampleJSON = `{
   388      "widget": {
   389          "debug": "on",
   390          "window": {
   391              "title": "Sample Konfabulator Widget",
   392              "name": "main_window",
   393              "width": 500,
   394              "height": 500
   395          },
   396          "image": {
   397              "src": "Images/Sun.png",
   398              "hOffset": 250,
   399              "vOffset": 250,
   400              "alignment": "center"
   401          },
   402          "text": {
   403              "data": "Click Here",
   404              "size": 36,
   405              "style": "bold",
   406              "vOffset": 100,
   407              "alignment": "center",
   408              "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
   409          }
   410      }
   411  }`
   412  
   413  func TestUnmarshalMap(t *testing.T) {
   414      n, err := Parse(exampleJSON)
   415      if err != nil || n == nil {
   416          t.Fatal(err)
   417      }
   418      m1, _ := n.Map()
   419      var m2 map[string]interface{}
   420      if err := json.Unmarshal([]byte(exampleJSON), &m2); err != nil {
   421          t.Fatal(err)
   422      }
   423      b1, err := json.Marshal(m1)
   424      if err != nil {
   425          t.Fatal(err)
   426      }
   427      b2, err := json.Marshal(m2)
   428      if err != nil {
   429          t.Fatal(err)
   430      }
   431      if !bytes.Equal(b1, b2) {
   432          t.Fatalf("b1 != b2\n b1: %v\nb2: %v", string(b1), string(b2))
   433      }
   434  }
   435  
   436  func GetMany(src2 string, path ...string) (ret []string) {
   437      src := []byte(src2)
   438      for _, p := range path {
   439          pathes := strings.Split(p, ".")
   440          if len(pathes) == 0 {
   441              panic(fmt.Sprintf("invalid path: %v", p))
   442          }
   443          ps := make([]interface{}, 0, len(pathes))
   444          for _, p := range pathes {
   445              ps = append(ps, p)
   446          }
   447          n, e := Get(src, ps...)
   448          if e != nil {
   449              ret = append(ret, "")
   450              continue
   451          }
   452          x, _ := n.Interface()
   453          ret = append(ret, fmt.Sprintf("%v", x))
   454      }
   455      return
   456  }
   457  
   458  func get(str string, path string) *ast.Node {
   459      src := []byte(str)
   460      pathes := strings.Split(path, ".")
   461      if len(pathes) == 0 {
   462          panic(fmt.Sprintf("invalid path: %v", path))
   463      }
   464      ps := make([]interface{}, 0, len(pathes))
   465      for _, p := range pathes {
   466          ps = append(ps, p)
   467      }
   468      n, e := Get(src, ps...)
   469      if e != nil {
   470          return nil
   471      }
   472      return &n
   473  }
   474  
   475  func TestSingleArrayValue(t *testing.T) {
   476      var data = []byte(`{"key": "value","key2":[1,2,3,4,"A"]}`)
   477      array, _ := get(string(data), "key2").Array()
   478      if len(array) != 5 {
   479          t.Fatalf("got '%v', expected '%v'", len(array), 5)
   480      }
   481  
   482      _, e := Get(data, "key3")
   483      if e == nil {
   484          t.Fatalf("got '%v', expected '%v'", e, nil)
   485      }
   486  }
   487  
   488  var manyJSON = `  {
   489      "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   490          "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   491          "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   492          "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   493          "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   494          "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   495          "a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"hello":"world"
   496          }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}},
   497          "position":{"type":"Point","coordinates":[-115.24,33.09]},
   498          "loves":["world peace"],
   499          "name":{"last":"Anderson","first":"Nancy"},
   500          "age":31,
   501          "x":{"a":"emptya","b":"emptyb"},
   502          "name_last":"Yellow",
   503          "name_first":"Cat",
   504  }`
   505  
   506  func TestManyBasic(t *testing.T) {
   507      testMany := func(shouldFallback bool, expect string, paths ...string) {
   508          println()
   509          rs := GetMany(
   510              manyJSON,
   511              paths...,
   512          )
   513          // if len(rs) != len(paths) {
   514          //     t.Fatalf("expected %v, got %v", len(paths), len(rs))
   515          // }
   516          var results = "[" + strings.Join(rs, " ") + "]"
   517          if results != expect {
   518              fmt.Printf("%v\n", paths)
   519              t.Fatalf("expected %v, got %v", expect, results)
   520          }
   521      }
   522      testMany(false, "[Point]", "position.type")
   523      testMany(false, `[emptya [world peace] 31]`, "x.a", "loves", "age")
   524      testMany(false, `[[world peace]]`, "loves")
   525      testMany(false, `[map[first:Nancy last:Anderson] Nancy]`, "name",
   526          "name.first")
   527      testMany(true, `[]`, strings.Repeat("a.", 40)+"hello")
   528      res := get(manyJSON, strings.Repeat("a.", 48)+"a")
   529      assertCond(res != nil)
   530      x, _ := res.Interface()
   531      testMany(true, "["+fmt.Sprint(x)+"]", strings.Repeat("a.", 48)+"a")
   532      // these should fallback
   533      testMany(true, `[Cat Nancy]`, "name_first", "name.first")
   534      testMany(true, `[world]`, strings.Repeat("a.", 70)+"hello")
   535  }
   536  
   537  func testMany(t *testing.T, json string, paths, expected []string) {
   538      testManyAny(t, json, paths, expected)
   539      testManyAny(t, json, paths, expected)
   540  }
   541  
   542  func testManyAny(t *testing.T, json string, paths, expected []string) {
   543      var result []string
   544      for i := 0; i < 2; i++ {
   545          var which string
   546          if i == 0 {
   547              which = "Get"
   548              result = nil
   549              for j := 0; j < len(expected); j++ {
   550                  x, _ := get(json, paths[j]).Interface()
   551                  result = append(result, fmt.Sprintf("%v", x))
   552              }
   553          } else if i == 1 {
   554              which = "GetMany"
   555              result = GetMany(json, paths...)
   556          }
   557          if result == nil {
   558              panic("result is nil")
   559          }
   560          for j := 0; j < len(expected); j++ {
   561              if result[j] != expected[j] {
   562                  t.Fatalf("Using key '%s' for '%s'\nexpected '%v', got '%v'",
   563                      paths[j], which, expected[j], result[j])
   564              }
   565          }
   566      }
   567  }
   568  
   569  func TestNested(t *testing.T) {
   570      data := `{ "name": "FirstName", "name1": "FirstName1", ` +
   571          `"address": "address1", "addressDetails": "address2", }`
   572      paths := []string{"name", "name1", "address", "addressDetails"}
   573      expected := []string{"FirstName", "FirstName1", "address1", "address2"}
   574      t.Run("SingleMany", func(t *testing.T) {
   575          testMany(t, data, paths,
   576              expected)
   577      })
   578  }
   579  
   580  func TestMultiLevelFields(t *testing.T) {
   581      data := `{ "Level1Field1":3, 
   582                 "Level1Field4":4, 
   583                 "Level1Field2":{ "Level2Field1":[ "value1", "value2" ], 
   584                 "Level2Field2":{ "Level3Field1":[ { "key1":"value1" } ] } } }`
   585      paths := []string{"Level1Field1", "Level1Field2.Level2Field1",
   586          "Level1Field2.Level2Field2.Level3Field1", "Level1Field4"}
   587      expected := []string{"3", `[value1 value2]`,
   588          `[map[key1:value1]]`, "4"}
   589      t.Run("SingleMany", func(t *testing.T) {
   590          testMany(t, data, paths,
   591              expected)
   592      })
   593  }
   594  
   595  func TestRandomMany(t *testing.T) {
   596      var lstr string
   597      defer func() {
   598          if v := recover(); v != nil {
   599              println("'" + hex.EncodeToString([]byte(lstr)) + "'")
   600              println("'" + lstr + "'")
   601              panic(v)
   602          }
   603      }()
   604      rand.Seed(time.Now().UnixNano())
   605      b := make([]byte, 512)
   606      for i := 0; i < 5000; i++ {
   607          n, err := rand.Read(b[:rand.Int()%len(b)])
   608          if err != nil {
   609              t.Fatal(err)
   610          }
   611          lstr = string(b[:n])
   612          paths := make([]string, rand.Int()%64)
   613          for i := range paths {
   614              var b []byte
   615              n := rand.Int() % 5
   616              for j := 0; j < n; j++ {
   617                  if j > 0 {
   618                      b = append(b, '.')
   619                  }
   620                  nn := rand.Int() % 10
   621                  for k := 0; k < nn; k++ {
   622                      b = append(b, 'a'+byte(rand.Int()%26))
   623                  }
   624              }
   625              paths[i] = string(b)
   626          }
   627          GetMany(lstr, paths...)
   628      }
   629  }
   630  
   631  func TestGetMany(t *testing.T) {
   632      data := `{"bar": {"id": 99, "mybar": "my mybar" }, "foo": ` +
   633          `{"myfoo": [605]}}`
   634      paths := []string{"foo.myfoo", "bar.id", "bar.mybar", "bar.mybarx"}
   635      expected := []string{"[605]", "99", "my mybar", ""}
   636      results := GetMany(data, paths...)
   637      if len(expected) != len(results) {
   638          t.Fatalf("expected %v, got %v", len(expected), len(results))
   639      }
   640      for i, path := range paths {
   641          if results[i] != expected[i] {
   642              t.Fatalf("expected '%v', got '%v' for path '%v'", expected[i],
   643                  results[i], path)
   644          }
   645      }
   646  }
   647  
   648  func TestGetMany2(t *testing.T) {
   649      data := `{"bar": {"id": 99, "xyz": "my xyz"}, "foo": {"myfoo": [605]}}`
   650      paths := []string{"foo.myfoo", "bar.id", "bar.xyz", "bar.abc"}
   651      expected := []string{"[605]", "99", "my xyz", ""}
   652      results := GetMany(data, paths...)
   653      if len(expected) != len(results) {
   654          t.Fatalf("expected %v, got %v", len(expected), len(results))
   655      }
   656      for i, path := range paths {
   657          if results[i] != expected[i] {
   658              t.Fatalf("expected '%v', got '%v' for path '%v'", expected[i],
   659                  results[i], path)
   660          }
   661      }
   662  }
   663  
   664  func TestNullArray(t *testing.T) {
   665      n, _ := get(`{"data":null}`, "data").Interface()
   666      if n != nil {
   667          t.Fatalf("expected '%v', got '%v'", nil, n)
   668      }
   669      n = get(`{}`, "data")
   670      if reflect.DeepEqual(n, nil) {
   671          t.Fatalf("expected '%v', got '%v'", nil, n)
   672      }
   673      n = get(`{"data":[]}`, "data")
   674      if reflect.DeepEqual(n, &ast.Node{}) {
   675          t.Fatalf("expected '%v', got '%v'", nil, n)
   676      }
   677      arr, _ := get(`{"data":[null]}`, "data").Array()
   678      n = len(arr)
   679      if n != 1 {
   680          t.Fatalf("expected '%v', got '%v'", 1, n)
   681      }
   682  }
   683  
   684  func TestGetMany3(t *testing.T) {
   685      var r []string
   686      data := `{"MarketName":null,"Nounce":6115}`
   687      r = GetMany(data, "Nounce", "Buys", "Sells", "Fills")
   688      if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" {
   689          t.Fatalf("expected '%v', got '%v'", "[6115]",
   690              strings.Replace(fmt.Sprintf("%v", r), " ", "", -1))
   691      }
   692      r = GetMany(data, "Nounce", "Buys", "Sells")
   693      if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" {
   694          t.Fatalf("expected '%v', got '%v'", "[6115]",
   695              strings.Replace(fmt.Sprintf("%v", r), " ", "", -1))
   696      }
   697      r = GetMany(data, "Nounce")
   698      if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" {
   699          t.Fatalf("expected '%v', got '%v'", "[6115]",
   700              strings.Replace(fmt.Sprintf("%v", r), " ", "", -1))
   701      }
   702  }
   703  
   704  func TestGetMany4(t *testing.T) {
   705      data := `{"one": {"two": 2, "three": 3}, "four": 4, "five": 5}`
   706      results := GetMany(data, "four", "five", "one.two", "one.six")
   707      expected := []string{"4", "5", "2", ""}
   708      for i, r := range results {
   709          if r != expected[i] {
   710              t.Fatalf("expected %v, got %v", expected[i], r)
   711          }
   712      }
   713  }
   714  
   715  func TestGetNotExist(t *testing.T) {
   716      var dataStr = `{"m1":{"m2":3}}`
   717      ret, err := GetFromString(dataStr, "not_exist", "m3")
   718      if err == nil || ret.Exists() {
   719          t.Fatal("Get exist!")
   720      }
   721      if ret.Type() != ast.V_NONE {
   722          t.Fatal(ret.Type())
   723      }
   724      ret, err = GetFromString(dataStr)
   725      if !ret.IsRaw() || ret.Type() != ast.V_OBJECT {
   726          t.Fatal(ret.Type())
   727      }
   728      v11 := ret.Get("not_exist")
   729      if v11.Exists() {
   730          t.Fatal()
   731      }
   732      v2 := ret.GetByPath("m1", "m2")
   733      if !v2.Exists() || !v2.IsRaw() {
   734          t.Fatal(ret.Type())
   735      }
   736      x, _ := v2.Int64()
   737      if x != 3 {
   738          t.Fatal(x)
   739      }
   740  }