github.com/zhangdapeng520/zdpgo_json@v0.1.5/query/query_test.go (about)

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