github.com/fufuok/utils@v1.0.10/xjson/gjson/gjson_test.go (about)

     1  package gjson
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"fmt"
     8  	"math"
     9  	"math/rand"
    10  	"strconv"
    11  	"strings"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/fufuok/utils/xjson/pretty"
    16  )
    17  
    18  // TestRandomData is a fuzzing test that throws random data at the Parse
    19  // function looking for panics.
    20  func TestRandomData(t *testing.T) {
    21  	var lstr string
    22  	defer func() {
    23  		if v := recover(); v != nil {
    24  			println("'" + hex.EncodeToString([]byte(lstr)) + "'")
    25  			println("'" + lstr + "'")
    26  			panic(v)
    27  		}
    28  	}()
    29  	rand.Seed(time.Now().UnixNano())
    30  	b := make([]byte, 200)
    31  	for i := 0; i < 2000000; i++ {
    32  		n, err := rand.Read(b[:rand.Int()%len(b)])
    33  		if err != nil {
    34  			t.Fatal(err)
    35  		}
    36  		lstr = string(b[:n])
    37  		GetBytes([]byte(lstr), "zzzz")
    38  		Parse(lstr)
    39  	}
    40  }
    41  
    42  func TestRandomValidStrings(t *testing.T) {
    43  	rand.Seed(time.Now().UnixNano())
    44  	b := make([]byte, 200)
    45  	for i := 0; i < 100000; i++ {
    46  		n, err := rand.Read(b[:rand.Int()%len(b)])
    47  		if err != nil {
    48  			t.Fatal(err)
    49  		}
    50  		sm, err := json.Marshal(string(b[:n]))
    51  		if err != nil {
    52  			t.Fatal(err)
    53  		}
    54  		var su string
    55  		if err := json.Unmarshal([]byte(sm), &su); err != nil {
    56  			t.Fatal(err)
    57  		}
    58  		token := Get(`{"str":`+string(sm)+`}`, "str")
    59  		if token.Type != String || token.Str != su {
    60  			println("["+token.Raw+"]", "["+token.Str+"]", "["+su+"]",
    61  				"["+string(sm)+"]")
    62  			t.Fatal("string mismatch")
    63  		}
    64  	}
    65  }
    66  
    67  func TestEmoji(t *testing.T) {
    68  	const input = `{"utf8":"Example emoji, KO: \ud83d\udd13, \ud83c\udfc3 ` +
    69  		`OK: \u2764\ufe0f "}`
    70  	value := Get(input, "utf8")
    71  	var s string
    72  	json.Unmarshal([]byte(value.Raw), &s)
    73  	if value.String() != s {
    74  		t.Fatalf("expected '%v', got '%v'", s, value.String())
    75  	}
    76  }
    77  
    78  func testEscapePath(t *testing.T, json, path, expect string) {
    79  	if Get(json, path).String() != expect {
    80  		t.Fatalf("expected '%v', got '%v'", expect, Get(json, path).String())
    81  	}
    82  }
    83  
    84  func TestEscapePath(t *testing.T) {
    85  	json := `{
    86  		"test":{
    87  			"*":"valZ",
    88  			"*v":"val0",
    89  			"keyv*":"val1",
    90  			"key*v":"val2",
    91  			"keyv?":"val3",
    92  			"key?v":"val4",
    93  			"keyv.":"val5",
    94  			"key.v":"val6",
    95  			"keyk*":{"key?":"val7"}
    96  		}
    97  	}`
    98  
    99  	testEscapePath(t, json, "test.\\*", "valZ")
   100  	testEscapePath(t, json, "test.\\*v", "val0")
   101  	testEscapePath(t, json, "test.keyv\\*", "val1")
   102  	testEscapePath(t, json, "test.key\\*v", "val2")
   103  	testEscapePath(t, json, "test.keyv\\?", "val3")
   104  	testEscapePath(t, json, "test.key\\?v", "val4")
   105  	testEscapePath(t, json, "test.keyv\\.", "val5")
   106  	testEscapePath(t, json, "test.key\\.v", "val6")
   107  	testEscapePath(t, json, "test.keyk\\*.key\\?", "val7")
   108  }
   109  
   110  // this json block is poorly formed on purpose.
   111  var basicJSON = `  {"age":100, "name":{"here":"B\\\"R"},
   112  	"noop":{"what is a wren?":"a bird"},
   113  	"happy":true,"immortal":false,
   114  	"items":[1,2,3,{"tags":[1,2,3],"points":[[1,2],[3,4]]},4,5,6,7],
   115  	"arr":["1",2,"3",{"hello":"world"},"4",5],
   116  	"vals":[1,2,3,{"sadf":sdf"asdf"}],"name":{"first":"tom","last":null},
   117  	"created":"2014-05-16T08:28:06.989Z",
   118  	"loggy":{
   119  		"programmers": [
   120      	    {
   121      	        "firstName": "Brett",
   122      	        "lastName": "McLaughlin",
   123      	        "email": "aaaa",
   124  				"tag": "good"
   125      	    },
   126      	    {
   127      	        "firstName": "Jason",
   128      	        "lastName": "Hunter",
   129      	        "email": "bbbb",
   130  				"tag": "bad"
   131      	    },
   132      	    {
   133      	        "firstName": "Elliotte",
   134      	        "lastName": "Harold",
   135      	        "email": "cccc",
   136  				"tag":, "good"
   137      	    },
   138  			{
   139  				"firstName": 1002.3,
   140  				"age": 101
   141  			}
   142      	]
   143  	},
   144  	"lastly":{"end...ing":"soon","yay":"final"}
   145  }`
   146  
   147  func TestPath(t *testing.T) {
   148  	json := basicJSON
   149  	r := Get(json, "@this")
   150  	path := r.Path(json)
   151  	if path != "@this" {
   152  		t.FailNow()
   153  	}
   154  
   155  	r = Parse(json)
   156  	path = r.Path(json)
   157  	if path != "@this" {
   158  		t.FailNow()
   159  	}
   160  
   161  	obj := Parse(json)
   162  	obj.ForEach(func(key, val Result) bool {
   163  		kp := key.Path(json)
   164  		assert(t, kp == "")
   165  		vp := val.Path(json)
   166  		if vp == "name" {
   167  			// there are two "name" keys
   168  			return true
   169  		}
   170  		val2 := obj.Get(vp)
   171  		assert(t, val2.Raw == val.Raw)
   172  		return true
   173  	})
   174  	arr := obj.Get("loggy.programmers")
   175  	arr.ForEach(func(_, val Result) bool {
   176  		vp := val.Path(json)
   177  		val2 := Get(json, vp)
   178  		assert(t, val2.Raw == val.Raw)
   179  		return true
   180  	})
   181  	get := func(path string) {
   182  		r1 := Get(json, path)
   183  		path2 := r1.Path(json)
   184  		r2 := Get(json, path2)
   185  		assert(t, r1.Raw == r2.Raw)
   186  	}
   187  	get("age")
   188  	get("name")
   189  	get("name.here")
   190  	get("noop")
   191  	get("noop.what is a wren?")
   192  	get("arr.0")
   193  	get("arr.1")
   194  	get("arr.2")
   195  	get("arr.3")
   196  	get("arr.3.hello")
   197  	get("arr.4")
   198  	get("arr.5")
   199  	get("loggy.programmers.2.email")
   200  	get("lastly.end\\.\\.\\.ing")
   201  	get("lastly.yay")
   202  }
   203  
   204  func TestTimeResult(t *testing.T) {
   205  	assert(t, Get(basicJSON, "created").String() ==
   206  		Get(basicJSON, "created").Time().Format(time.RFC3339Nano))
   207  }
   208  
   209  func TestParseAny(t *testing.T) {
   210  	assert(t, Parse("100").Float() == 100)
   211  	assert(t, Parse("true").Bool())
   212  	assert(t, Parse("false").Bool() == false)
   213  	assert(t, Parse("yikes").Exists() == false)
   214  }
   215  
   216  func TestManyVariousPathCounts(t *testing.T) {
   217  	json := `{"a":"a","b":"b","c":"c"}`
   218  	counts := []int{
   219  		3, 4, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127,
   220  		128, 129, 255, 256, 257, 511, 512, 513,
   221  	}
   222  	paths := []string{"a", "b", "c"}
   223  	expects := []string{"a", "b", "c"}
   224  	for _, count := range counts {
   225  		var gpaths []string
   226  		for i := 0; i < count; i++ {
   227  			if i < len(paths) {
   228  				gpaths = append(gpaths, paths[i])
   229  			} else {
   230  				gpaths = append(gpaths, fmt.Sprintf("not%d", i))
   231  			}
   232  		}
   233  		results := GetMany(json, gpaths...)
   234  		for i := 0; i < len(paths); i++ {
   235  			if results[i].String() != expects[i] {
   236  				t.Fatalf("expected '%v', got '%v'", expects[i],
   237  					results[i].String())
   238  			}
   239  		}
   240  	}
   241  }
   242  
   243  func TestManyRecursion(t *testing.T) {
   244  	var json string
   245  	var path string
   246  	for i := 0; i < 100; i++ {
   247  		json += `{"a":`
   248  		path += ".a"
   249  	}
   250  	json += `"b"`
   251  	for i := 0; i < 100; i++ {
   252  		json += `}`
   253  	}
   254  	path = path[1:]
   255  	assert(t, GetMany(json, path)[0].String() == "b")
   256  }
   257  
   258  func TestByteSafety(t *testing.T) {
   259  	jsonb := []byte(`{"name":"Janet","age":38}`)
   260  	mtok := GetBytes(jsonb, "name")
   261  	if mtok.String() != "Janet" {
   262  		t.Fatalf("expected %v, got %v", "Jason", mtok.String())
   263  	}
   264  	mtok2 := GetBytes(jsonb, "age")
   265  	if mtok2.Raw != "38" {
   266  		t.Fatalf("expected %v, got %v", "Jason", mtok2.Raw)
   267  	}
   268  	jsonb[9] = 'T'
   269  	jsonb[12] = 'd'
   270  	jsonb[13] = 'y'
   271  	if mtok.String() != "Janet" {
   272  		t.Fatalf("expected %v, got %v", "Jason", mtok.String())
   273  	}
   274  }
   275  
   276  func get(json, path string) Result {
   277  	return GetBytes([]byte(json), path)
   278  }
   279  
   280  func TestBasic(t *testing.T) {
   281  	var mtok Result
   282  	mtok = get(basicJSON, `loggy.programmers.#[tag="good"].firstName`)
   283  	if mtok.String() != "Brett" {
   284  		t.Fatalf("expected %v, got %v", "Brett", mtok.String())
   285  	}
   286  	mtok = get(basicJSON, `loggy.programmers.#[tag="good"]#.firstName`)
   287  	if mtok.String() != `["Brett","Elliotte"]` {
   288  		t.Fatalf("expected %v, got %v", `["Brett","Elliotte"]`, mtok.String())
   289  	}
   290  }
   291  
   292  func TestIsArrayIsObject(t *testing.T) {
   293  	mtok := get(basicJSON, "loggy")
   294  	assert(t, mtok.IsObject())
   295  	assert(t, !mtok.IsArray())
   296  
   297  	mtok = get(basicJSON, "loggy.programmers")
   298  	assert(t, !mtok.IsObject())
   299  	assert(t, mtok.IsArray())
   300  
   301  	mtok = get(basicJSON, `loggy.programmers.#[tag="good"]#.firstName`)
   302  	assert(t, mtok.IsArray())
   303  
   304  	mtok = get(basicJSON, `loggy.programmers.0.firstName`)
   305  	assert(t, !mtok.IsObject())
   306  	assert(t, !mtok.IsArray())
   307  }
   308  
   309  func TestPlus53BitInts(t *testing.T) {
   310  	json := `{"IdentityData":{"GameInstanceId":634866135153775564}}`
   311  	value := Get(json, "IdentityData.GameInstanceId")
   312  	assert(t, value.Uint() == 634866135153775564)
   313  	assert(t, value.Int() == 634866135153775564)
   314  	assert(t, value.Float() == 634866135153775616)
   315  
   316  	json = `{"IdentityData":{"GameInstanceId":634866135153775564.88172}}`
   317  	value = Get(json, "IdentityData.GameInstanceId")
   318  	assert(t, value.Uint() == 634866135153775616)
   319  	assert(t, value.Int() == 634866135153775616)
   320  	assert(t, value.Float() == 634866135153775616.88172)
   321  
   322  	json = `{
   323  		"min_uint64": 0,
   324  		"max_uint64": 18446744073709551615,
   325  		"overflow_uint64": 18446744073709551616,
   326  		"min_int64": -9223372036854775808,
   327  		"max_int64": 9223372036854775807,
   328  		"overflow_int64": 9223372036854775808,
   329  		"min_uint53":  0,
   330  		"max_uint53":  4503599627370495,
   331  		"overflow_uint53": 4503599627370496,
   332  		"min_int53": -2251799813685248,
   333  		"max_int53": 2251799813685247,
   334  		"overflow_int53": 2251799813685248
   335  	}`
   336  
   337  	assert(t, Get(json, "min_uint53").Uint() == 0)
   338  	assert(t, Get(json, "max_uint53").Uint() == 4503599627370495)
   339  	assert(t, Get(json, "overflow_uint53").Int() == 4503599627370496)
   340  	assert(t, Get(json, "min_int53").Int() == -2251799813685248)
   341  	assert(t, Get(json, "max_int53").Int() == 2251799813685247)
   342  	assert(t, Get(json, "overflow_int53").Int() == 2251799813685248)
   343  	assert(t, Get(json, "min_uint64").Uint() == 0)
   344  	assert(t, Get(json, "max_uint64").Uint() == 18446744073709551615)
   345  	// this next value overflows the max uint64 by one which will just
   346  	// flip the number to zero
   347  	assert(t, Get(json, "overflow_uint64").Int() == 0)
   348  	assert(t, Get(json, "min_int64").Int() == -9223372036854775808)
   349  	assert(t, Get(json, "max_int64").Int() == 9223372036854775807)
   350  	// this next value overflows the max int64 by one which will just
   351  	// flip the number to the negative sign.
   352  	assert(t, Get(json, "overflow_int64").Int() == -9223372036854775808)
   353  }
   354  
   355  func TestIssue38(t *testing.T) {
   356  	// These should not fail, even though the unicode is invalid.
   357  	Get(`["S3O PEDRO DO BUTI\udf93"]`, "0")
   358  	Get(`["S3O PEDRO DO BUTI\udf93asdf"]`, "0")
   359  	Get(`["S3O PEDRO DO BUTI\udf93\u"]`, "0")
   360  	Get(`["S3O PEDRO DO BUTI\udf93\u1"]`, "0")
   361  	Get(`["S3O PEDRO DO BUTI\udf93\u13"]`, "0")
   362  	Get(`["S3O PEDRO DO BUTI\udf93\u134"]`, "0")
   363  	Get(`["S3O PEDRO DO BUTI\udf93\u1345"]`, "0")
   364  	Get(`["S3O PEDRO DO BUTI\udf93\u1345asd"]`, "0")
   365  }
   366  
   367  func TestTypes(t *testing.T) {
   368  	assert(t, (Result{Type: String}).Type.String() == "String")
   369  	assert(t, (Result{Type: Number}).Type.String() == "Number")
   370  	assert(t, (Result{Type: Null}).Type.String() == "Null")
   371  	assert(t, (Result{Type: False}).Type.String() == "False")
   372  	assert(t, (Result{Type: True}).Type.String() == "True")
   373  	assert(t, (Result{Type: JSON}).Type.String() == "JSON")
   374  	assert(t, (Result{Type: 100}).Type.String() == "")
   375  	// bool
   376  	assert(t, (Result{Type: True}).Bool() == true)
   377  	assert(t, (Result{Type: False}).Bool() == false)
   378  	assert(t, (Result{Type: Number, Num: 1}).Bool() == true)
   379  	assert(t, (Result{Type: Number, Num: 0}).Bool() == false)
   380  	assert(t, (Result{Type: String, Str: "1"}).Bool() == true)
   381  	assert(t, (Result{Type: String, Str: "T"}).Bool() == true)
   382  	assert(t, (Result{Type: String, Str: "t"}).Bool() == true)
   383  	assert(t, (Result{Type: String, Str: "true"}).Bool() == true)
   384  	assert(t, (Result{Type: String, Str: "True"}).Bool() == true)
   385  	assert(t, (Result{Type: String, Str: "TRUE"}).Bool() == true)
   386  	assert(t, (Result{Type: String, Str: "tRuE"}).Bool() == true)
   387  	assert(t, (Result{Type: String, Str: "0"}).Bool() == false)
   388  	assert(t, (Result{Type: String, Str: "f"}).Bool() == false)
   389  	assert(t, (Result{Type: String, Str: "F"}).Bool() == false)
   390  	assert(t, (Result{Type: String, Str: "false"}).Bool() == false)
   391  	assert(t, (Result{Type: String, Str: "False"}).Bool() == false)
   392  	assert(t, (Result{Type: String, Str: "FALSE"}).Bool() == false)
   393  	assert(t, (Result{Type: String, Str: "fAlSe"}).Bool() == false)
   394  	assert(t, (Result{Type: String, Str: "random"}).Bool() == false)
   395  
   396  	// int
   397  	assert(t, (Result{Type: String, Str: "1"}).Int() == 1)
   398  	assert(t, (Result{Type: True}).Int() == 1)
   399  	assert(t, (Result{Type: False}).Int() == 0)
   400  	assert(t, (Result{Type: Number, Num: 1}).Int() == 1)
   401  	// uint
   402  	assert(t, (Result{Type: String, Str: "1"}).Uint() == 1)
   403  	assert(t, (Result{Type: True}).Uint() == 1)
   404  	assert(t, (Result{Type: False}).Uint() == 0)
   405  	assert(t, (Result{Type: Number, Num: 1}).Uint() == 1)
   406  	// float
   407  	assert(t, (Result{Type: String, Str: "1"}).Float() == 1)
   408  	assert(t, (Result{Type: True}).Float() == 1)
   409  	assert(t, (Result{Type: False}).Float() == 0)
   410  	assert(t, (Result{Type: Number, Num: 1}).Float() == 1)
   411  }
   412  
   413  func TestForEach(t *testing.T) {
   414  	Result{}.ForEach(nil)
   415  	Result{Type: String, Str: "Hello"}.ForEach(func(_, value Result) bool {
   416  		assert(t, value.String() == "Hello")
   417  		return false
   418  	})
   419  	Result{Type: JSON, Raw: "*invalid*"}.ForEach(nil)
   420  
   421  	json := ` {"name": {"first": "Janet","last": "Prichard"},
   422  	"asd\nf":"\ud83d\udd13","age": 47}`
   423  	var count int
   424  	ParseBytes([]byte(json)).ForEach(func(key, value Result) bool {
   425  		count++
   426  		return true
   427  	})
   428  	assert(t, count == 3)
   429  	ParseBytes([]byte(`{"bad`)).ForEach(nil)
   430  	ParseBytes([]byte(`{"ok":"bad`)).ForEach(nil)
   431  }
   432  
   433  func TestMap(t *testing.T) {
   434  	assert(t, len(ParseBytes([]byte(`"asdf"`)).Map()) == 0)
   435  	assert(t, ParseBytes([]byte(`{"asdf":"ghjk"`)).Map()["asdf"].String() ==
   436  		"ghjk")
   437  	assert(t, len(Result{Type: JSON, Raw: "**invalid**"}.Map()) == 0)
   438  	assert(t, Result{Type: JSON, Raw: "**invalid**"}.Value() == nil)
   439  	assert(t, Result{Type: JSON, Raw: "{"}.Map() != nil)
   440  }
   441  
   442  func TestBasic1(t *testing.T) {
   443  	mtok := get(basicJSON, `loggy.programmers`)
   444  	var count int
   445  	mtok.ForEach(func(key, value Result) bool {
   446  		assert(t, key.Exists())
   447  		assert(t, key.String() == fmt.Sprint(count))
   448  		assert(t, key.Int() == int64(count))
   449  		count++
   450  		if count == 3 {
   451  			return false
   452  		}
   453  		if count == 1 {
   454  			i := 0
   455  			value.ForEach(func(key, value Result) bool {
   456  				switch i {
   457  				case 0:
   458  					if key.String() != "firstName" ||
   459  						value.String() != "Brett" {
   460  						t.Fatalf("expected %v/%v got %v/%v", "firstName",
   461  							"Brett", key.String(), value.String())
   462  					}
   463  				case 1:
   464  					if key.String() != "lastName" ||
   465  						value.String() != "McLaughlin" {
   466  						t.Fatalf("expected %v/%v got %v/%v", "lastName",
   467  							"McLaughlin", key.String(), value.String())
   468  					}
   469  				case 2:
   470  					if key.String() != "email" || value.String() != "aaaa" {
   471  						t.Fatalf("expected %v/%v got %v/%v", "email", "aaaa",
   472  							key.String(), value.String())
   473  					}
   474  				}
   475  				i++
   476  				return true
   477  			})
   478  		}
   479  		return true
   480  	})
   481  	if count != 3 {
   482  		t.Fatalf("expected %v, got %v", 3, count)
   483  	}
   484  }
   485  
   486  func TestBasic2(t *testing.T) {
   487  	mtok := get(basicJSON, `loggy.programmers.#[age=101].firstName`)
   488  	if mtok.String() != "1002.3" {
   489  		t.Fatalf("expected %v, got %v", "1002.3", mtok.String())
   490  	}
   491  	mtok = get(basicJSON,
   492  		`loggy.programmers.#[firstName != "Brett"].firstName`)
   493  	if mtok.String() != "Jason" {
   494  		t.Fatalf("expected %v, got %v", "Jason", mtok.String())
   495  	}
   496  	mtok = get(basicJSON, `loggy.programmers.#[firstName % "Bre*"].email`)
   497  	if mtok.String() != "aaaa" {
   498  		t.Fatalf("expected %v, got %v", "aaaa", mtok.String())
   499  	}
   500  	mtok = get(basicJSON, `loggy.programmers.#[firstName !% "Bre*"].email`)
   501  	if mtok.String() != "bbbb" {
   502  		t.Fatalf("expected %v, got %v", "bbbb", mtok.String())
   503  	}
   504  	mtok = get(basicJSON, `loggy.programmers.#[firstName == "Brett"].email`)
   505  	if mtok.String() != "aaaa" {
   506  		t.Fatalf("expected %v, got %v", "aaaa", mtok.String())
   507  	}
   508  	mtok = get(basicJSON, "loggy")
   509  	if mtok.Type != JSON {
   510  		t.Fatalf("expected %v, got %v", JSON, mtok.Type)
   511  	}
   512  	if len(mtok.Map()) != 1 {
   513  		t.Fatalf("expected %v, got %v", 1, len(mtok.Map()))
   514  	}
   515  	programmers := mtok.Map()["programmers"]
   516  	if programmers.Array()[1].Map()["firstName"].Str != "Jason" {
   517  		t.Fatalf("expected %v, got %v", "Jason",
   518  			mtok.Map()["programmers"].Array()[1].Map()["firstName"].Str)
   519  	}
   520  }
   521  
   522  func TestBasic3(t *testing.T) {
   523  	var mtok Result
   524  	if Parse(basicJSON).Get("loggy.programmers").Get("1").
   525  		Get("firstName").Str != "Jason" {
   526  		t.Fatalf("expected %v, got %v", "Jason", Parse(basicJSON).
   527  			Get("loggy.programmers").Get("1").Get("firstName").Str)
   528  	}
   529  	var token Result
   530  	if token = Parse("-102"); token.Num != -102 {
   531  		t.Fatalf("expected %v, got %v", -102, token.Num)
   532  	}
   533  	if token = Parse("102"); token.Num != 102 {
   534  		t.Fatalf("expected %v, got %v", 102, token.Num)
   535  	}
   536  	if token = Parse("102.2"); token.Num != 102.2 {
   537  		t.Fatalf("expected %v, got %v", 102.2, token.Num)
   538  	}
   539  	if token = Parse(`"hello"`); token.Str != "hello" {
   540  		t.Fatalf("expected %v, got %v", "hello", token.Str)
   541  	}
   542  	if token = Parse(`"\"he\nllo\""`); token.Str != "\"he\nllo\"" {
   543  		t.Fatalf("expected %v, got %v", "\"he\nllo\"", token.Str)
   544  	}
   545  	mtok = get(basicJSON, "loggy.programmers.#.firstName")
   546  	if len(mtok.Array()) != 4 {
   547  		t.Fatalf("expected 4, got %v", len(mtok.Array()))
   548  	}
   549  	for i, ex := range []string{"Brett", "Jason", "Elliotte", "1002.3"} {
   550  		if mtok.Array()[i].String() != ex {
   551  			t.Fatalf("expected '%v', got '%v'", ex, mtok.Array()[i].String())
   552  		}
   553  	}
   554  	mtok = get(basicJSON, "loggy.programmers.#.asd")
   555  	if mtok.Type != JSON {
   556  		t.Fatalf("expected %v, got %v", JSON, mtok.Type)
   557  	}
   558  	if len(mtok.Array()) != 0 {
   559  		t.Fatalf("expected 0, got %v", len(mtok.Array()))
   560  	}
   561  }
   562  
   563  func TestBasic4(t *testing.T) {
   564  	if get(basicJSON, "items.3.tags.#").Num != 3 {
   565  		t.Fatalf("expected 3, got %v", get(basicJSON, "items.3.tags.#").Num)
   566  	}
   567  	if get(basicJSON, "items.3.points.1.#").Num != 2 {
   568  		t.Fatalf("expected 2, got %v",
   569  			get(basicJSON, "items.3.points.1.#").Num)
   570  	}
   571  	if get(basicJSON, "items.#").Num != 8 {
   572  		t.Fatalf("expected 6, got %v", get(basicJSON, "items.#").Num)
   573  	}
   574  	if get(basicJSON, "vals.#").Num != 4 {
   575  		t.Fatalf("expected 4, got %v", get(basicJSON, "vals.#").Num)
   576  	}
   577  	if !get(basicJSON, "name.last").Exists() {
   578  		t.Fatal("expected true, got false")
   579  	}
   580  	token := get(basicJSON, "name.here")
   581  	if token.String() != "B\\\"R" {
   582  		t.Fatal("expecting 'B\\\"R'", "got", token.String())
   583  	}
   584  	token = get(basicJSON, "arr.#")
   585  	if token.String() != "6" {
   586  		fmt.Printf("%#v\n", token)
   587  		t.Fatal("expecting 6", "got", token.String())
   588  	}
   589  	token = get(basicJSON, "arr.3.hello")
   590  	if token.String() != "world" {
   591  		t.Fatal("expecting 'world'", "got", token.String())
   592  	}
   593  	_ = token.Value().(string)
   594  	token = get(basicJSON, "name.first")
   595  	if token.String() != "tom" {
   596  		t.Fatal("expecting 'tom'", "got", token.String())
   597  	}
   598  	_ = token.Value().(string)
   599  	token = get(basicJSON, "name.last")
   600  	if token.String() != "" {
   601  		t.Fatal("expecting ''", "got", token.String())
   602  	}
   603  	if token.Value() != nil {
   604  		t.Fatal("should be nil")
   605  	}
   606  }
   607  
   608  func TestBasic5(t *testing.T) {
   609  	token := get(basicJSON, "age")
   610  	if token.String() != "100" {
   611  		t.Fatal("expecting '100'", "got", token.String())
   612  	}
   613  	_ = token.Value().(float64)
   614  	token = get(basicJSON, "happy")
   615  	if token.String() != "true" {
   616  		t.Fatal("expecting 'true'", "got", token.String())
   617  	}
   618  	_ = token.Value().(bool)
   619  	token = get(basicJSON, "immortal")
   620  	if token.String() != "false" {
   621  		t.Fatal("expecting 'false'", "got", token.String())
   622  	}
   623  	_ = token.Value().(bool)
   624  	token = get(basicJSON, "noop")
   625  	if token.String() != `{"what is a wren?":"a bird"}` {
   626  		t.Fatal("expecting '"+`{"what is a wren?":"a bird"}`+"'", "got",
   627  			token.String())
   628  	}
   629  	_ = token.Value().(map[string]interface{})
   630  
   631  	if get(basicJSON, "").Value() != nil {
   632  		t.Fatal("should be nil")
   633  	}
   634  
   635  	get(basicJSON, "vals.hello")
   636  
   637  	type msi = map[string]interface{}
   638  	type fi = []interface{}
   639  	mm := Parse(basicJSON).Value().(msi)
   640  	fn := mm["loggy"].(msi)["programmers"].(fi)[1].(msi)["firstName"].(string)
   641  	if fn != "Jason" {
   642  		t.Fatalf("expecting %v, got %v", "Jason", fn)
   643  	}
   644  }
   645  
   646  func TestUnicode(t *testing.T) {
   647  	json := `{"key":0,"的情况下解":{"key":1,"的情况":2}}`
   648  	if Get(json, "的情况下解.key").Num != 1 {
   649  		t.Fatal("fail")
   650  	}
   651  	if Get(json, "的情况下解.的情况").Num != 2 {
   652  		t.Fatal("fail")
   653  	}
   654  	if Get(json, "的情况下解.的?况").Num != 2 {
   655  		t.Fatal("fail")
   656  	}
   657  	if Get(json, "的情况下解.的?*").Num != 2 {
   658  		t.Fatal("fail")
   659  	}
   660  	if Get(json, "的情况下解.*?况").Num != 2 {
   661  		t.Fatal("fail")
   662  	}
   663  	if Get(json, "的情?下解.*?况").Num != 2 {
   664  		t.Fatal("fail")
   665  	}
   666  	if Get(json, "的情下解.*?况").Num != 0 {
   667  		t.Fatal("fail")
   668  	}
   669  }
   670  
   671  func TestUnescape(t *testing.T) {
   672  	unescape(string([]byte{'\\', '\\', 0}))
   673  	unescape(string([]byte{'\\', '/', '\\', 'b', '\\', 'f'}))
   674  }
   675  
   676  func assert(t testing.TB, cond bool) {
   677  	if !cond {
   678  		panic("assert failed")
   679  	}
   680  }
   681  
   682  func TestLess(t *testing.T) {
   683  	assert(t, !Result{Type: Null}.Less(Result{Type: Null}, true))
   684  	assert(t, Result{Type: Null}.Less(Result{Type: False}, true))
   685  	assert(t, Result{Type: Null}.Less(Result{Type: True}, true))
   686  	assert(t, Result{Type: Null}.Less(Result{Type: JSON}, true))
   687  	assert(t, Result{Type: Null}.Less(Result{Type: Number}, true))
   688  	assert(t, Result{Type: Null}.Less(Result{Type: String}, true))
   689  	assert(t, !Result{Type: False}.Less(Result{Type: Null}, true))
   690  	assert(t, Result{Type: False}.Less(Result{Type: True}, true))
   691  	assert(t, Result{Type: String, Str: "abc"}.Less(Result{
   692  		Type: String,
   693  		Str:  "bcd",
   694  	}, true))
   695  	assert(t, Result{Type: String, Str: "ABC"}.Less(Result{
   696  		Type: String,
   697  		Str:  "abc",
   698  	}, true))
   699  	assert(t, !Result{Type: String, Str: "ABC"}.Less(Result{
   700  		Type: String,
   701  		Str:  "abc",
   702  	}, false))
   703  	assert(t, Result{Type: Number, Num: 123}.Less(Result{
   704  		Type: Number,
   705  		Num:  456,
   706  	}, true))
   707  	assert(t, !Result{Type: Number, Num: 456}.Less(Result{
   708  		Type: Number,
   709  		Num:  123,
   710  	}, true))
   711  	assert(t, !Result{Type: Number, Num: 456}.Less(Result{
   712  		Type: Number,
   713  		Num:  456,
   714  	}, true))
   715  	assert(t, stringLessInsensitive("abcde", "BBCDE"))
   716  	assert(t, stringLessInsensitive("abcde", "bBCDE"))
   717  	assert(t, stringLessInsensitive("Abcde", "BBCDE"))
   718  	assert(t, stringLessInsensitive("Abcde", "bBCDE"))
   719  	assert(t, !stringLessInsensitive("bbcde", "aBCDE"))
   720  	assert(t, !stringLessInsensitive("bbcde", "ABCDE"))
   721  	assert(t, !stringLessInsensitive("Bbcde", "aBCDE"))
   722  	assert(t, !stringLessInsensitive("Bbcde", "ABCDE"))
   723  	assert(t, !stringLessInsensitive("abcde", "ABCDE"))
   724  	assert(t, !stringLessInsensitive("Abcde", "ABCDE"))
   725  	assert(t, !stringLessInsensitive("abcde", "ABCDE"))
   726  	assert(t, !stringLessInsensitive("ABCDE", "ABCDE"))
   727  	assert(t, !stringLessInsensitive("abcde", "abcde"))
   728  	assert(t, !stringLessInsensitive("123abcde", "123Abcde"))
   729  	assert(t, !stringLessInsensitive("123Abcde", "123Abcde"))
   730  	assert(t, !stringLessInsensitive("123Abcde", "123abcde"))
   731  	assert(t, !stringLessInsensitive("123abcde", "123abcde"))
   732  	assert(t, !stringLessInsensitive("124abcde", "123abcde"))
   733  	assert(t, !stringLessInsensitive("124Abcde", "123Abcde"))
   734  	assert(t, !stringLessInsensitive("124Abcde", "123abcde"))
   735  	assert(t, !stringLessInsensitive("124abcde", "123abcde"))
   736  	assert(t, stringLessInsensitive("124abcde", "125abcde"))
   737  	assert(t, stringLessInsensitive("124Abcde", "125Abcde"))
   738  	assert(t, stringLessInsensitive("124Abcde", "125abcde"))
   739  	assert(t, stringLessInsensitive("124abcde", "125abcde"))
   740  }
   741  
   742  func TestIssue6(t *testing.T) {
   743  	data := `{
   744        "code": 0,
   745        "msg": "",
   746        "data": {
   747          "sz002024": {
   748            "qfqday": [
   749              [
   750                "2014-01-02",
   751                "8.93",
   752                "9.03",
   753                "9.17",
   754                "8.88",
   755                "621143.00"
   756              ],
   757              [
   758                "2014-01-03",
   759                "9.03",
   760                "9.30",
   761                "9.47",
   762                "8.98",
   763                "1624438.00"
   764              ]
   765            ]
   766          }
   767        }
   768      }`
   769  
   770  	var num []string
   771  	for _, v := range Get(data, "data.sz002024.qfqday.0").Array() {
   772  		num = append(num, v.String())
   773  	}
   774  	if fmt.Sprintf("%v", num) != "[2014-01-02 8.93 9.03 9.17 8.88 621143.00]" {
   775  		t.Fatalf("invalid result")
   776  	}
   777  }
   778  
   779  var exampleJSON = `{
   780  	"widget": {
   781  		"debug": "on",
   782  		"window": {
   783  			"title": "Sample Konfabulator Widget",
   784  			"name": "main_window",
   785  			"width": 500,
   786  			"height": 500
   787  		},
   788  		"image": {
   789  			"src": "Images/Sun.png",
   790  			"hOffset": 250,
   791  			"vOffset": 250,
   792  			"alignment": "center"
   793  		},
   794  		"text": {
   795  			"data": "Click Here",
   796  			"size": 36,
   797  			"style": "bold",
   798  			"vOffset": 100,
   799  			"alignment": "center",
   800  			"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
   801  		}
   802  	}
   803  }`
   804  
   805  func TestUnmarshalMap(t *testing.T) {
   806  	m1 := Parse(exampleJSON).Value().(map[string]interface{})
   807  	var m2 map[string]interface{}
   808  	if err := json.Unmarshal([]byte(exampleJSON), &m2); err != nil {
   809  		t.Fatal(err)
   810  	}
   811  	b1, err := json.Marshal(m1)
   812  	if err != nil {
   813  		t.Fatal(err)
   814  	}
   815  	b2, err := json.Marshal(m2)
   816  	if err != nil {
   817  		t.Fatal(err)
   818  	}
   819  	if !bytes.Equal(b1, b2) {
   820  		t.Fatal("b1 != b2")
   821  	}
   822  }
   823  
   824  func TestSingleArrayValue(t *testing.T) {
   825  	json := `{"key": "value","key2":[1,2,3,4,"A"]}`
   826  	result := Get(json, "key")
   827  	array := result.Array()
   828  	if len(array) != 1 {
   829  		t.Fatal("array is empty")
   830  	}
   831  	if array[0].String() != "value" {
   832  		t.Fatalf("got %s, should be %s", array[0].String(), "value")
   833  	}
   834  
   835  	array = Get(json, "key2.#").Array()
   836  	if len(array) != 1 {
   837  		t.Fatalf("got '%v', expected '%v'", len(array), 1)
   838  	}
   839  
   840  	array = Get(json, "key3").Array()
   841  	if len(array) != 0 {
   842  		t.Fatalf("got '%v', expected '%v'", len(array), 0)
   843  	}
   844  }
   845  
   846  var manyJSON = `  {
   847  	"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   848  	"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   849  	"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   850  	"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   851  	"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   852  	"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{
   853  	"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"hello":"world"
   854  	}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
   855  	"position":{"type":"Point","coordinates":[-115.24,33.09]},
   856  	"loves":["world peace"],
   857  	"name":{"last":"Anderson","first":"Nancy"},
   858  	"age":31
   859  	"":{"a":"emptya","b":"emptyb"},
   860  	"name.last":"Yellow",
   861  	"name.first":"Cat",
   862  }`
   863  
   864  var testWatchForFallback bool
   865  
   866  func TestManyBasic(t *testing.T) {
   867  	testWatchForFallback = true
   868  	defer func() {
   869  		testWatchForFallback = false
   870  	}()
   871  	testMany := func(shouldFallback bool, expect string, paths ...string) {
   872  		results := GetManyBytes(
   873  			[]byte(manyJSON),
   874  			paths...,
   875  		)
   876  		if len(results) != len(paths) {
   877  			t.Fatalf("expected %v, got %v", len(paths), len(results))
   878  		}
   879  		if fmt.Sprintf("%v", results) != expect {
   880  			fmt.Printf("%v\n", paths)
   881  			t.Fatalf("expected %v, got %v", expect, results)
   882  		}
   883  	}
   884  	testMany(false, "[Point]", "position.type")
   885  	testMany(false, `[emptya ["world peace"] 31]`, ".a", "loves", "age")
   886  	testMany(false, `[["world peace"]]`, "loves")
   887  	testMany(false, `[{"last":"Anderson","first":"Nancy"} Nancy]`, "name",
   888  		"name.first")
   889  	testMany(true, `[]`, strings.Repeat("a.", 40)+"hello")
   890  	res := Get(manyJSON, strings.Repeat("a.", 48)+"a")
   891  	testMany(true, `[`+res.String()+`]`, strings.Repeat("a.", 48)+"a")
   892  	// these should fallback
   893  	testMany(true, `[Cat Nancy]`, "name\\.first", "name.first")
   894  	testMany(true, `[world]`, strings.Repeat("a.", 70)+"hello")
   895  }
   896  
   897  func testMany(t *testing.T, json string, paths, expected []string) {
   898  	testManyAny(t, json, paths, expected, true)
   899  	testManyAny(t, json, paths, expected, false)
   900  }
   901  
   902  func testManyAny(t *testing.T, json string, paths, expected []string,
   903  	bytes bool,
   904  ) {
   905  	var result []Result
   906  	for i := 0; i < 2; i++ {
   907  		var which string
   908  		if i == 0 {
   909  			which = "Get"
   910  			result = nil
   911  			for j := 0; j < len(expected); j++ {
   912  				if bytes {
   913  					result = append(result, GetBytes([]byte(json), paths[j]))
   914  				} else {
   915  					result = append(result, Get(json, paths[j]))
   916  				}
   917  			}
   918  		} else if i == 1 {
   919  			which = "GetMany"
   920  			if bytes {
   921  				result = GetManyBytes([]byte(json), paths...)
   922  			} else {
   923  				result = GetMany(json, paths...)
   924  			}
   925  		}
   926  		for j := 0; j < len(expected); j++ {
   927  			if result[j].String() != expected[j] {
   928  				t.Fatalf("Using key '%s' for '%s'\nexpected '%v', got '%v'",
   929  					paths[j], which, expected[j], result[j].String())
   930  			}
   931  		}
   932  	}
   933  }
   934  
   935  func TestIssue20(t *testing.T) {
   936  	json := `{ "name": "FirstName", "name1": "FirstName1", ` +
   937  		`"address": "address1", "addressDetails": "address2", }`
   938  	paths := []string{"name", "name1", "address", "addressDetails"}
   939  	expected := []string{"FirstName", "FirstName1", "address1", "address2"}
   940  	t.Run("SingleMany", func(t *testing.T) {
   941  		testMany(t, json, paths,
   942  			expected)
   943  	})
   944  }
   945  
   946  func TestIssue21(t *testing.T) {
   947  	json := `{ "Level1Field1":3,
   948  	           "Level1Field4":4,
   949  			   "Level1Field2":{ "Level2Field1":[ "value1", "value2" ],
   950  			   "Level2Field2":{ "Level3Field1":[ { "key1":"value1" } ] } } }`
   951  	paths := []string{
   952  		"Level1Field1", "Level1Field2.Level2Field1",
   953  		"Level1Field2.Level2Field2.Level3Field1", "Level1Field4",
   954  	}
   955  	expected := []string{
   956  		"3", `[ "value1", "value2" ]`,
   957  		`[ { "key1":"value1" } ]`, "4",
   958  	}
   959  	t.Run("SingleMany", func(t *testing.T) {
   960  		testMany(t, json, paths,
   961  			expected)
   962  	})
   963  }
   964  
   965  func TestRandomMany(t *testing.T) {
   966  	var lstr string
   967  	defer func() {
   968  		if v := recover(); v != nil {
   969  			println("'" + hex.EncodeToString([]byte(lstr)) + "'")
   970  			println("'" + lstr + "'")
   971  			panic(v)
   972  		}
   973  	}()
   974  	rand.Seed(time.Now().UnixNano())
   975  	b := make([]byte, 512)
   976  	for i := 0; i < 50000; i++ {
   977  		n, err := rand.Read(b[:rand.Int()%len(b)])
   978  		if err != nil {
   979  			t.Fatal(err)
   980  		}
   981  		lstr = string(b[:n])
   982  		paths := make([]string, rand.Int()%64)
   983  		for i := range paths {
   984  			var b []byte
   985  			n := rand.Int() % 5
   986  			for j := 0; j < n; j++ {
   987  				if j > 0 {
   988  					b = append(b, '.')
   989  				}
   990  				nn := rand.Int() % 10
   991  				for k := 0; k < nn; k++ {
   992  					b = append(b, 'a'+byte(rand.Int()%26))
   993  				}
   994  			}
   995  			paths[i] = string(b)
   996  		}
   997  		GetMany(lstr, paths...)
   998  	}
   999  }
  1000  
  1001  var complicatedJSON = `
  1002  {
  1003  	"tagged": "OK",
  1004  	"Tagged": "KO",
  1005  	"NotTagged": true,
  1006  	"unsettable": 101,
  1007  	"Nested": {
  1008  		"Yellow": "Green",
  1009  		"yellow": "yellow"
  1010  	},
  1011  	"nestedTagged": {
  1012  		"Green": "Green",
  1013  		"Map": {
  1014  			"this": "that",
  1015  			"and": "the other thing"
  1016  		},
  1017  		"Ints": {
  1018  			"Uint": 99,
  1019  			"Uint16": 16,
  1020  			"Uint32": 32,
  1021  			"Uint64": 65
  1022  		},
  1023  		"Uints": {
  1024  			"int": -99,
  1025  			"Int": -98,
  1026  			"Int16": -16,
  1027  			"Int32": -32,
  1028  			"int64": -64,
  1029  			"Int64": -65
  1030  		},
  1031  		"Uints": {
  1032  			"Float32": 32.32,
  1033  			"Float64": 64.64
  1034  		},
  1035  		"Byte": 254,
  1036  		"Bool": true
  1037  	},
  1038  	"LeftOut": "you shouldn't be here",
  1039  	"SelfPtr": {"tagged":"OK","nestedTagged":{"Ints":{"Uint32":32}}},
  1040  	"SelfSlice": [{"tagged":"OK","nestedTagged":{"Ints":{"Uint32":32}}}],
  1041  	"SelfSlicePtr": [{"tagged":"OK","nestedTagged":{"Ints":{"Uint32":32}}}],
  1042  	"SelfPtrSlice": [{"tagged":"OK","nestedTagged":{"Ints":{"Uint32":32}}}],
  1043  	"interface": "Tile38 Rocks!",
  1044  	"Interface": "Please Download",
  1045  	"Array": [0,2,3,4,5],
  1046  	"time": "2017-05-07T13:24:43-07:00",
  1047  	"Binary": "R0lGODlhPQBEAPeo",
  1048  	"NonBinary": [9,3,100,115]
  1049  }
  1050  `
  1051  
  1052  func testvalid(t *testing.T, json string, expect bool) {
  1053  	t.Helper()
  1054  	_, ok := validpayload([]byte(json), 0)
  1055  	if ok != expect {
  1056  		t.Fatal("mismatch")
  1057  	}
  1058  }
  1059  
  1060  func TestValidBasic(t *testing.T) {
  1061  	testvalid(t, "0", true)
  1062  	testvalid(t, "00", false)
  1063  	testvalid(t, "-00", false)
  1064  	testvalid(t, "-.", false)
  1065  	testvalid(t, "-.123", false)
  1066  	testvalid(t, "0.0", true)
  1067  	testvalid(t, "10.0", true)
  1068  	testvalid(t, "10e1", true)
  1069  	testvalid(t, "10EE", false)
  1070  	testvalid(t, "10E-", false)
  1071  	testvalid(t, "10E+", false)
  1072  	testvalid(t, "10E123", true)
  1073  	testvalid(t, "10E-123", true)
  1074  	testvalid(t, "10E-0123", true)
  1075  	testvalid(t, "", false)
  1076  	testvalid(t, " ", false)
  1077  	testvalid(t, "{}", true)
  1078  	testvalid(t, "{", false)
  1079  	testvalid(t, "-", false)
  1080  	testvalid(t, "-1", true)
  1081  	testvalid(t, "-1.", false)
  1082  	testvalid(t, "-1.0", true)
  1083  	testvalid(t, " -1.0", true)
  1084  	testvalid(t, " -1.0 ", true)
  1085  	testvalid(t, "-1.0 ", true)
  1086  	testvalid(t, "-1.0 i", false)
  1087  	testvalid(t, "-1.0 i", false)
  1088  	testvalid(t, "true", true)
  1089  	testvalid(t, " true", true)
  1090  	testvalid(t, " true ", true)
  1091  	testvalid(t, " True ", false)
  1092  	testvalid(t, " tru", false)
  1093  	testvalid(t, "false", true)
  1094  	testvalid(t, " false", true)
  1095  	testvalid(t, " false ", true)
  1096  	testvalid(t, " False ", false)
  1097  	testvalid(t, " fals", false)
  1098  	testvalid(t, "null", true)
  1099  	testvalid(t, " null", true)
  1100  	testvalid(t, " null ", true)
  1101  	testvalid(t, " Null ", false)
  1102  	testvalid(t, " nul", false)
  1103  	testvalid(t, " []", true)
  1104  	testvalid(t, " [true]", true)
  1105  	testvalid(t, " [ true, null ]", true)
  1106  	testvalid(t, " [ true,]", false)
  1107  	testvalid(t, `{"hello":"world"}`, true)
  1108  	testvalid(t, `{ "hello": "world" }`, true)
  1109  	testvalid(t, `{ "hello": "world", }`, false)
  1110  	testvalid(t, `{"a":"b",}`, false)
  1111  	testvalid(t, `{"a":"b","a"}`, false)
  1112  	testvalid(t, `{"a":"b","a":}`, false)
  1113  	testvalid(t, `{"a":"b","a":1}`, true)
  1114  	testvalid(t, `{"a":"b",2"1":2}`, false)
  1115  	testvalid(t, `{"a":"b","a": 1, "c":{"hi":"there"} }`, true)
  1116  	testvalid(t, `{"a":"b","a": 1, "c":{"hi":"there", "easy":["going",`+
  1117  		`{"mixed":"bag"}]} }`, true)
  1118  	testvalid(t, `""`, true)
  1119  	testvalid(t, `"`, false)
  1120  	testvalid(t, `"\n"`, true)
  1121  	testvalid(t, `"\"`, false)
  1122  	testvalid(t, `"\\"`, true)
  1123  	testvalid(t, `"a\\b"`, true)
  1124  	testvalid(t, `"a\\b\\\"a"`, true)
  1125  	testvalid(t, `"a\\b\\\uFFAAa"`, true)
  1126  	testvalid(t, `"a\\b\\\uFFAZa"`, false)
  1127  	testvalid(t, `"a\\b\\\uFFA"`, false)
  1128  	testvalid(t, string(complicatedJSON), true)
  1129  	testvalid(t, string(exampleJSON), true)
  1130  	testvalid(t, "[-]", false)
  1131  	testvalid(t, "[-.123]", false)
  1132  }
  1133  
  1134  var jsonchars = []string{
  1135  	"{", "[", ",", ":", "}", "]", "1", "0", "true",
  1136  	"false", "null", `""`, `"\""`, `"a"`,
  1137  }
  1138  
  1139  func makeRandomJSONChars(b []byte) {
  1140  	var bb []byte
  1141  	for len(bb) < len(b) {
  1142  		bb = append(bb, jsonchars[rand.Int()%len(jsonchars)]...)
  1143  	}
  1144  	copy(b, bb[:len(b)])
  1145  }
  1146  
  1147  func TestValidRandom(t *testing.T) {
  1148  	rand.Seed(time.Now().UnixNano())
  1149  	b := make([]byte, 100000)
  1150  	start := time.Now()
  1151  	for time.Since(start) < time.Second*3 {
  1152  		n := rand.Int() % len(b)
  1153  		rand.Read(b[:n])
  1154  		validpayload(b[:n], 0)
  1155  	}
  1156  
  1157  	start = time.Now()
  1158  	for time.Since(start) < time.Second*3 {
  1159  		n := rand.Int() % len(b)
  1160  		makeRandomJSONChars(b[:n])
  1161  		validpayload(b[:n], 0)
  1162  	}
  1163  }
  1164  
  1165  func TestGetMany47(t *testing.T) {
  1166  	json := `{"bar": {"id": 99, "mybar": "my mybar" }, "foo": ` +
  1167  		`{"myfoo": [605]}}`
  1168  	paths := []string{"foo.myfoo", "bar.id", "bar.mybar", "bar.mybarx"}
  1169  	expected := []string{"[605]", "99", "my mybar", ""}
  1170  	results := GetMany(json, paths...)
  1171  	if len(expected) != len(results) {
  1172  		t.Fatalf("expected %v, got %v", len(expected), len(results))
  1173  	}
  1174  	for i, path := range paths {
  1175  		if results[i].String() != expected[i] {
  1176  			t.Fatalf("expected '%v', got '%v' for path '%v'", expected[i],
  1177  				results[i].String(), path)
  1178  		}
  1179  	}
  1180  }
  1181  
  1182  func TestGetMany48(t *testing.T) {
  1183  	json := `{"bar": {"id": 99, "xyz": "my xyz"}, "foo": {"myfoo": [605]}}`
  1184  	paths := []string{"foo.myfoo", "bar.id", "bar.xyz", "bar.abc"}
  1185  	expected := []string{"[605]", "99", "my xyz", ""}
  1186  	results := GetMany(json, paths...)
  1187  	if len(expected) != len(results) {
  1188  		t.Fatalf("expected %v, got %v", len(expected), len(results))
  1189  	}
  1190  	for i, path := range paths {
  1191  		if results[i].String() != expected[i] {
  1192  			t.Fatalf("expected '%v', got '%v' for path '%v'", expected[i],
  1193  				results[i].String(), path)
  1194  		}
  1195  	}
  1196  }
  1197  
  1198  func TestResultRawForLiteral(t *testing.T) {
  1199  	for _, lit := range []string{"null", "true", "false"} {
  1200  		result := Parse(lit)
  1201  		if result.Raw != lit {
  1202  			t.Fatalf("expected '%v', got '%v'", lit, result.Raw)
  1203  		}
  1204  	}
  1205  }
  1206  
  1207  func TestNullArray(t *testing.T) {
  1208  	n := len(Get(`{"data":null}`, "data").Array())
  1209  	if n != 0 {
  1210  		t.Fatalf("expected '%v', got '%v'", 0, n)
  1211  	}
  1212  	n = len(Get(`{}`, "data").Array())
  1213  	if n != 0 {
  1214  		t.Fatalf("expected '%v', got '%v'", 0, n)
  1215  	}
  1216  	n = len(Get(`{"data":[]}`, "data").Array())
  1217  	if n != 0 {
  1218  		t.Fatalf("expected '%v', got '%v'", 0, n)
  1219  	}
  1220  	n = len(Get(`{"data":[null]}`, "data").Array())
  1221  	if n != 1 {
  1222  		t.Fatalf("expected '%v', got '%v'", 1, n)
  1223  	}
  1224  }
  1225  
  1226  func TestIssue54(t *testing.T) {
  1227  	var r []Result
  1228  	json := `{"MarketName":null,"Nounce":6115}`
  1229  	r = GetMany(json, "Nounce", "Buys", "Sells", "Fills")
  1230  	if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" {
  1231  		t.Fatalf("expected '%v', got '%v'", "[6115]",
  1232  			strings.Replace(fmt.Sprintf("%v", r), " ", "", -1))
  1233  	}
  1234  	r = GetMany(json, "Nounce", "Buys", "Sells")
  1235  	if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" {
  1236  		t.Fatalf("expected '%v', got '%v'", "[6115]",
  1237  			strings.Replace(fmt.Sprintf("%v", r), " ", "", -1))
  1238  	}
  1239  	r = GetMany(json, "Nounce")
  1240  	if strings.Replace(fmt.Sprintf("%v", r), " ", "", -1) != "[6115]" {
  1241  		t.Fatalf("expected '%v', got '%v'", "[6115]",
  1242  			strings.Replace(fmt.Sprintf("%v", r), " ", "", -1))
  1243  	}
  1244  }
  1245  
  1246  func TestIssue55(t *testing.T) {
  1247  	json := `{"one": {"two": 2, "three": 3}, "four": 4, "five": 5}`
  1248  	results := GetMany(json, "four", "five", "one.two", "one.six")
  1249  	expected := []string{"4", "5", "2", ""}
  1250  	for i, r := range results {
  1251  		if r.String() != expected[i] {
  1252  			t.Fatalf("expected %v, got %v", expected[i], r.String())
  1253  		}
  1254  	}
  1255  }
  1256  
  1257  func TestIssue58(t *testing.T) {
  1258  	json := `{"data":[{"uid": 1},{"uid": 2}]}`
  1259  	res := Get(json, `data.#[uid!=1]`).Raw
  1260  	if res != `{"uid": 2}` {
  1261  		t.Fatalf("expected '%v', got '%v'", `{"uid": 1}`, res)
  1262  	}
  1263  }
  1264  
  1265  func TestObjectGrouping(t *testing.T) {
  1266  	json := `
  1267  [
  1268  	true,
  1269  	{"name":"tom"},
  1270  	false,
  1271  	{"name":"janet"},
  1272  	null
  1273  ]
  1274  `
  1275  	res := Get(json, "#.name")
  1276  	if res.String() != `["tom","janet"]` {
  1277  		t.Fatalf("expected '%v', got '%v'", `["tom","janet"]`, res.String())
  1278  	}
  1279  }
  1280  
  1281  func TestJSONLines(t *testing.T) {
  1282  	json := `
  1283  true
  1284  false
  1285  {"name":"tom"}
  1286  [1,2,3,4,5]
  1287  {"name":"janet"}
  1288  null
  1289  12930.1203
  1290  	`
  1291  	paths := []string{"..#", "..0", "..2.name", "..#.name", "..6", "..7"}
  1292  	ress := []string{"7", "true", "tom", `["tom","janet"]`, "12930.1203", ""}
  1293  	for i, path := range paths {
  1294  		res := Get(json, path)
  1295  		if res.String() != ress[i] {
  1296  			t.Fatalf("expected '%v', got '%v'", ress[i], res.String())
  1297  		}
  1298  	}
  1299  
  1300  	json = `
  1301  {"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
  1302  {"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
  1303  {"name": "May", "wins": []}
  1304  {"name": "Deloise", "wins": [["three of a kind", "5♣"]]}
  1305  `
  1306  
  1307  	var i int
  1308  	lines := strings.Split(strings.TrimSpace(json), "\n")
  1309  	ForEachLine(json, func(line Result) bool {
  1310  		if line.Raw != lines[i] {
  1311  			t.Fatalf("expected '%v', got '%v'", lines[i], line.Raw)
  1312  		}
  1313  		i++
  1314  		return true
  1315  	})
  1316  	if i != 4 {
  1317  		t.Fatalf("expected '%v', got '%v'", 4, i)
  1318  	}
  1319  }
  1320  
  1321  func TestNumUint64String(t *testing.T) {
  1322  	var i int64 = 9007199254740993 // 2^53 + 1
  1323  	j := fmt.Sprintf(`{"data":  [  %d, "hello" ] }`, i)
  1324  	res := Get(j, "data.0")
  1325  	if res.String() != "9007199254740993" {
  1326  		t.Fatalf("expected '%v', got '%v'", "9007199254740993", res.String())
  1327  	}
  1328  }
  1329  
  1330  func TestNumInt64String(t *testing.T) {
  1331  	var i int64 = -9007199254740993
  1332  	j := fmt.Sprintf(`{"data":[ "hello", %d ]}`, i)
  1333  	res := Get(j, "data.1")
  1334  	if res.String() != "-9007199254740993" {
  1335  		t.Fatalf("expected '%v', got '%v'", "-9007199254740993", res.String())
  1336  	}
  1337  }
  1338  
  1339  func TestNumBigString(t *testing.T) {
  1340  	i := "900719925474099301239109123101" // very big
  1341  	j := fmt.Sprintf(`{"data":[ "hello", "%s" ]}`, i)
  1342  	res := Get(j, "data.1")
  1343  	if res.String() != "900719925474099301239109123101" {
  1344  		t.Fatalf("expected '%v', got '%v'", "900719925474099301239109123101",
  1345  			res.String())
  1346  	}
  1347  }
  1348  
  1349  func TestNumFloatString(t *testing.T) {
  1350  	var i int64 = -9007199254740993
  1351  	j := fmt.Sprintf(`{"data":[ "hello", %d ]}`, i) // No quotes around value!!
  1352  	res := Get(j, "data.1")
  1353  	if res.String() != "-9007199254740993" {
  1354  		t.Fatalf("expected '%v', got '%v'", "-9007199254740993", res.String())
  1355  	}
  1356  }
  1357  
  1358  func TestDuplicateKeys(t *testing.T) {
  1359  	// this is valid json according to the JSON spec
  1360  	json := `{"name": "Alex","name": "Peter"}`
  1361  	if Parse(json).Get("name").String() !=
  1362  		Parse(json).Map()["name"].String() {
  1363  		t.Fatalf("expected '%v', got '%v'",
  1364  			Parse(json).Get("name").String(),
  1365  			Parse(json).Map()["name"].String(),
  1366  		)
  1367  	}
  1368  	if !Valid(json) {
  1369  		t.Fatal("should be valid")
  1370  	}
  1371  }
  1372  
  1373  func TestArrayValues(t *testing.T) {
  1374  	json := `{"array": ["PERSON1","PERSON2",0],}`
  1375  	values := Get(json, "array").Array()
  1376  	var output string
  1377  	for i, val := range values {
  1378  		if i > 0 {
  1379  			output += "\n"
  1380  		}
  1381  		output += fmt.Sprintf("%#v", val)
  1382  	}
  1383  	expect := strings.Join([]string{
  1384  		`gjson.Result{Type:3, Raw:"\"PERSON1\"", Str:"PERSON1", Num:0, ` +
  1385  			`Index:11, Indexes:[]int(nil)}`,
  1386  		`gjson.Result{Type:3, Raw:"\"PERSON2\"", Str:"PERSON2", Num:0, ` +
  1387  			`Index:21, Indexes:[]int(nil)}`,
  1388  		`gjson.Result{Type:2, Raw:"0", Str:"", Num:0, Index:31, Indexes:[]int(nil)}`,
  1389  	}, "\n")
  1390  	if output != expect {
  1391  		t.Fatalf("expected '%v', got '%v'", expect, output)
  1392  	}
  1393  }
  1394  
  1395  func BenchmarkValid(b *testing.B) {
  1396  	for i := 0; i < b.N; i++ {
  1397  		Valid(complicatedJSON)
  1398  	}
  1399  }
  1400  
  1401  func BenchmarkValidBytes(b *testing.B) {
  1402  	complicatedJSON := []byte(complicatedJSON)
  1403  	for i := 0; i < b.N; i++ {
  1404  		ValidBytes(complicatedJSON)
  1405  	}
  1406  }
  1407  
  1408  func BenchmarkGoStdlibValidBytes(b *testing.B) {
  1409  	complicatedJSON := []byte(complicatedJSON)
  1410  	for i := 0; i < b.N; i++ {
  1411  		json.Valid(complicatedJSON)
  1412  	}
  1413  }
  1414  
  1415  func TestModifier(t *testing.T) {
  1416  	json := `{"other":{"hello":"world"},"arr":[1,2,3,4,5,6]}`
  1417  	opts := *pretty.DefaultOptions
  1418  	opts.SortKeys = true
  1419  	exp := string(pretty.PrettyOptions([]byte(json), &opts))
  1420  	res := Get(json, `@pretty:{"sortKeys":true}`).String()
  1421  	if res != exp {
  1422  		t.Fatalf("expected '%v', got '%v'", exp, res)
  1423  	}
  1424  	res = Get(res, "@pretty|@reverse|@ugly").String()
  1425  	if res != json {
  1426  		t.Fatalf("expected '%v', got '%v'", json, res)
  1427  	}
  1428  	if res := Get(res, "@this").String(); res != json {
  1429  		t.Fatalf("expected '%v', got '%v'", json, res)
  1430  	}
  1431  	if res := Get(res, "other.@this").String(); res != `{"hello":"world"}` {
  1432  		t.Fatalf("expected '%v', got '%v'", json, res)
  1433  	}
  1434  	res = Get(res, "@pretty|@reverse|arr|@reverse|2").String()
  1435  	if res != "4" {
  1436  		t.Fatalf("expected '%v', got '%v'", "4", res)
  1437  	}
  1438  	AddModifier("case", func(json, arg string) string {
  1439  		if arg == "upper" {
  1440  			return strings.ToUpper(json)
  1441  		}
  1442  		if arg == "lower" {
  1443  			return strings.ToLower(json)
  1444  		}
  1445  		return json
  1446  	})
  1447  	res = Get(json, "other|@case:upper").String()
  1448  	if res != `{"HELLO":"WORLD"}` {
  1449  		t.Fatalf("expected '%v', got '%v'", `{"HELLO":"WORLD"}`, res)
  1450  	}
  1451  }
  1452  
  1453  func TestChaining(t *testing.T) {
  1454  	json := `{
  1455  		"info": {
  1456  			"friends": [
  1457  				{"first": "Dale", "last": "Murphy", "age": 44},
  1458  				{"first": "Roger", "last": "Craig", "age": 68},
  1459  				{"first": "Jane", "last": "Murphy", "age": 47}
  1460  			]
  1461  		}
  1462  	  }`
  1463  	res := Get(json, "info.friends|0|first").String()
  1464  	if res != "Dale" {
  1465  		t.Fatalf("expected '%v', got '%v'", "Dale", res)
  1466  	}
  1467  	res = Get(json, "info.friends|@reverse|0|age").String()
  1468  	if res != "47" {
  1469  		t.Fatalf("expected '%v', got '%v'", "47", res)
  1470  	}
  1471  	res = Get(json, "@ugly|i\\nfo|friends.0.first").String()
  1472  	if res != "Dale" {
  1473  		t.Fatalf("expected '%v', got '%v'", "Dale", res)
  1474  	}
  1475  }
  1476  
  1477  func TestSplitPipe(t *testing.T) {
  1478  	split := func(t *testing.T, path, el, er string, eo bool) {
  1479  		t.Helper()
  1480  		left, right, ok := splitPossiblePipe(path)
  1481  		// fmt.Printf("%-40s [%v] [%v] [%v]\n", path, left, right, ok)
  1482  		if left != el || right != er || ok != eo {
  1483  			t.Fatalf("expected '%v/%v/%v', got '%v/%v/%v",
  1484  				el, er, eo, left, right, ok)
  1485  		}
  1486  	}
  1487  
  1488  	split(t, "hello", "", "", false)
  1489  	split(t, "hello.world", "", "", false)
  1490  	split(t, "hello|world", "hello", "world", true)
  1491  	split(t, "hello\\|world", "", "", false)
  1492  	split(t, "hello.#", "", "", false)
  1493  	split(t, `hello.#[a|1="asdf\"|1324"]#\|that`, "", "", false)
  1494  	split(t, `hello.#[a|1="asdf\"|1324"]#|that.more|yikes`,
  1495  		`hello.#[a|1="asdf\"|1324"]#`, "that.more|yikes", true)
  1496  	split(t, `a.#[]#\|b`, "", "", false)
  1497  }
  1498  
  1499  func TestArrayEx(t *testing.T) {
  1500  	json := `
  1501  	[
  1502  		{
  1503  			"c":[
  1504  				{"a":10.11}
  1505  			]
  1506  		}, {
  1507  			"c":[
  1508  				{"a":11.11}
  1509  			]
  1510  		}
  1511  	]`
  1512  	res := Get(json, "@ugly|#.c.#[a=10.11]").String()
  1513  	if res != `[{"a":10.11}]` {
  1514  		t.Fatalf("expected '%v', got '%v'", `[{"a":10.11}]`, res)
  1515  	}
  1516  	res = Get(json, "@ugly|#.c.#").String()
  1517  	if res != `[1,1]` {
  1518  		t.Fatalf("expected '%v', got '%v'", `[1,1]`, res)
  1519  	}
  1520  	res = Get(json, "@reverse|0|c|0|a").String()
  1521  	if res != "11.11" {
  1522  		t.Fatalf("expected '%v', got '%v'", "11.11", res)
  1523  	}
  1524  	res = Get(json, "#.c|#").String()
  1525  	if res != "2" {
  1526  		t.Fatalf("expected '%v', got '%v'", "2", res)
  1527  	}
  1528  }
  1529  
  1530  func TestPipeDotMixing(t *testing.T) {
  1531  	json := `{
  1532  		"info": {
  1533  			"friends": [
  1534  				{"first": "Dale", "last": "Murphy", "age": 44},
  1535  				{"first": "Roger", "last": "Craig", "age": 68},
  1536  				{"first": "Jane", "last": "Murphy", "age": 47}
  1537  			]
  1538  		}
  1539  	  }`
  1540  	var res string
  1541  	res = Get(json, `info.friends.#[first="Dale"].last`).String()
  1542  	if res != "Murphy" {
  1543  		t.Fatalf("expected '%v', got '%v'", "Murphy", res)
  1544  	}
  1545  	res = Get(json, `info|friends.#[first="Dale"].last`).String()
  1546  	if res != "Murphy" {
  1547  		t.Fatalf("expected '%v', got '%v'", "Murphy", res)
  1548  	}
  1549  	res = Get(json, `info|friends.#[first="Dale"]|last`).String()
  1550  	if res != "Murphy" {
  1551  		t.Fatalf("expected '%v', got '%v'", "Murphy", res)
  1552  	}
  1553  	res = Get(json, `info|friends|#[first="Dale"]|last`).String()
  1554  	if res != "Murphy" {
  1555  		t.Fatalf("expected '%v', got '%v'", "Murphy", res)
  1556  	}
  1557  	res = Get(json, `@ugly|info|friends|#[first="Dale"]|last`).String()
  1558  	if res != "Murphy" {
  1559  		t.Fatalf("expected '%v', got '%v'", "Murphy", res)
  1560  	}
  1561  	res = Get(json, `@ugly|info.@ugly|friends|#[first="Dale"]|last`).String()
  1562  	if res != "Murphy" {
  1563  		t.Fatalf("expected '%v', got '%v'", "Murphy", res)
  1564  	}
  1565  	res = Get(json, `@ugly.info|@ugly.friends|#[first="Dale"]|last`).String()
  1566  	if res != "Murphy" {
  1567  		t.Fatalf("expected '%v', got '%v'", "Murphy", res)
  1568  	}
  1569  }
  1570  
  1571  func TestDeepSelectors(t *testing.T) {
  1572  	json := `{
  1573  		"info": {
  1574  			"friends": [
  1575  				{
  1576  					"first": "Dale", "last": "Murphy",
  1577  					"extra": [10,20,30],
  1578  					"details": {
  1579  						"city": "Tempe",
  1580  						"state": "Arizona"
  1581  					}
  1582  				},
  1583  				{
  1584  					"first": "Roger", "last": "Craig",
  1585  					"extra": [40,50,60],
  1586  					"details": {
  1587  						"city": "Phoenix",
  1588  						"state": "Arizona"
  1589  					}
  1590  				}
  1591  			]
  1592  		}
  1593  	  }`
  1594  	var res string
  1595  	res = Get(json, `info.friends.#[first="Dale"].extra.0`).String()
  1596  	if res != "10" {
  1597  		t.Fatalf("expected '%v', got '%v'", "10", res)
  1598  	}
  1599  	res = Get(json, `info.friends.#[first="Dale"].extra|0`).String()
  1600  	if res != "10" {
  1601  		t.Fatalf("expected '%v', got '%v'", "10", res)
  1602  	}
  1603  	res = Get(json, `info.friends.#[first="Dale"]|extra|0`).String()
  1604  	if res != "10" {
  1605  		t.Fatalf("expected '%v', got '%v'", "10", res)
  1606  	}
  1607  	res = Get(json, `info.friends.#[details.city="Tempe"].last`).String()
  1608  	if res != "Murphy" {
  1609  		t.Fatalf("expected '%v', got '%v'", "Murphy", res)
  1610  	}
  1611  	res = Get(json, `info.friends.#[details.city="Phoenix"].last`).String()
  1612  	if res != "Craig" {
  1613  		t.Fatalf("expected '%v', got '%v'", "Craig", res)
  1614  	}
  1615  	res = Get(json, `info.friends.#[details.state="Arizona"].last`).String()
  1616  	if res != "Murphy" {
  1617  		t.Fatalf("expected '%v', got '%v'", "Murphy", res)
  1618  	}
  1619  }
  1620  
  1621  func TestMultiArrayEx(t *testing.T) {
  1622  	json := `{
  1623  		"info": {
  1624  			"friends": [
  1625  				{
  1626  					"first": "Dale", "last": "Murphy", "kind": "Person",
  1627  					"cust1": true,
  1628  					"extra": [10,20,30],
  1629  					"details": {
  1630  						"city": "Tempe",
  1631  						"state": "Arizona"
  1632  					}
  1633  				},
  1634  				{
  1635  					"first": "Roger", "last": "Craig", "kind": "Person",
  1636  					"cust2": false,
  1637  					"extra": [40,50,60],
  1638  					"details": {
  1639  						"city": "Phoenix",
  1640  						"state": "Arizona"
  1641  					}
  1642  				}
  1643  			]
  1644  		}
  1645  	  }`
  1646  
  1647  	var res string
  1648  
  1649  	res = Get(json, `info.friends.#[kind="Person"]#.kind|0`).String()
  1650  	if res != "Person" {
  1651  		t.Fatalf("expected '%v', got '%v'", "Person", res)
  1652  	}
  1653  	res = Get(json, `info.friends.#.kind|0`).String()
  1654  	if res != "Person" {
  1655  		t.Fatalf("expected '%v', got '%v'", "Person", res)
  1656  	}
  1657  
  1658  	res = Get(json, `info.friends.#[kind="Person"]#.kind`).String()
  1659  	if res != `["Person","Person"]` {
  1660  		t.Fatalf("expected '%v', got '%v'", `["Person","Person"]`, res)
  1661  	}
  1662  	res = Get(json, `info.friends.#.kind`).String()
  1663  	if res != `["Person","Person"]` {
  1664  		t.Fatalf("expected '%v', got '%v'", `["Person","Person"]`, res)
  1665  	}
  1666  
  1667  	res = Get(json, `info.friends.#[kind="Person"]#|kind`).String()
  1668  	if res != `` {
  1669  		t.Fatalf("expected '%v', got '%v'", ``, res)
  1670  	}
  1671  	res = Get(json, `info.friends.#|kind`).String()
  1672  	if res != `` {
  1673  		t.Fatalf("expected '%v', got '%v'", ``, res)
  1674  	}
  1675  
  1676  	res = Get(json, `i*.f*.#[kind="Other"]#`).String()
  1677  	if res != `[]` {
  1678  		t.Fatalf("expected '%v', got '%v'", `[]`, res)
  1679  	}
  1680  }
  1681  
  1682  func TestQueries(t *testing.T) {
  1683  	json := `{
  1684  		"info": {
  1685  			"friends": [
  1686  				{
  1687  					"first": "Dale", "last": "Murphy", "kind": "Person",
  1688  					"cust1": true,
  1689  					"extra": [10,20,30],
  1690  					"details": {
  1691  						"city": "Tempe",
  1692  						"state": "Arizona"
  1693  					}
  1694  				},
  1695  				{
  1696  					"first": "Roger", "last": "Craig", "kind": "Person",
  1697  					"cust2": false,
  1698  					"extra": [40,50,60],
  1699  					"details": {
  1700  						"city": "Phoenix",
  1701  						"state": "Arizona"
  1702  					}
  1703  				}
  1704  			]
  1705  		}
  1706  	  }`
  1707  
  1708  	// numbers
  1709  	assert(t, Get(json, "i*.f*.#[extra.0<11].first").Exists())
  1710  	assert(t, Get(json, "i*.f*.#[extra.0<=11].first").Exists())
  1711  	assert(t, !Get(json, "i*.f*.#[extra.0<10].first").Exists())
  1712  	assert(t, Get(json, "i*.f*.#[extra.0<=10].first").Exists())
  1713  	assert(t, Get(json, "i*.f*.#[extra.0=10].first").Exists())
  1714  	assert(t, !Get(json, "i*.f*.#[extra.0=11].first").Exists())
  1715  	assert(t, Get(json, "i*.f*.#[extra.0!=10].first").String() == "Roger")
  1716  	assert(t, Get(json, "i*.f*.#[extra.0>10].first").String() == "Roger")
  1717  	assert(t, Get(json, "i*.f*.#[extra.0>=10].first").String() == "Dale")
  1718  
  1719  	// strings
  1720  	assert(t, Get(json, `i*.f*.#[extra.0<"11"].first`).Exists())
  1721  	assert(t, Get(json, `i*.f*.#[first>"Dale"].last`).String() == "Craig")
  1722  	assert(t, Get(json, `i*.f*.#[first>="Dale"].last`).String() == "Murphy")
  1723  	assert(t, Get(json, `i*.f*.#[first="Dale"].last`).String() == "Murphy")
  1724  	assert(t, Get(json, `i*.f*.#[first!="Dale"].last`).String() == "Craig")
  1725  	assert(t, !Get(json, `i*.f*.#[first<"Dale"].last`).Exists())
  1726  	assert(t, Get(json, `i*.f*.#[first<="Dale"].last`).Exists())
  1727  	assert(t, Get(json, `i*.f*.#[first%"Da*"].last`).Exists())
  1728  	assert(t, Get(json, `i*.f*.#[first%"Dale"].last`).Exists())
  1729  	assert(t, Get(json, `i*.f*.#[first%"*a*"]#|#`).String() == "1")
  1730  	assert(t, Get(json, `i*.f*.#[first%"*e*"]#|#`).String() == "2")
  1731  	assert(t, Get(json, `i*.f*.#[first!%"*e*"]#|#`).String() == "0")
  1732  
  1733  	// trues
  1734  	assert(t, Get(json, `i*.f*.#[cust1=true].first`).String() == "Dale")
  1735  	assert(t, Get(json, `i*.f*.#[cust2=false].first`).String() == "Roger")
  1736  	assert(t, Get(json, `i*.f*.#[cust1!=false].first`).String() == "Dale")
  1737  	assert(t, Get(json, `i*.f*.#[cust2!=true].first`).String() == "Roger")
  1738  	assert(t, !Get(json, `i*.f*.#[cust1>true].first`).Exists())
  1739  	assert(t, Get(json, `i*.f*.#[cust1>=true].first`).Exists())
  1740  	assert(t, !Get(json, `i*.f*.#[cust2<false].first`).Exists())
  1741  	assert(t, Get(json, `i*.f*.#[cust2<=false].first`).Exists())
  1742  }
  1743  
  1744  func TestQueryArrayValues(t *testing.T) {
  1745  	json := `{
  1746  		"artists": [
  1747  			["Bob Dylan"],
  1748  			"John Lennon",
  1749  			"Mick Jagger",
  1750  			"Elton John",
  1751  			"Michael Jackson",
  1752  			"John Smith",
  1753  			true,
  1754  			123,
  1755  			456,
  1756  			false,
  1757  			null
  1758  		]
  1759  	}`
  1760  	assert(t, Get(json, `a*.#[0="Bob Dylan"]#|#`).String() == "1")
  1761  	assert(t, Get(json, `a*.#[0="Bob Dylan 2"]#|#`).String() == "0")
  1762  	assert(t, Get(json, `a*.#[%"John*"]#|#`).String() == "2")
  1763  	assert(t, Get(json, `a*.#[_%"John*"]#|#`).String() == "0")
  1764  	assert(t, Get(json, `a*.#[="123"]#|#`).String() == "1")
  1765  }
  1766  
  1767  func TestParenQueries(t *testing.T) {
  1768  	json := `{
  1769  		"friends": [{"a":10},{"a":20},{"a":30},{"a":40}]
  1770  	}`
  1771  	assert(t, Get(json, "friends.#(a>9)#|#").Int() == 4)
  1772  	assert(t, Get(json, "friends.#(a>10)#|#").Int() == 3)
  1773  	assert(t, Get(json, "friends.#(a>40)#|#").Int() == 0)
  1774  }
  1775  
  1776  func TestSubSelectors(t *testing.T) {
  1777  	json := `{
  1778  		"info": {
  1779  			"friends": [
  1780  				{
  1781  					"first": "Dale", "last": "Murphy", "kind": "Person",
  1782  					"cust1": true,
  1783  					"extra": [10,20,30],
  1784  					"details": {
  1785  						"city": "Tempe",
  1786  						"state": "Arizona"
  1787  					}
  1788  				},
  1789  				{
  1790  					"first": "Roger", "last": "Craig", "kind": "Person",
  1791  					"cust2": false,
  1792  					"extra": [40,50,60],
  1793  					"details": {
  1794  						"city": "Phoenix",
  1795  						"state": "Arizona"
  1796  					}
  1797  				}
  1798  			]
  1799  		}
  1800  	  }`
  1801  	assert(t, Get(json, "[]").String() == "[]")
  1802  	assert(t, Get(json, "{}").String() == "{}")
  1803  	res := Get(json, `{`+
  1804  		`abc:info.friends.0.first,`+
  1805  		`info.friends.1.last,`+
  1806  		`"a`+"\r"+`a":info.friends.0.kind,`+
  1807  		`"abc":info.friends.1.kind,`+
  1808  		`{123:info.friends.1.cust2},`+
  1809  		`[info.friends.#[details.city="Phoenix"]#|#]`+
  1810  		`}.@pretty.@ugly`).String()
  1811  	// println(res)
  1812  	// {"abc":"Dale","last":"Craig","\"a\ra\"":"Person","_":{"123":false},"_":[1]}
  1813  	assert(t, Get(res, "abc").String() == "Dale")
  1814  	assert(t, Get(res, "last").String() == "Craig")
  1815  	assert(t, Get(res, "\"a\ra\"").String() == "Person")
  1816  	assert(t, Get(res, "@reverse.abc").String() == "Person")
  1817  	assert(t, Get(res, "_.123").String() == "false")
  1818  	assert(t, Get(res, "@reverse._.0").String() == "1")
  1819  	assert(t, Get(json, "info.friends.[0.first,1.extra.0]").String() ==
  1820  		`["Dale",40]`)
  1821  	assert(t, Get(json, "info.friends.#.[first,extra.0]").String() ==
  1822  		`[["Dale",10],["Roger",40]]`)
  1823  }
  1824  
  1825  func TestArrayCountRawOutput(t *testing.T) {
  1826  	assert(t, Get(`[1,2,3,4]`, "#").Raw == "4")
  1827  }
  1828  
  1829  func TestParseQuery(t *testing.T) {
  1830  	var path, op, value, remain string
  1831  	var ok bool
  1832  
  1833  	path, op, value, remain, _, _, ok = parseQuery(`#(service_roles.#(=="one").()==asdf).cap`)
  1834  	assert(t, ok &&
  1835  		path == `service_roles.#(=="one").()` &&
  1836  		op == "=" &&
  1837  		value == `asdf` &&
  1838  		remain == `.cap`)
  1839  
  1840  	path, op, value, remain, _, _, ok = parseQuery(`#(first_name%"Murphy").last`)
  1841  	assert(t, ok &&
  1842  		path == `first_name` &&
  1843  		op == `%` &&
  1844  		value == `"Murphy"` &&
  1845  		remain == `.last`)
  1846  
  1847  	path, op, value, remain, _, _, ok = parseQuery(`#( first_name !% "Murphy" ).last`)
  1848  	assert(t, ok &&
  1849  		path == `first_name` &&
  1850  		op == `!%` &&
  1851  		value == `"Murphy"` &&
  1852  		remain == `.last`)
  1853  
  1854  	path, op, value, remain, _, _, ok = parseQuery(`#(service_roles.#(=="one"))`)
  1855  	assert(t, ok &&
  1856  		path == `service_roles.#(=="one")` &&
  1857  		op == `` &&
  1858  		value == `` &&
  1859  		remain == ``)
  1860  
  1861  	path, op, value, remain, _, _, ok = parseQuery(`#(a\("\"(".#(=="o\"(ne")%"ab\")").remain`)
  1862  	assert(t, ok &&
  1863  		path == `a\("\"(".#(=="o\"(ne")` &&
  1864  		op == "%" &&
  1865  		value == `"ab\")"` &&
  1866  		remain == `.remain`)
  1867  }
  1868  
  1869  func TestParentSubQuery(t *testing.T) {
  1870  	json := `{
  1871  		"topology": {
  1872  		  "instances": [
  1873  			{
  1874  			  "service_version": "1.2.3",
  1875  			  "service_locale": {"lang": "en"},
  1876  			  "service_roles": ["one", "two"]
  1877  			},
  1878  			{
  1879  			  "service_version": "1.2.4",
  1880  			  "service_locale": {"lang": "th"},
  1881  			  "service_roles": ["three", "four"]
  1882  			},
  1883  			{
  1884  			  "service_version": "1.2.2",
  1885  			  "service_locale": {"lang": "en"},
  1886  			  "service_roles": ["one"]
  1887  			}
  1888  		  ]
  1889  		}
  1890  	  }`
  1891  	res := Get(json, `topology.instances.#( service_roles.#(=="one"))#.service_version`)
  1892  	// should return two instances
  1893  	assert(t, res.String() == `["1.2.3","1.2.2"]`)
  1894  }
  1895  
  1896  func TestSingleModifier(t *testing.T) {
  1897  	data := `{"@key": "value"}`
  1898  	assert(t, Get(data, "@key").String() == "value")
  1899  	assert(t, Get(data, "\\@key").String() == "value")
  1900  }
  1901  
  1902  func TestModifiersInMultipaths(t *testing.T) {
  1903  	AddModifier("case", func(json, arg string) string {
  1904  		if arg == "upper" {
  1905  			return strings.ToUpper(json)
  1906  		}
  1907  		if arg == "lower" {
  1908  			return strings.ToLower(json)
  1909  		}
  1910  		return json
  1911  	})
  1912  	json := `{"friends": [
  1913  		{"age": 44, "first": "Dale", "last": "Murphy"},
  1914  		{"age": 68, "first": "Roger", "last": "Craig"},
  1915  		{"age": 47, "first": "Jane", "last": "Murphy"}
  1916  	]}`
  1917  
  1918  	res := Get(json, `friends.#.{age,first|@case:upper}|@ugly`)
  1919  	exp := `[{"age":44,"@case:upper":"DALE"},{"age":68,"@case:upper":"ROGER"},{"age":47,"@case:upper":"JANE"}]`
  1920  	assert(t, res.Raw == exp)
  1921  
  1922  	res = Get(json, `{friends.#.{age,first:first|@case:upper}|0.first}`)
  1923  	exp = `{"first":"DALE"}`
  1924  	assert(t, res.Raw == exp)
  1925  
  1926  	res = Get(readmeJSON, `{"children":children|@case:upper,"name":name.first,"age":age}`)
  1927  	exp = `{"children":["SARA","ALEX","JACK"],"name":"Tom","age":37}`
  1928  	assert(t, res.Raw == exp)
  1929  }
  1930  
  1931  func TestIssue141(t *testing.T) {
  1932  	json := `{"data": [{"q": 11, "w": 12}, {"q": 21, "w": 22}, {"q": 31, "w": 32} ], "sql": "some stuff here"}`
  1933  	assert(t, Get(json, "data.#").Int() == 3)
  1934  	assert(t, Get(json, "data.#.{q}|@ugly").Raw == `[{"q":11},{"q":21},{"q":31}]`)
  1935  	assert(t, Get(json, "data.#.q|@ugly").Raw == `[11,21,31]`)
  1936  }
  1937  
  1938  func TestChainedModifierStringArgs(t *testing.T) {
  1939  	// issue #143
  1940  	AddModifier("push", func(json, arg string) string {
  1941  		json = strings.TrimSpace(json)
  1942  		if len(json) < 2 || !Parse(json).IsArray() {
  1943  			return json
  1944  		}
  1945  		json = strings.TrimSpace(json[1 : len(json)-1])
  1946  		if len(json) == 0 {
  1947  			return "[" + arg + "]"
  1948  		}
  1949  		return "[" + json + "," + arg + "]"
  1950  	})
  1951  	res := Get("[]", `@push:"2"|@push:"3"|@push:{"a":"b","c":["e","f"]}|@push:true|@push:10.23`)
  1952  	assert(t, res.String() == `["2","3",{"a":"b","c":["e","f"]},true,10.23]`)
  1953  }
  1954  
  1955  func TestFlatten(t *testing.T) {
  1956  	json := `[1,[2],[3,4],[5,[6,[7]]],{"hi":"there"},8,[9]]`
  1957  	assert(t, Get(json, "@flatten").String() == `[1,2,3,4,5,[6,[7]],{"hi":"there"},8,9]`)
  1958  	assert(t, Get(json, `@flatten:{"deep":true}`).String() == `[1,2,3,4,5,6,7,{"hi":"there"},8,9]`)
  1959  	assert(t, Get(`{"9999":1234}`, "@flatten").String() == `{"9999":1234}`)
  1960  }
  1961  
  1962  func TestJoin(t *testing.T) {
  1963  	assert(t, Get(`[{},{}]`, "@join").String() == `{}`)
  1964  	assert(t, Get(`[{"a":1},{"b":2}]`, "@join").String() == `{"a":1,"b":2}`)
  1965  	assert(t, Get(`[{"a":1,"b":1},{"b":2}]`, "@join").String() == `{"a":1,"b":2}`)
  1966  	assert(t, Get(`[{"a":1,"b":1},{"b":2},5,{"c":3}]`, "@join").String() == `{"a":1,"b":2,"c":3}`)
  1967  	assert(t, Get(`[{"a":1,"b":1},{"b":2},5,{"c":3}]`, `@join:{"preserve":true}`).String() == `{"a":1,"b":1,"b":2,"c":3}`)
  1968  	assert(t, Get(`[{"a":1,"b":1},{"b":2},5,{"c":3}]`, `@join:{"preserve":true}.b`).String() == `1`)
  1969  	assert(t, Get(`{"9999":1234}`, "@join").String() == `{"9999":1234}`)
  1970  }
  1971  
  1972  func TestValid(t *testing.T) {
  1973  	assert(t, Get("[{}", "@valid").Exists() == false)
  1974  	assert(t, Get("[{}]", "@valid").Exists() == true)
  1975  }
  1976  
  1977  // https://github.com/tidwall/gjson/issues/152
  1978  func TestJoin152(t *testing.T) {
  1979  	json := `{
  1980  		"distance": 1374.0,
  1981  		"validFrom": "2005-11-14",
  1982  		"historical": {
  1983  		  "type": "Day",
  1984  		  "name": "last25Hours",
  1985  		  "summary": {
  1986  			"units": {
  1987  			  "temperature": "C",
  1988  			  "wind": "m/s",
  1989  			  "snow": "cm",
  1990  			  "precipitation": "mm"
  1991  			},
  1992  			"days": [
  1993  			  {
  1994  				"time": "2020-02-08",
  1995  				"hours": [
  1996  				  {
  1997  					"temperature": {
  1998  					  "min": -2.0,
  1999  					  "max": -1.6,
  2000  					  "value": -1.6
  2001  					},
  2002  					"wind": {},
  2003  					"precipitation": {},
  2004  					"humidity": {
  2005  					  "value": 92.0
  2006  					},
  2007  					"snow": {
  2008  					  "depth": 49.0
  2009  					},
  2010  					"time": "2020-02-08T16:00:00+01:00"
  2011  				  },
  2012  				  {
  2013  					"temperature": {
  2014  					  "min": -1.7,
  2015  					  "max": -1.3,
  2016  					  "value": -1.3
  2017  					},
  2018  					"wind": {},
  2019  					"precipitation": {},
  2020  					"humidity": {
  2021  					  "value": 92.0
  2022  					},
  2023  					"snow": {
  2024  					  "depth": 49.0
  2025  					},
  2026  					"time": "2020-02-08T17:00:00+01:00"
  2027  				  },
  2028  				  {
  2029  					"temperature": {
  2030  					  "min": -1.3,
  2031  					  "max": -0.9,
  2032  					  "value": -1.2
  2033  					},
  2034  					"wind": {},
  2035  					"precipitation": {},
  2036  					"humidity": {
  2037  					  "value": 91.0
  2038  					},
  2039  					"snow": {
  2040  					  "depth": 49.0
  2041  					},
  2042  					"time": "2020-02-08T18:00:00+01:00"
  2043  				  }
  2044  				]
  2045  			  },
  2046  			  {
  2047  				"time": "2020-02-09",
  2048  				"hours": [
  2049  				  {
  2050  					"temperature": {
  2051  					  "min": -1.7,
  2052  					  "max": -0.9,
  2053  					  "value": -1.5
  2054  					},
  2055  					"wind": {},
  2056  					"precipitation": {},
  2057  					"humidity": {
  2058  					  "value": 91.0
  2059  					},
  2060  					"snow": {
  2061  					  "depth": 49.0
  2062  					},
  2063  					"time": "2020-02-09T00:00:00+01:00"
  2064  				  },
  2065  				  {
  2066  					"temperature": {
  2067  					  "min": -1.5,
  2068  					  "max": 0.9,
  2069  					  "value": 0.2
  2070  					},
  2071  					"wind": {},
  2072  					"precipitation": {},
  2073  					"humidity": {
  2074  					  "value": 67.0
  2075  					},
  2076  					"snow": {
  2077  					  "depth": 49.0
  2078  					},
  2079  					"time": "2020-02-09T01:00:00+01:00"
  2080  				  }
  2081  				]
  2082  			  }
  2083  			]
  2084  		  }
  2085  		}
  2086  	  }`
  2087  
  2088  	res := Get(json, "historical.summary.days.#.hours|@flatten|#.humidity.value")
  2089  	assert(t, res.Raw == `[92.0,92.0,91.0,91.0,67.0]`)
  2090  }
  2091  
  2092  func TestVariousFuzz(t *testing.T) {
  2093  	// Issue #192	assert(t, squash(`"000"hello`) == `"000"`)
  2094  	assert(t, squash(`"000"`) == `"000"`)
  2095  	assert(t, squash(`"000`) == `"000`)
  2096  	assert(t, squash(`"`) == `"`)
  2097  
  2098  	assert(t, squash(`[000]hello`) == `[000]`)
  2099  	assert(t, squash(`[000]`) == `[000]`)
  2100  	assert(t, squash(`[000`) == `[000`)
  2101  	assert(t, squash(`[`) == `[`)
  2102  	assert(t, squash(`]`) == `]`)
  2103  
  2104  	testJSON := `0.#[[{}]].@valid:"000`
  2105  	Get(testJSON, testJSON)
  2106  
  2107  	// Issue #195
  2108  	testJSON = `\************************************` +
  2109  		`**********{**",**,,**,**,**,**,"",**,**,**,**,**,**,**,**,**,**]`
  2110  	Get(testJSON, testJSON)
  2111  
  2112  	// Issue #196
  2113  	testJSON = `[#.@pretty.@join:{""[]""preserve"3,"][{]]]`
  2114  	Get(testJSON, testJSON)
  2115  
  2116  	// Issue #237
  2117  	testJSON1 := `["*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,,,,,,"]`
  2118  	testJSON2 := `#[%"*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,,,,,,""*,*"]`
  2119  	Get(testJSON1, testJSON2)
  2120  }
  2121  
  2122  func TestSubpathsWithMultipaths(t *testing.T) {
  2123  	const json = `
  2124  [
  2125    {"a": 1},
  2126    {"a": 2, "values": ["a", "b", "c", "d", "e"]},
  2127    true,
  2128    ["a", "b", "c", "d", "e"],
  2129    4
  2130  ]
  2131  `
  2132  	assert(t, Get(json, `1.values.@ugly`).Raw == `["a","b","c","d","e"]`)
  2133  	assert(t, Get(json, `1.values.[0,3]`).Raw == `["a","d"]`)
  2134  	assert(t, Get(json, `3.@ugly`).Raw == `["a","b","c","d","e"]`)
  2135  	assert(t, Get(json, `3.[0,3]`).Raw == `["a","d"]`)
  2136  	assert(t, Get(json, `#.@ugly`).Raw == `[{"a":1},{"a":2,"values":["a","b","c","d","e"]},true,["a","b","c","d","e"],4]`)
  2137  	assert(t, Get(json, `#.[0,3]`).Raw == `[[],[],[],["a","d"],[]]`)
  2138  }
  2139  
  2140  func TestFlattenRemoveNonExist(t *testing.T) {
  2141  	raw := Get("[[1],[2,[[],[3]],[4,[5],[],[[[6]]]]]]", `@flatten:{"deep":true}`).Raw
  2142  	assert(t, raw == "[1,2,3,4,5,6]")
  2143  }
  2144  
  2145  func TestPipeEmptyArray(t *testing.T) {
  2146  	raw := Get("[]", `#(hello)#`).Raw
  2147  	assert(t, raw == "[]")
  2148  }
  2149  
  2150  func TestEncodedQueryString(t *testing.T) {
  2151  	json := `{
  2152  		"friends": [
  2153  			{"first": "Dale", "last": "Mur\nphy", "age": 44},
  2154  			{"first": "Roger", "last": "Craig", "age": 68},
  2155  			{"first": "Jane", "last": "Murphy", "age": 47}
  2156  		]
  2157  	}`
  2158  	assert(t, Get(json, `friends.#(last=="Mur\nphy").age`).Int() == 44)
  2159  	assert(t, Get(json, `friends.#(last=="Murphy").age`).Int() == 47)
  2160  }
  2161  
  2162  func TestTildeQueries(t *testing.T) {
  2163  	json := `{
  2164  		"vals": [
  2165  			{ "a": 1, "b": "data" },
  2166  			{ "a": 2, "b": true },
  2167  			{ "a": 3, "b": false },
  2168  			{ "a": 4, "b": "0" },
  2169  			{ "a": 5, "b": 0 },
  2170  			{ "a": 6, "b": "1" },
  2171  			{ "a": 7, "b": 1 },
  2172  			{ "a": 8, "b": "true" },
  2173  			{ "a": 9, "b": false },
  2174  			{ "a": 10, "b": null },
  2175  			{ "a": 11 }
  2176  		]
  2177  	}`
  2178  	trues := Get(json, `vals.#(b==~true)#.a`).Raw
  2179  	truesNOT := Get(json, `vals.#(b!=~true)#.a`).Raw
  2180  	falses := Get(json, `vals.#(b==~false)#.a`).Raw
  2181  	falsesNOT := Get(json, `vals.#(b!=~false)#.a`).Raw
  2182  	nulls := Get(json, `vals.#(b==~null)#.a`).Raw
  2183  	nullsNOT := Get(json, `vals.#(b!=~null)#.a`).Raw
  2184  	exists := Get(json, `vals.#(b==~*)#.a`).Raw
  2185  	existsNOT := Get(json, `vals.#(b!=~*)#.a`).Raw
  2186  
  2187  	assert(t, trues == "[2,6,7,8]")
  2188  	assert(t, truesNOT == "[1,3,4,5,9,10,11]")
  2189  	assert(t, falses == "[3,4,5,9,10,11]")
  2190  	assert(t, falsesNOT == "[1,2,6,7,8]")
  2191  	assert(t, nulls == "[10,11]")
  2192  	assert(t, nullsNOT == "[1,2,3,4,5,6,7,8,9]")
  2193  	assert(t, exists == "[1,2,3,4,5,6,7,8,9,10]")
  2194  	assert(t, existsNOT == "[11]")
  2195  	json = `{
  2196  		"vals": [
  2197  		  { "a": 1, "b": "something" },
  2198  		  { "a": 2, "b": "else" },
  2199  		  { "a": 3, "b": false },
  2200  		  { "a": 4, "b": "0" },
  2201  		  { "a": 5, "b": 0 },
  2202  		  { "a": 6, "b": "1" },
  2203  		  { "a": 7, "b": 1 },
  2204  		  { "a": 8, "b": "true" },
  2205  		  { "a": 9, "b": false },
  2206  		  { "a": 10, "b": null },
  2207  		  { "a": 11 }
  2208  		],
  2209  		"anything": "else"
  2210  	}`
  2211  	trues = Get(json, `vals.#(b==~true)#.a`).Raw
  2212  	truesNOT = Get(json, `vals.#(b!=~true)#.a`).Raw
  2213  	falses = Get(json, `vals.#(b==~false)#.a`).Raw
  2214  	falsesNOT = Get(json, `vals.#(b!=~false)#.a`).Raw
  2215  	nulls = Get(json, `vals.#(b==~null)#.a`).Raw
  2216  	nullsNOT = Get(json, `vals.#(b!=~null)#.a`).Raw
  2217  	exists = Get(json, `vals.#(b==~*)#.a`).Raw
  2218  	existsNOT = Get(json, `vals.#(b!=~*)#.a`).Raw
  2219  	assert(t, trues == "[6,7,8]")
  2220  	assert(t, truesNOT == "[1,2,3,4,5,9,10,11]")
  2221  	assert(t, falses == "[3,4,5,9,10,11]")
  2222  	assert(t, falsesNOT == "[1,2,6,7,8]")
  2223  	assert(t, nulls == "[10,11]")
  2224  	assert(t, nullsNOT == "[1,2,3,4,5,6,7,8,9]")
  2225  	assert(t, exists == "[1,2,3,4,5,6,7,8,9,10]")
  2226  	assert(t, existsNOT == "[11]")
  2227  }
  2228  
  2229  func TestModifierDoubleQuotes(t *testing.T) {
  2230  	josn := `{
  2231  		"data": [
  2232  		  {
  2233  			"name": "Product P4",
  2234  			"productId": "1bb3",
  2235  			"vendorId": "10de"
  2236  		  },
  2237  		  {
  2238  			"name": "Product P4",
  2239  			"productId": "1cc3",
  2240  			"vendorId": "20de"
  2241  		  },
  2242  		  {
  2243  			"name": "Product P4",
  2244  			"productId": "1dd3",
  2245  			"vendorId": "30de"
  2246  		  }
  2247  		]
  2248  	  }`
  2249  	AddModifier("string", func(josn, arg string) string {
  2250  		return strconv.Quote(josn)
  2251  	})
  2252  
  2253  	res := Get(josn, "data.#.{name,value:{productId,vendorId}.@string.@ugly}")
  2254  
  2255  	assert(t, res.Raw == `[`+
  2256  		`{"name":"Product P4","value":"{\"productId\":\"1bb3\",\"vendorId\":\"10de\"}"},`+
  2257  		`{"name":"Product P4","value":"{\"productId\":\"1cc3\",\"vendorId\":\"20de\"}"},`+
  2258  		`{"name":"Product P4","value":"{\"productId\":\"1dd3\",\"vendorId\":\"30de\"}"}`+
  2259  		`]`)
  2260  }
  2261  
  2262  func TestIndexes(t *testing.T) {
  2263  	exampleJSON := `{
  2264  		"vals": [
  2265  			[1,66,{test: 3}],
  2266  			[4,5,[6]]
  2267  		],
  2268  		"objectArray":[
  2269  			{"first": "Dale", "age": 44},
  2270  			{"first": "Roger", "age": 68},
  2271  		]
  2272  	}`
  2273  
  2274  	testCases := []struct {
  2275  		path     string
  2276  		expected []string
  2277  	}{
  2278  		{
  2279  			`vals.#.1`,
  2280  			[]string{`6`, "5"},
  2281  		},
  2282  		{
  2283  			`vals.#.2`,
  2284  			[]string{"{", "["},
  2285  		},
  2286  		{
  2287  			`objectArray.#(age>43)#.first`,
  2288  			[]string{`"`, `"`},
  2289  		},
  2290  		{
  2291  			`objectArray.@reverse.#.first`,
  2292  			nil,
  2293  		},
  2294  	}
  2295  
  2296  	for _, tc := range testCases {
  2297  		r := Get(exampleJSON, tc.path)
  2298  
  2299  		assert(t, len(r.Indexes) == len(tc.expected))
  2300  
  2301  		for i, a := range r.Indexes {
  2302  			assert(t, string(exampleJSON[a]) == tc.expected[i])
  2303  		}
  2304  	}
  2305  }
  2306  
  2307  func TestIndexesMatchesRaw(t *testing.T) {
  2308  	exampleJSON := `{
  2309  		"objectArray":[
  2310  			{"first": "Jason", "age": 41},
  2311  			{"first": "Dale", "age": 44},
  2312  			{"first": "Roger", "age": 68},
  2313  			{"first": "Mandy", "age": 32}
  2314  		]
  2315  	}`
  2316  	r := Get(exampleJSON, `objectArray.#(age>43)#.first`)
  2317  	assert(t, len(r.Indexes) == 2)
  2318  	assert(t, Parse(exampleJSON[r.Indexes[0]:]).String() == "Dale")
  2319  	assert(t, Parse(exampleJSON[r.Indexes[1]:]).String() == "Roger")
  2320  	r = Get(exampleJSON, `objectArray.#(age>43)#`)
  2321  	assert(t, Parse(exampleJSON[r.Indexes[0]:]).Get("first").String() == "Dale")
  2322  	assert(t, Parse(exampleJSON[r.Indexes[1]:]).Get("first").String() == "Roger")
  2323  }
  2324  
  2325  func TestIssue240(t *testing.T) {
  2326  	nonArrayData := `{"jsonrpc":"2.0","method":"subscription","params":
  2327  		{"channel":"funny_channel","data":
  2328  			{"name":"Jason","company":"good_company","number":12345}
  2329  		}
  2330  	}`
  2331  	parsed := Parse(nonArrayData)
  2332  	assert(t, len(parsed.Get("params.data").Array()) == 1)
  2333  
  2334  	arrayData := `{"jsonrpc":"2.0","method":"subscription","params":
  2335  		{"channel":"funny_channel","data":[
  2336  			{"name":"Jason","company":"good_company","number":12345}
  2337  		]}
  2338  	}`
  2339  	parsed = Parse(arrayData)
  2340  	assert(t, len(parsed.Get("params.data").Array()) == 1)
  2341  }
  2342  
  2343  func TestKeysValuesModifier(t *testing.T) {
  2344  	json := `{
  2345  		"1300014": {
  2346  		  "code": "1300014",
  2347  		  "price": 59.18,
  2348  		  "symbol": "300014",
  2349  		  "update": "2020/04/15 15:59:54",
  2350  		},
  2351  		"1300015": {
  2352  		  "code": "1300015",
  2353  		  "price": 43.31,
  2354  		  "symbol": "300015",
  2355  		  "update": "2020/04/15 15:59:54",
  2356  		}
  2357  	  }`
  2358  	assert(t, Get(json, `@keys`).String() == `["1300014","1300015"]`)
  2359  	assert(t, Get(``, `@keys`).String() == `[]`)
  2360  	assert(t, Get(`"hello"`, `@keys`).String() == `[null]`)
  2361  	assert(t, Get(`[]`, `@keys`).String() == `[]`)
  2362  	assert(t, Get(`[1,2,3]`, `@keys`).String() == `[null,null,null]`)
  2363  
  2364  	assert(t, Get(json, `@values.#.code`).String() == `["1300014","1300015"]`)
  2365  	assert(t, Get(``, `@values`).String() == `[]`)
  2366  	assert(t, Get(`"hello"`, `@values`).String() == `["hello"]`)
  2367  	assert(t, Get(`[]`, `@values`).String() == `[]`)
  2368  	assert(t, Get(`[1,2,3]`, `@values`).String() == `[1,2,3]`)
  2369  }
  2370  
  2371  func TestNaNInf(t *testing.T) {
  2372  	json := `[+Inf,-Inf,Inf,iNF,-iNF,+iNF,NaN,nan,nAn,-0,+0]`
  2373  	raws := []string{
  2374  		"+Inf", "-Inf", "Inf", "iNF", "-iNF", "+iNF", "NaN", "nan",
  2375  		"nAn", "-0", "+0",
  2376  	}
  2377  	nums := []float64{
  2378  		math.Inf(+1), math.Inf(-1), math.Inf(0), math.Inf(0),
  2379  		math.Inf(-1), math.Inf(+1), math.NaN(), math.NaN(), math.NaN(),
  2380  		math.Copysign(0, -1), 0,
  2381  	}
  2382  
  2383  	assert(t, int(Get(json, `#`).Int()) == len(raws))
  2384  	for i := 0; i < len(raws); i++ {
  2385  		r := Get(json, fmt.Sprintf("%d", i))
  2386  		assert(t, r.Raw == raws[i])
  2387  		assert(t, r.Num == nums[i] || (math.IsNaN(r.Num) && math.IsNaN(nums[i])))
  2388  		assert(t, r.Type == Number)
  2389  	}
  2390  
  2391  	var i int
  2392  	Parse(json).ForEach(func(_, r Result) bool {
  2393  		assert(t, r.Raw == raws[i])
  2394  		assert(t, r.Num == nums[i] || (math.IsNaN(r.Num) && math.IsNaN(nums[i])))
  2395  		assert(t, r.Type == Number)
  2396  		i++
  2397  		return true
  2398  	})
  2399  
  2400  	// Parse should also return valid numbers
  2401  	assert(t, math.IsNaN(Parse("nan").Float()))
  2402  	assert(t, math.IsNaN(Parse("NaN").Float()))
  2403  	assert(t, math.IsNaN(Parse(" NaN").Float()))
  2404  	assert(t, math.IsInf(Parse("+inf").Float(), +1))
  2405  	assert(t, math.IsInf(Parse("-inf").Float(), -1))
  2406  	assert(t, math.IsInf(Parse("+INF").Float(), +1))
  2407  	assert(t, math.IsInf(Parse("-INF").Float(), -1))
  2408  	assert(t, math.IsInf(Parse(" +INF").Float(), +1))
  2409  	assert(t, math.IsInf(Parse(" -INF").Float(), -1))
  2410  }
  2411  
  2412  func TestEmptyValueQuery(t *testing.T) {
  2413  	// issue: https://github.com/tidwall/gjson/issues/246
  2414  	assert(t, Get(
  2415  		`["ig","","tw","fb","tw","ig","tw"]`,
  2416  		`#(!="")#`).Raw ==
  2417  		`["ig","tw","fb","tw","ig","tw"]`)
  2418  	assert(t, Get(
  2419  		`["ig","","tw","fb","tw","ig","tw"]`,
  2420  		`#(!=)#`).Raw ==
  2421  		`["ig","tw","fb","tw","ig","tw"]`)
  2422  }
  2423  
  2424  func TestParseIndex(t *testing.T) {
  2425  	assert(t, Parse(`{}`).Index == 0)
  2426  	assert(t, Parse(` {}`).Index == 1)
  2427  	assert(t, Parse(` []`).Index == 1)
  2428  	assert(t, Parse(` true`).Index == 1)
  2429  	assert(t, Parse(` false`).Index == 1)
  2430  	assert(t, Parse(` null`).Index == 1)
  2431  	assert(t, Parse(` +inf`).Index == 1)
  2432  	assert(t, Parse(` -inf`).Index == 1)
  2433  }
  2434  
  2435  func TestRevSquash(t *testing.T) {
  2436  	assert(t, revSquash(` {}`) == `{}`)
  2437  	assert(t, revSquash(` }`) == ` }`)
  2438  	assert(t, revSquash(` [123]`) == `[123]`)
  2439  	assert(t, revSquash(` ,123,123]`) == ` ,123,123]`)
  2440  	assert(t, revSquash(` hello,[[true,false],[0,1,2,3,5],[123]]`) == `[[true,false],[0,1,2,3,5],[123]]`)
  2441  	assert(t, revSquash(` "hello"`) == `"hello"`)
  2442  	assert(t, revSquash(` "hel\\lo"`) == `"hel\\lo"`)
  2443  	assert(t, revSquash(` "hel\\"lo"`) == `"lo"`)
  2444  	assert(t, revSquash(` "hel\\\"lo"`) == `"hel\\\"lo"`)
  2445  	assert(t, revSquash(`hel\\\"lo"`) == `hel\\\"lo"`)
  2446  	assert(t, revSquash(`\"hel\\\"lo"`) == `\"hel\\\"lo"`)
  2447  	assert(t, revSquash(`\\\"hel\\\"lo"`) == `\\\"hel\\\"lo"`)
  2448  	assert(t, revSquash(`\\\\"hel\\\"lo"`) == `"hel\\\"lo"`)
  2449  	assert(t, revSquash(`hello"`) == `hello"`)
  2450  	json := `true,[0,1,"sadf\"asdf",{"hi":["hello","t\"\"u",{"a":"b"}]},9]`
  2451  	assert(t, revSquash(json) == json[5:])
  2452  	assert(t, revSquash(json[:len(json)-3]) == `{"hi":["hello","t\"\"u",{"a":"b"}]}`)
  2453  	assert(t, revSquash(json[:len(json)-4]) == `["hello","t\"\"u",{"a":"b"}]`)
  2454  	assert(t, revSquash(json[:len(json)-5]) == `{"a":"b"}`)
  2455  	assert(t, revSquash(json[:len(json)-6]) == `"b"`)
  2456  	assert(t, revSquash(json[:len(json)-10]) == `"a"`)
  2457  	assert(t, revSquash(json[:len(json)-15]) == `"t\"\"u"`)
  2458  	assert(t, revSquash(json[:len(json)-24]) == `"hello"`)
  2459  	assert(t, revSquash(json[:len(json)-33]) == `"hi"`)
  2460  	assert(t, revSquash(json[:len(json)-39]) == `"sadf\"asdf"`)
  2461  }
  2462  
  2463  const readmeJSON = `
  2464  {
  2465    "name": {"first": "Tom", "last": "Anderson"},
  2466    "age":37,
  2467    "children": ["Sara","Alex","Jack"],
  2468    "fav.movie": "Deer Hunter",
  2469    "friends": [
  2470      {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
  2471      {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
  2472      {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
  2473    ]
  2474  }
  2475  `
  2476  
  2477  func TestQueryGetPath(t *testing.T) {
  2478  	assert(t, strings.Join(
  2479  		Get(readmeJSON, "friends.#.first").Paths(readmeJSON), " ") ==
  2480  		"friends.0.first friends.1.first friends.2.first")
  2481  	assert(t, strings.Join(
  2482  		Get(readmeJSON, "friends.#(last=Murphy)").Paths(readmeJSON), " ") ==
  2483  		"")
  2484  	assert(t, Get(readmeJSON, "friends.#(last=Murphy)").Path(readmeJSON) ==
  2485  		"friends.0")
  2486  	assert(t, strings.Join(
  2487  		Get(readmeJSON, "friends.#(last=Murphy)#").Paths(readmeJSON), " ") ==
  2488  		"friends.0 friends.2")
  2489  	arr := Get(readmeJSON, "friends.#.first").Array()
  2490  	for i := 0; i < len(arr); i++ {
  2491  		assert(t, arr[i].Path(readmeJSON) == fmt.Sprintf("friends.%d.first", i))
  2492  	}
  2493  }
  2494  
  2495  func TestStaticJSON(t *testing.T) {
  2496  	json := `{
  2497  		"name": {"first": "Tom", "last": "Anderson"}
  2498  	}`
  2499  	assert(t, Get(json,
  2500  		`"bar"`).Raw ==
  2501  		``)
  2502  	assert(t, Get(json,
  2503  		`!"bar"`).Raw ==
  2504  		`"bar"`)
  2505  	assert(t, Get(json,
  2506  		`!{"name":{"first":"Tom"}}.{name.first}.first`).Raw ==
  2507  		`"Tom"`)
  2508  	assert(t, Get(json,
  2509  		`{name.last,"foo":!"bar"}`).Raw ==
  2510  		`{"last":"Anderson","foo":"bar"}`)
  2511  	assert(t, Get(json,
  2512  		`{name.last,"foo":!{"a":"b"},"that"}`).Raw ==
  2513  		`{"last":"Anderson","foo":{"a":"b"}}`)
  2514  	assert(t, Get(json,
  2515  		`{name.last,"foo":!{"c":"d"},!"that"}`).Raw ==
  2516  		`{"last":"Anderson","foo":{"c":"d"},"_":"that"}`)
  2517  	assert(t, Get(json,
  2518  		`[!true,!false,!null,!inf,!nan,!hello,{"name":!"andy",name.last},+inf,!["any","thing"]]`).Raw ==
  2519  		`[true,false,null,inf,nan,{"name":"andy","last":"Anderson"},["any","thing"]]`,
  2520  	)
  2521  }
  2522  
  2523  func TestArrayKeys(t *testing.T) {
  2524  	N := 100
  2525  	json := "["
  2526  	for i := 0; i < N; i++ {
  2527  		if i > 0 {
  2528  			json += ","
  2529  		}
  2530  		json += fmt.Sprint(i)
  2531  	}
  2532  	json += "]"
  2533  	var i int
  2534  	Parse(json).ForEach(func(key, value Result) bool {
  2535  		assert(t, key.String() == fmt.Sprint(i))
  2536  		assert(t, key.Int() == int64(i))
  2537  		i++
  2538  		return true
  2539  	})
  2540  	assert(t, i == N)
  2541  }
  2542  
  2543  func TestToFromStr(t *testing.T) {
  2544  	json := `{"Message":"{\"Records\":[{\"eventVersion\":\"2.1\"}]"}`
  2545  	res := Get(json, "Message.@fromstr.Records.#.eventVersion.@tostr").Raw
  2546  	assert(t, res == `["\"2.1\""]`)
  2547  }
  2548  
  2549  func TestGroup(t *testing.T) {
  2550  	json := `{"id":["123","456","789"],"val":[2,1]}`
  2551  	res := Get(json, "@group").Raw
  2552  	assert(t, res == `[{"id":"123","val":2},{"id":"456","val":1},{"id":"789"}]`)
  2553  
  2554  	json = `
  2555  {
  2556  	"issues": [
  2557  	  {
  2558  		"fields": {
  2559  		  "labels": [
  2560  			"milestone_1",
  2561  			"group:foo",
  2562  			"plan:a",
  2563  			"plan:b"
  2564  		  ]
  2565  		},
  2566  		"id": "123"
  2567  	  },{
  2568  		"fields": {
  2569  		  "labels": [
  2570  			"milestone_1",
  2571  			"group:foo",
  2572  			"plan:a",
  2573  			"plan"
  2574  		  ]
  2575  		},
  2576  		"id": "456"
  2577  	  }
  2578  	]
  2579    }
  2580    `
  2581  	res = Get(json, `{"id":issues.#.id,"plans":issues.#.fields.labels.#(%"plan:*")#|#.#}|@group|#(plans>=2)#.id`).Raw
  2582  	assert(t, res == `["123"]`)
  2583  }
  2584  
  2585  func testJSONString(t *testing.T, str string) {
  2586  	gjsonString := string(AppendJSONString(nil, str))
  2587  	data, err := json.Marshal(str)
  2588  	if err != nil {
  2589  		panic(123)
  2590  	}
  2591  	goString := string(data)
  2592  	if gjsonString != goString {
  2593  		t.Fatal(strconv.Quote(str) + "\n\t" +
  2594  			gjsonString + "\n\t" +
  2595  			goString + "\n\t<<< MISMATCH >>>")
  2596  	}
  2597  }
  2598  
  2599  func TestJSONString(t *testing.T) {
  2600  	testJSONString(t, "hello")
  2601  	testJSONString(t, "he\"llo")
  2602  	testJSONString(t, "he\"l\\lo")
  2603  	const input = `{"utf8":"Example emoji, KO: \ud83d\udd13, \ud83c\udfc3 ` +
  2604  		`OK: \u2764\ufe0f "}`
  2605  	value := Get(input, "utf8")
  2606  	var s string
  2607  	json.Unmarshal([]byte(value.Raw), &s)
  2608  	if value.String() != s {
  2609  		t.Fatalf("expected '%v', got '%v'", s, value.String())
  2610  	}
  2611  	testJSONString(t, s)
  2612  	testJSONString(t, "R\xfd\xfc\a!\x82eO\x16?_\x0f\x9ab\x1dr")
  2613  	testJSONString(t, "_\xb9\v\xad\xb3|X!\xb6\xd9U&\xa4\x1a\x95\x04")
  2614  	data, _ := json.Marshal("\b\f")
  2615  	if string(data) == "\"\\b\\f\"" {
  2616  		// Go version 1.22+ encodes "\b" and "\f" correctly.
  2617  		testJSONString(t, "\b\f")
  2618  		rng := rand.New(rand.NewSource(time.Now().UnixNano()))
  2619  		start := time.Now()
  2620  		var buf [16]byte
  2621  		for time.Since(start) < time.Second*2 {
  2622  			if _, err := rng.Read(buf[:]); err != nil {
  2623  				t.Fatal(err)
  2624  			}
  2625  			testJSONString(t, string(buf[:]))
  2626  		}
  2627  	}
  2628  }
  2629  
  2630  func TestIndexAtSymbol(t *testing.T) {
  2631  	json := `{
  2632  		"@context": {
  2633  		  "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
  2634  		  "@vocab": "http://schema.org/",
  2635  		  "sh": "http://www.w3.org/ns/shacl#"
  2636  		}
  2637  	}`
  2638  	assert(t, Get(json, "@context.@vocab").Index == 85)
  2639  }
  2640  
  2641  func TestDeepModifierWithOptions(t *testing.T) {
  2642  	rawJson := `{"x":[{"y":[{"z":{"b":1, "c": 2, "a": 3}}]}]}`
  2643  	jsonPathExpr := `x.#.y.#.z.@pretty:{"sortKeys":true}`
  2644  	results := GetManyBytes([]byte(rawJson), jsonPathExpr)
  2645  	assert(t, len(results) == 1)
  2646  	actual := results[0].Raw
  2647  	expected := `[[{
  2648    "a": 3,
  2649    "b": 1,
  2650    "c": 2
  2651  }
  2652  ]]`
  2653  	if expected != actual {
  2654  		t.Fatal(strconv.Quote(rawJson) + "\n\t" +
  2655  			expected + "\n\t" +
  2656  			actual + "\n\t<<< MISMATCH >>>")
  2657  	}
  2658  }
  2659  
  2660  func TestIssue301(t *testing.T) {
  2661  	json := `{
  2662  		"children": ["Sara","Alex","Jack"],
  2663  		"fav.movie": ["Deer Hunter"]
  2664  	}`
  2665  
  2666  	assert(t, Get(json, `children.0`).String() == "Sara")
  2667  	assert(t, Get(json, `children.[0]`).String() == `["Sara"]`)
  2668  	assert(t, Get(json, `children.1`).String() == "Alex")
  2669  	assert(t, Get(json, `children.[1]`).String() == `["Alex"]`)
  2670  	assert(t, Get(json, `children.[10]`).String() == `[]`)
  2671  	assert(t, Get(json, `fav\.movie.0`).String() == "Deer Hunter")
  2672  	assert(t, Get(json, `fav\.movie.[0]`).String() == `["Deer Hunter"]`)
  2673  	assert(t, Get(json, `fav\.movie.1`).String() == "")
  2674  	assert(t, Get(json, `fav\.movie.[1]`).String() == "[]")
  2675  }
  2676  
  2677  func TestModDig(t *testing.T) {
  2678  	json := `
  2679  		{
  2680  
  2681  			"group": {
  2682  				"issues": [
  2683  					{
  2684  						"fields": {
  2685  						"labels": [
  2686  							"milestone_1",
  2687  							"group:foo",
  2688  							"plan:a",
  2689  							"plan:b"
  2690  						]
  2691  						},
  2692  						"refid": "123"
  2693  					},{
  2694  						"fields": {
  2695  						"labels": [
  2696  							"milestone_2",
  2697  							"group:foo",
  2698  							"plan:a",
  2699  							"plan"
  2700  						]
  2701  						},
  2702  						"refid": "456"
  2703  					},[
  2704  						{"extra_deep":[{
  2705  							"fields": {
  2706  							"labels": [
  2707  								"milestone_3",
  2708  								"group:foo",
  2709  								"plan:a",
  2710  								"plan"
  2711  							]
  2712  							},
  2713  							"refid": "789"
  2714  						}]
  2715  					}]
  2716  				]
  2717  			}
  2718  		}
  2719  	`
  2720  	assert(t, Get(json, "group.@dig:#(refid=123)|0.fields.labels.0").String() == "milestone_1")
  2721  	assert(t, Get(json, "group.@dig:#(refid=456)|0.fields.labels.0").String() == "milestone_2")
  2722  	assert(t, Get(json, "group.@dig:#(refid=789)|0.fields.labels.0").String() == "milestone_3")
  2723  	json = `
  2724  	{ "something": {
  2725  		"anything": {
  2726  		  "abcdefg": {
  2727  			  "finally": {
  2728  				"important": {
  2729  					"secret": "password",
  2730  					"name": "jake"
  2731  				}
  2732  			},
  2733  			"name": "melinda"
  2734  		  }
  2735  		}
  2736  	  }
  2737  	}`
  2738  	assert(t, Get(json, "@dig:name").String() == `["melinda","jake"]`)
  2739  	assert(t, Get(json, "@dig:secret").String() == `["password"]`)
  2740  }
  2741  
  2742  func TestEscape(t *testing.T) {
  2743  	json := `{
  2744  		"user":{
  2745  			"first.name": "Janet",
  2746  			"last.name": "Prichard"
  2747  		  }
  2748  	  }`
  2749  	user := Get(json, "user")
  2750  	assert(t, user.Get(Escape("first.name")).String() == "Janet")
  2751  	assert(t, user.Get(Escape("last.name")).String() == "Prichard")
  2752  	assert(t, user.Get("first.name").String() == "")
  2753  }