github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/json/json_test.go (about)

     1  // Copyright 2017 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package json
    12  
    13  import (
    14  	"bytes"
    15  	"encoding/json"
    16  	"fmt"
    17  	"math/rand"
    18  	"strconv"
    19  	"strings"
    20  	"testing"
    21  
    22  	"github.com/cockroachdb/apd"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    24  	"github.com/cockroachdb/cockroach/pkg/util/encoding"
    25  	"github.com/cockroachdb/cockroach/pkg/util/timeutil"
    26  	"github.com/cockroachdb/cockroach/pkg/util/unique"
    27  )
    28  
    29  func eachPair(a, b JSON, f func(a, b JSON)) {
    30  	f(a, a)
    31  	f(a, b)
    32  	f(b, a)
    33  	f(b, b)
    34  }
    35  
    36  func eachComparison(a, b JSON, c, d JSON, f func(a, b JSON)) {
    37  	f(a, c)
    38  	f(a, d)
    39  	f(b, c)
    40  	f(b, d)
    41  }
    42  
    43  func runDecodedAndEncoded(t *testing.T, testName string, j JSON, f func(t *testing.T, j JSON)) {
    44  	t.Run(testName, func(t *testing.T) {
    45  		f(t, j)
    46  	})
    47  	t.Run(testName+` (encoded)`, func(t *testing.T) {
    48  		encoding, err := EncodeJSON(nil, j)
    49  		if err != nil {
    50  			t.Fatal(err)
    51  		}
    52  		encoded, err := newEncodedFromRoot(encoding)
    53  		if err != nil {
    54  			t.Fatal(err)
    55  		}
    56  		f(t, encoded)
    57  	})
    58  }
    59  
    60  func TestJSONOrdering(t *testing.T) {
    61  	// We test here that every element in order sorts before every one that comes
    62  	// after it, and is equal to itself.
    63  	sources := []string{
    64  		`null`,
    65  		`"a"`,
    66  		`"aa"`,
    67  		`"b"`,
    68  		`"bb"`,
    69  		`1`,
    70  		`2`,
    71  		`100`,
    72  		`false`,
    73  		`true`,
    74  		// In Postgres's sorting rules, the empty array comes before everything (even null),
    75  		// so this is a departure.
    76  		// Shorter arrays sort before longer arrays (this is the same as in Postgres).
    77  		`[]`,
    78  		`[1]`,
    79  		`[2]`,
    80  		`[1, 2]`,
    81  		`[1, 3]`,
    82  		// Objects with fewer keys come before objects with more keys.
    83  		`{}`,
    84  		`{"a": 1}`,
    85  		`{"a": 2}`,
    86  		// In Postgres, keys which are shorter sort before keys which are longer. This
    87  		// is not true for us (right now). TODO(justin): unclear if it should be.
    88  		`{"aa": 1}`,
    89  		`{"b": 1}`,
    90  		`{"b": 2}`,
    91  		// Objects are compared key-1, value-1, key-2, value-2, ...
    92  		`{"a": 2, "c": 3}`,
    93  		`{"a": 3, "b": 3}`,
    94  	}
    95  	jsons := make([]JSON, len(sources))
    96  	encJSONs := make([]JSON, len(sources))
    97  	for i := range sources {
    98  		j, err := ParseJSON(sources[i])
    99  		if err != nil {
   100  			t.Fatal(err)
   101  		}
   102  		jsons[i] = j
   103  		b, err := EncodeJSON(nil, j)
   104  		if err != nil {
   105  			t.Fatal(err)
   106  		}
   107  		encJSONs[i], err = newEncodedFromRoot(b)
   108  		if err != nil {
   109  			t.Fatal(err)
   110  		}
   111  	}
   112  	for i := range jsons {
   113  		eachPair(jsons[i], encJSONs[i], func(a, b JSON) {
   114  			c, err := a.Compare(b)
   115  			if err != nil {
   116  				t.Fatal(err)
   117  			}
   118  			if c != 0 {
   119  				t.Errorf("%s not equal to %s", a, b)
   120  			}
   121  		})
   122  		for j := i + 1; j < len(jsons); j++ {
   123  			eachComparison(jsons[i], encJSONs[i], jsons[j], encJSONs[j], func(a, b JSON) {
   124  				c, err := a.Compare(b)
   125  				if err != nil {
   126  					t.Fatal(err)
   127  				}
   128  				if c != -1 {
   129  					t.Errorf("expected %s < %s", a, b)
   130  				}
   131  			})
   132  			eachComparison(jsons[j], encJSONs[j], jsons[i], encJSONs[i], func(a, b JSON) {
   133  				c, err := a.Compare(b)
   134  				if err != nil {
   135  					t.Fatal(err)
   136  				}
   137  				if c != 1 {
   138  					t.Errorf("expected %s > %s", a, b)
   139  				}
   140  			})
   141  		}
   142  	}
   143  }
   144  
   145  func TestJSONRoundTrip(t *testing.T) {
   146  	testCases := []string{
   147  		`1`,
   148  		`-5`,
   149  		`1.00`,
   150  		`1.00000000000`,
   151  		`100000000000000000000000000000000000000000`,
   152  		`1.3e100`,
   153  		`true`,
   154  		` true `,
   155  		`
   156  
   157          true
   158          `,
   159  		`false`,
   160  		`"hello"`,
   161  		`"hel\"\n\r\tlo"`,
   162  		`[1, true, "three"]`,
   163  		`[1, 1.0, 1.00, 1.000, 1.0000, 1.00000]`,
   164  		`[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]`,
   165  		`"日本語"`,
   166  		`["日本語"]`,
   167  		`{"日本語": "日本語"}`,
   168  		`{"a": "b"}`,
   169  		`{"a\nb": "a"}`,
   170  		`{"a": "b", "b": "c"}`,
   171  		`{"a": "b", "b": 1}`,
   172  		`{"a": "b", "b": 1, "c": [1, 2, {"a": 3}]}`,
   173  		`"🤔"`,
   174  		`{"🤔": "🤔"}`,
   175  		`"\u0000"`,
   176  		`"\u0001"`,
   177  		`"\u0002"`,
   178  		`"\u0003"`,
   179  		`"\u0004"`,
   180  		`"\u0005"`,
   181  		`"\u0006"`,
   182  		`"\u0007"`,
   183  		`"\u0008"`,
   184  		`"\t"`,
   185  		`"\n"`,
   186  		`"\u000b"`,
   187  		`"\u000c"`,
   188  		`"\r"`,
   189  		`"\u000e"`,
   190  		`"\u000f"`,
   191  		`"\u0010"`,
   192  		`"\u0011"`,
   193  		`"\u0012"`,
   194  		`"\u0013"`,
   195  		`"\u0014"`,
   196  		`"\u0015"`,
   197  		`"\u0016"`,
   198  		`"\u0017"`,
   199  		`"\u0018"`,
   200  		`"\u0019"`,
   201  		`"\u001a"`,
   202  		`"\u001b"`,
   203  		`"\u001c"`,
   204  		`"\u001d"`,
   205  		`"\u001e"`,
   206  		`"\u001f"`,
   207  		`"\uffff"`,
   208  		`"\\"`,
   209  		`"\""`,
   210  		// We don't expect to get any invalid UTF8, but check one anyway. We could do
   211  		// a validation that the input is valid UTF8, but that seems wasteful when it
   212  		// should be checked higher up.
   213  		string([]byte{'"', 0xa7, '"'}),
   214  		`[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]`,
   215  	}
   216  	for i, tc := range testCases {
   217  		j, err := ParseJSON(tc)
   218  		if err != nil {
   219  			t.Fatal(err)
   220  		}
   221  		// We don't include the actual string here because TeamCity doesn't handle
   222  		// test names with emojis in them well.
   223  		runDecodedAndEncoded(t, fmt.Sprintf("%d", i), j, func(t *testing.T, j JSON) {
   224  			s := j.String()
   225  
   226  			j2, err := ParseJSON(s)
   227  			if err != nil {
   228  				t.Fatalf("error while parsing %v: %s", s, err)
   229  			}
   230  			c, err := j.Compare(j2)
   231  			if err != nil {
   232  				t.Fatal(err)
   233  			}
   234  			if c != 0 {
   235  				t.Fatalf("%v should equal %v", tc, s)
   236  			}
   237  			s2 := j2.String()
   238  			if s != s2 {
   239  				t.Fatalf("%v should equal %v", s, s2)
   240  			}
   241  		})
   242  	}
   243  }
   244  
   245  func TestJSONErrors(t *testing.T) {
   246  	testCases := []struct {
   247  		input string
   248  		msg   string
   249  	}{
   250  		{`true false`, `trailing characters after JSON document`},
   251  		{`trues`, `trailing characters after JSON document`},
   252  		{`1 2 3`, `trailing characters after JSON document`},
   253  		// Here the decoder just grabs the 0 and leaves the 1. JSON numbers can't have
   254  		// leading 0s.
   255  		{`01`, `trailing characters after JSON document`},
   256  		{`{foo: 1}`, `invalid character 'f' looking for beginning of object key string`},
   257  		{`{'foo': 1}`, `invalid character '\'' looking for beginning of object key string`},
   258  		{`{"foo": 01}`, `invalid character '1' after object key:value pair`},
   259  		{`{`, `unexpected EOF`},
   260  		{`"\v"`, `invalid character 'v' in string escape code`},
   261  		{`"\x00"`, `invalid character 'x' in string escape code`},
   262  		{string([]byte{'"', '\n', '"'}), `invalid character`},
   263  		{string([]byte{'"', 8, '"'}), `invalid character`},
   264  	}
   265  	for _, tc := range testCases {
   266  		t.Run(tc.input, func(t *testing.T) {
   267  			j, err := ParseJSON(tc.input)
   268  			if err == nil {
   269  				t.Fatalf("expected parsing '%v' to error with '%s', but no error occurred and parsed as %s", tc.input, tc.msg, j)
   270  			}
   271  			if !strings.Contains(err.Error(), tc.msg) {
   272  				t.Fatalf("expected error message to be '%s', but was '%s'", tc.msg, err.Error())
   273  			}
   274  			if !pgerror.HasCandidateCode(err) {
   275  				t.Fatalf("expected parsing '%s' to provide a pg error code", tc.input)
   276  			}
   277  		})
   278  	}
   279  }
   280  
   281  func TestJSONSize(t *testing.T) {
   282  	testCases := []struct {
   283  		input string
   284  		size  uintptr
   285  	}{
   286  		// These numbers aren't set in stone, they're just here to make sure this
   287  		// function makes some amount of sense.
   288  		{`true`, 0},
   289  		{`false`, 0},
   290  		{`null`, 0},
   291  		{`""`, stringHeaderSize},
   292  		{`"hello"`, stringHeaderSize + 5},
   293  		{`[]`, sliceHeaderSize},
   294  		{`[null]`, sliceHeaderSize + jsonInterfaceSize},
   295  		{`[""]`, sliceHeaderSize + jsonInterfaceSize + stringHeaderSize},
   296  		{`[[]]`, sliceHeaderSize + jsonInterfaceSize + sliceHeaderSize},
   297  		{`[{}]`, sliceHeaderSize + jsonInterfaceSize + sliceHeaderSize},
   298  		{`["hello","goodbye"]`, sliceHeaderSize + 2*jsonInterfaceSize + 2*stringHeaderSize + 12},
   299  		{`{}`, sliceHeaderSize},
   300  		{`{"":null}`, sliceHeaderSize + keyValuePairSize},
   301  		{`{"":{}}`, sliceHeaderSize + keyValuePairSize + sliceHeaderSize},
   302  		{`{"a":"b"}`, sliceHeaderSize + keyValuePairSize + 1 + stringHeaderSize + 1},
   303  	}
   304  	largeBuf := make([]byte, 0, 10240)
   305  	for _, tc := range testCases {
   306  		t.Run(tc.input, func(t *testing.T) {
   307  			j, err := ParseJSON(tc.input)
   308  			if err != nil {
   309  				t.Fatal(err)
   310  			}
   311  			if j.Size() != tc.size {
   312  				t.Fatalf("expected %v to have size %d, but had size %d", j, tc.size, j.Size())
   313  			}
   314  
   315  			t.Run("jsonEncodedSize", func(t *testing.T) {
   316  				largeBuf = largeBuf[:0]
   317  				var buf []byte
   318  				var err error
   319  
   320  				if buf, err = EncodeJSON(buf, j); err != nil {
   321  					t.Fatal(err)
   322  				}
   323  				if largeBuf, err = EncodeJSON(largeBuf, j); err != nil {
   324  					t.Fatal(err)
   325  				}
   326  
   327  				encoded, err := newEncodedFromRoot(buf)
   328  				if err != nil {
   329  					t.Fatal(err)
   330  				}
   331  				encodedFromLargeBuf, err := newEncodedFromRoot(largeBuf)
   332  				if err != nil {
   333  					t.Fatal(err)
   334  				}
   335  				if encodedFromLargeBuf.Size() != encoded.Size() {
   336  					t.Errorf("expected jsonEncoded on a large buf for %v to have size %d, found %d", j, encoded.Size(), encodedFromLargeBuf.Size())
   337  				}
   338  			})
   339  		})
   340  	}
   341  }
   342  
   343  func TestJSONLen(t *testing.T) {
   344  	testCases := []struct {
   345  		input string
   346  		len   int
   347  	}{
   348  		{`true`, 0},
   349  		{`false`, 0},
   350  		{`null`, 0},
   351  		{`"a"`, 0},
   352  		{`[]`, 0},
   353  		{`["a","b"]`, 2},
   354  		{`{}`, 0},
   355  		{`{"a":"b"}`, 1},
   356  	}
   357  	for _, tc := range testCases {
   358  		j, err := ParseJSON(tc.input)
   359  		if err != nil {
   360  			t.Fatal(err)
   361  		}
   362  		runDecodedAndEncoded(t, tc.input, j, func(t *testing.T, j JSON) {
   363  			if j.Len() != tc.len {
   364  				t.Fatalf("expected %d, got %d", tc.len, j.Len())
   365  			}
   366  		})
   367  	}
   368  }
   369  
   370  func TestMakeJSON(t *testing.T) {
   371  	testCases := []struct {
   372  		input    interface{}
   373  		expected string
   374  	}{
   375  		// These tests are limited because they only really need to exercise the
   376  		// parts not exercised by the ParseJSON tests - that is, those involving
   377  		// int/int64/float64.
   378  		{json.Number("1.00"), "1.00"},
   379  		{1, "1"},
   380  		{int64(1), "1"},
   381  		{1.4, "1.4"},
   382  		{map[string]interface{}{"foo": 4}, `{"foo": 4}`},
   383  	}
   384  
   385  	for _, tc := range testCases {
   386  		t.Run(tc.expected, func(t *testing.T) {
   387  			result, err := MakeJSON(tc.input)
   388  			if err != nil {
   389  				t.Fatal(err)
   390  			}
   391  
   392  			expectedResult, err := ParseJSON(tc.expected)
   393  			if err != nil {
   394  				t.Fatal(err)
   395  			}
   396  
   397  			c, err := result.Compare(expectedResult)
   398  			if err != nil {
   399  				t.Fatal(err)
   400  			}
   401  			if c != 0 {
   402  				t.Fatalf("expected %v to equal %v", result, expectedResult)
   403  			}
   404  		})
   405  	}
   406  }
   407  
   408  func TestArrayBuilderWithCounter(t *testing.T) {
   409  	testCases := []struct {
   410  		input []interface{}
   411  	}{
   412  		{[]interface{}{}},
   413  		{[]interface{}{"a"}},
   414  		{[]interface{}{1, 2, "abc", nil, 1.2}},
   415  		{[]interface{}{"a", "aa", "aaa", "aaaa"}},
   416  	}
   417  	for _, tc := range testCases {
   418  		t.Run(fmt.Sprintf("array %v", tc.input), func(t *testing.T) {
   419  			builder := NewArrayBuilderWithCounter()
   420  			for _, e := range tc.input {
   421  				j, err := MakeJSON(e)
   422  				if err != nil {
   423  					t.Fatal(err)
   424  				}
   425  				builder.Add(j)
   426  			}
   427  			result := builder.Build()
   428  			expectedJSON, err := MakeJSON(tc.input)
   429  			if err != nil {
   430  				t.Fatal(err)
   431  			}
   432  			c, err := result.Compare(expectedJSON)
   433  			if err != nil {
   434  				t.Fatal(err)
   435  			}
   436  			if c != 0 {
   437  				t.Fatalf("expected %v to equal %v", result, expectedJSON)
   438  			}
   439  			if builder.Size() != result.Size() {
   440  				t.Fatalf("expected %v to equal %v", builder.Size(), result.Size())
   441  			}
   442  		})
   443  	}
   444  }
   445  
   446  func TestBuildJSONObject(t *testing.T) {
   447  	testCases := []struct {
   448  		input []string
   449  	}{
   450  		{[]string{}},
   451  		{[]string{"a"}},
   452  		{[]string{"a", "c", "a", "b", "a"}},
   453  		{[]string{"2", "1", "10", "3", "10", "1"}},
   454  	}
   455  	for _, tc := range testCases {
   456  		t.Run(fmt.Sprintf("keys %v", tc.input), func(t *testing.T) {
   457  			m := map[string]interface{}{}
   458  			b := NewObjectBuilder(0)
   459  			for i, k := range tc.input {
   460  				j := FromString(fmt.Sprintf("%d", i))
   461  				m[k] = j
   462  				b.Add(k, j)
   463  			}
   464  			expectedResult, err := MakeJSON(m)
   465  			if err != nil {
   466  				t.Fatal(err)
   467  			}
   468  			result := b.Build()
   469  			c, err := result.Compare(expectedResult)
   470  			if err != nil {
   471  				t.Fatal(err)
   472  			}
   473  			if c != 0 {
   474  				t.Fatalf("expected %v to equal %v", result, expectedResult)
   475  			}
   476  		})
   477  	}
   478  }
   479  
   480  func jsonTestShorthand(s string) JSON {
   481  	j, err := ParseJSON(s)
   482  	if err != nil {
   483  		panic(fmt.Sprintf("bad json: %s", s))
   484  	}
   485  	return j
   486  }
   487  
   488  func TestJSONFetch(t *testing.T) {
   489  	// Shorthand for tests.
   490  	json := jsonTestShorthand
   491  	cases := map[string][]struct {
   492  		key      string
   493  		expected JSON
   494  	}{
   495  		`{}`: {
   496  			{``, nil},
   497  			{`foo`, nil},
   498  		},
   499  		`{"foo": 1, "bar": "baz"}`: {
   500  			{``, nil},
   501  			{`foo`, json(`1`)},
   502  			{`bar`, json(`"baz"`)},
   503  			{`baz`, nil},
   504  		},
   505  		`{"foo": [1, 2, 3], "bar": {"a": "b"}}`: {
   506  			{``, nil},
   507  			{`foo`, json(`[1, 2, 3]`)},
   508  			{`bar`, json(`{"a": "b"}`)},
   509  			{`baz`, nil},
   510  		},
   511  		`["a"]`: {{``, nil}, {`0`, nil}, {`a`, nil}},
   512  		`"a"`:   {{``, nil}, {`0`, nil}, {`a`, nil}},
   513  		`1`:     {{``, nil}, {`0`, nil}, {`a`, nil}},
   514  		`true`:  {{``, nil}, {`0`, nil}, {`a`, nil}},
   515  	}
   516  
   517  	for k, tests := range cases {
   518  		left, err := ParseJSON(k)
   519  		if err != nil {
   520  			t.Fatal(err)
   521  		}
   522  
   523  		for _, tc := range tests {
   524  			runDecodedAndEncoded(t, k+`->`+tc.key, left, func(t *testing.T, j JSON) {
   525  				result, err := j.FetchValKey(tc.key)
   526  				if err != nil {
   527  					t.Fatal(err)
   528  				}
   529  				if result == nil || tc.expected == nil {
   530  					if result == tc.expected {
   531  						return
   532  					}
   533  					t.Fatalf("expected %s, got %s", tc.expected, result)
   534  				}
   535  				c, err := result.Compare(tc.expected)
   536  				if err != nil {
   537  					t.Fatal(err)
   538  				}
   539  				if c != 0 {
   540  					t.Fatalf("expected %s, got %s", tc.expected, result)
   541  				}
   542  			})
   543  		}
   544  	}
   545  }
   546  
   547  func TestJSONRandomFetch(t *testing.T) {
   548  	rng := rand.New(rand.NewSource(timeutil.Now().Unix()))
   549  	for i := 0; i < 1000; i++ {
   550  		// We want a big object to trigger the binary search behavior in FetchValKey.
   551  		j, err := Random(1000, rng)
   552  		if err != nil {
   553  			t.Fatal(err)
   554  		}
   555  		if obj, ok := j.(jsonObject); ok {
   556  			// Pick a key:
   557  			idx := rand.Intn(len(obj))
   558  			result, err := obj.FetchValKey(string(obj[idx].k))
   559  			if err != nil {
   560  				t.Fatal(err)
   561  			}
   562  			c, err := result.Compare(obj[idx].v)
   563  			if err != nil {
   564  				t.Fatal(err)
   565  			}
   566  			if c != 0 {
   567  				t.Fatalf("%s: expected fetching %s to give %s got %s", obj, obj[idx].k, obj[idx].v, result)
   568  			}
   569  		}
   570  	}
   571  }
   572  
   573  func TestJSONFetchFromBig(t *testing.T) {
   574  	size := 100
   575  
   576  	obj := make(map[string]interface{})
   577  	for i := 0; i < size; i++ {
   578  		obj[fmt.Sprintf("key%d", i)] = i
   579  	}
   580  	j, err := MakeJSON(obj)
   581  	if err != nil {
   582  		t.Fatal(err)
   583  	}
   584  
   585  	runDecodedAndEncoded(t, "fetch big", j, func(t *testing.T, j JSON) {
   586  		for i := 0; i < size; i++ {
   587  			result, err := j.FetchValKey(fmt.Sprintf("key%d", i))
   588  			if err != nil {
   589  				t.Fatal(err)
   590  			}
   591  
   592  			expected, err := MakeJSON(i)
   593  			if err != nil {
   594  				t.Fatal(err)
   595  			}
   596  
   597  			cmp, err := result.Compare(expected)
   598  			if err != nil {
   599  				t.Fatal(err)
   600  			}
   601  			if cmp != 0 {
   602  				t.Errorf("expected %d, got %d", i, result)
   603  			}
   604  		}
   605  	})
   606  }
   607  
   608  func TestJSONFetchIdx(t *testing.T) {
   609  	json := jsonTestShorthand
   610  	cases := map[string][]struct {
   611  		idx      int
   612  		expected JSON
   613  	}{
   614  		`{}`:                     {{1, nil}, {2, nil}},
   615  		`{"foo": 1, "1": "baz"}`: {{0, nil}, {1, nil}, {2, nil}},
   616  		`[]`:                     {{-1, nil}, {0, nil}, {1, nil}},
   617  		`["a", "b", "c"]`: {
   618  			// Negative indices count from the back.
   619  			{-4, nil},
   620  			{-3, json(`"a"`)},
   621  			{-2, json(`"b"`)},
   622  			{-1, json(`"c"`)},
   623  			{0, json(`"a"`)},
   624  			{1, json(`"b"`)},
   625  			{2, json(`"c"`)},
   626  			{3, nil},
   627  		},
   628  		`[1, 2, {"foo":"bar"}]`: {
   629  			{0, json(`1`)},
   630  			{1, json(`2`)},
   631  			{2, json(`{"foo":"bar"}`)},
   632  		},
   633  		// Trigger the offset-value
   634  		`[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40]`: {
   635  			{0, json(`0`)},
   636  			{1, json(`1`)},
   637  			{2, json(`2`)},
   638  			{10, json(`10`)},
   639  			{35, json(`35`)},
   640  		},
   641  	}
   642  
   643  	for k, tests := range cases {
   644  		left, err := ParseJSON(k)
   645  		if err != nil {
   646  			t.Fatal(err)
   647  		}
   648  
   649  		for _, tc := range tests {
   650  			runDecodedAndEncoded(t, fmt.Sprintf("%s->%d", k, tc.idx), left, func(t *testing.T, j JSON) {
   651  				result, err := j.FetchValIdx(tc.idx)
   652  				if err != nil {
   653  					t.Fatal(err)
   654  				}
   655  				if result == nil || tc.expected == nil {
   656  					if result == tc.expected {
   657  						return
   658  					}
   659  					t.Fatalf("expected %s, got %s", tc.expected, result)
   660  				}
   661  				c, err := result.Compare(tc.expected)
   662  				if err != nil {
   663  					t.Fatal(err)
   664  				}
   665  				if c != 0 {
   666  					t.Fatalf("expected %s, got %s", tc.expected, result)
   667  				}
   668  			})
   669  		}
   670  	}
   671  }
   672  
   673  func TestJSONExists(t *testing.T) {
   674  	cases := map[string][]struct {
   675  		key    string
   676  		exists bool
   677  	}{
   678  		`{}`: {
   679  			{``, false},
   680  			{`foo`, false},
   681  		},
   682  		`{"foo": 1, "bar": "baz"}`: {
   683  			{``, false},
   684  			{`foo`, true},
   685  			{`bar`, true},
   686  			{`baz`, false},
   687  		},
   688  		`{"foo": [1, 2, 3], "bar": {"a": "b"}}`: {
   689  			{``, false},
   690  			{`foo`, true},
   691  			{`bar`, true},
   692  			{`baz`, false},
   693  		},
   694  		`["a"]`: {{``, false}, {`0`, false}, {`a`, true}},
   695  		`"a"`:   {{``, false}, {`0`, false}, {`a`, true}},
   696  		`1`:     {{``, false}, {`0`, false}, {`a`, false}},
   697  		`true`:  {{``, false}, {`0`, false}, {`a`, false}},
   698  	}
   699  
   700  	for k, tests := range cases {
   701  		left, err := ParseJSON(k)
   702  		if err != nil {
   703  			t.Fatal(err)
   704  		}
   705  
   706  		for _, tc := range tests {
   707  			t.Run(k+` ? `+tc.key, func(t *testing.T) {
   708  				result, err := left.Exists(tc.key)
   709  				if err != nil {
   710  					t.Fatal(err)
   711  				}
   712  				if result != tc.exists {
   713  					if tc.exists {
   714  						t.Fatalf("expected %s ? %s", left, tc.key)
   715  					}
   716  					t.Fatalf("expected %s to NOT ? %s", left, tc.key)
   717  				}
   718  			})
   719  
   720  			t.Run(k+` ? `+tc.key+` (encoded)`, func(t *testing.T) {
   721  				encoding, err := EncodeJSON(nil, left)
   722  				if err != nil {
   723  					t.Fatal(err)
   724  				}
   725  				encoded, err := newEncodedFromRoot(encoding)
   726  				if err != nil {
   727  					t.Fatal(err)
   728  				}
   729  
   730  				result, err := encoded.Exists(tc.key)
   731  				if err != nil {
   732  					t.Fatal(err)
   733  				}
   734  				if result != tc.exists {
   735  					if tc.exists {
   736  						t.Fatalf("expected %s ? %s", encoded, tc.key)
   737  					}
   738  					t.Fatalf("expected %s to NOT ? %s", encoded, tc.key)
   739  				}
   740  			})
   741  		}
   742  	}
   743  }
   744  
   745  func TestJSONStripNulls(t *testing.T) {
   746  	testcases := []struct {
   747  		input       string
   748  		needToStrip bool
   749  		expected    string
   750  	}{
   751  		{`null`, false, `null`},
   752  		{`1`, false, `1`},
   753  		{`"a"`, false, `"a"`},
   754  		{`true`, false, `true`},
   755  		{`false`, false, `false`},
   756  		{`[]`, false, `[]`},
   757  		{`[1, "a", null, true, {"a":1, "b":[null]}]`, false, `[1, "a", null, true, {"a":1, "b":[null]}]`},
   758  		{`[{"a":null}]`, true, `[{}]`},
   759  		{`[[{"a":null}]]`, true, `[[{}]]`},
   760  		{`[null, {"a":null}, {"a":null}]`, true, `[null, {}, {}]`},
   761  		{`[{"a":null}, {"a":null}, null]`, true, `[{}, {}, null]`},
   762  		{`{}`, false, `{}`},
   763  		{`{"a":[null], "b":1, "c":{"a":1}}`, false, `{"a":[null], "b":1, "c":{"a":1}}`},
   764  		{`{"a":null}`, true, `{}`},
   765  		{`{"a":{"a":null}}`, true, `{"a":{}}`},
   766  		{`{"a":[{"a":null}]}`, true, `{"a":[{}]}`},
   767  		{`{"a":[null], "b":null, "c":{"a":null}}`, true, `{"a":[null], "c":{}}`},
   768  		{`{"a":[null], "b":{"a":null}, "c":{"a":null}}`, true, `{"a":[null], "b":{}, "c":{}}`},
   769  		{`{"a":{"a":null}, "b":{"a":null}, "c":[null]}`, true, `{"a":{}, "b":{}, "c":[null]}`},
   770  	}
   771  	for _, tc := range testcases {
   772  		j, err := ParseJSON(tc.input)
   773  		if err != nil {
   774  			t.Fatal(err)
   775  		}
   776  		expectedResult, err := ParseJSON(tc.expected)
   777  		if err != nil {
   778  			t.Fatal(err)
   779  		}
   780  		runDecodedAndEncoded(t, tc.input, j, func(t *testing.T, j JSON) {
   781  			result, needToStrip, err := j.StripNulls()
   782  			if err != nil {
   783  				t.Fatal(err)
   784  			}
   785  			c, err := result.Compare(expectedResult)
   786  			if err != nil {
   787  				t.Fatal(err)
   788  			}
   789  			if needToStrip != tc.needToStrip {
   790  				t.Fatalf("expected %t, got %t", tc.needToStrip, needToStrip)
   791  			}
   792  			if c != 0 {
   793  				t.Fatalf("expected %s, got %s", tc.expected, result)
   794  			}
   795  			// Check whether j is not changed.
   796  			originInput, err := ParseJSON(tc.input)
   797  			if err != nil {
   798  				t.Fatal(err)
   799  			}
   800  			if c, err = j.Compare(originInput); err != nil {
   801  				t.Fatal(err)
   802  			}
   803  			if c != 0 {
   804  				t.Fatalf("expected %s, got %s", originInput, j)
   805  			}
   806  		})
   807  	}
   808  }
   809  
   810  func TestJSONFetchPath(t *testing.T) {
   811  	json := jsonTestShorthand
   812  	cases := map[string][]struct {
   813  		path     []string
   814  		expected JSON
   815  	}{
   816  		`{}`: {
   817  			{[]string{`a`}, nil},
   818  		},
   819  		`{"foo": "bar"}`: {
   820  			{[]string{`foo`}, json(`"bar"`)},
   821  			{[]string{`goo`}, nil},
   822  		},
   823  		`{"foo": {"bar": "baz"}}`: {
   824  			{[]string{`foo`}, json(`{"bar": "baz"}`)},
   825  			{[]string{`foo`, `bar`}, json(`"baz"`)},
   826  			{[]string{`foo`, `baz`}, nil},
   827  		},
   828  		`{"foo": [1, 2, {"bar": "baz"}]}`: {
   829  			{[]string{`foo`}, json(`[1, 2, {"bar": "baz"}]`)},
   830  			{[]string{`foo`, `0`}, json(`1`)},
   831  			{[]string{`foo`, `1`}, json(`2`)},
   832  			{[]string{`foo`, `2`}, json(`{"bar": "baz"}`)},
   833  			{[]string{`foo`, `2`, "bar"}, json(`"baz"`)},
   834  			{[]string{`foo`, `-1`, "bar"}, json(`"baz"`)},
   835  			{[]string{`foo`, `3`}, nil},
   836  			{[]string{`foo`, `3`, "bar"}, nil},
   837  		},
   838  		`[1, 2, [1, 2, [1, 2]]]`: {
   839  			{[]string{`"foo"`}, nil},
   840  			{[]string{`0`}, json(`1`)},
   841  			{[]string{`1`}, json(`2`)},
   842  			{[]string{`0`, `0`}, nil},
   843  			{[]string{`2`}, json(`[1, 2, [1, 2]]`)},
   844  			{[]string{`2`, `0`}, json(`1`)},
   845  			{[]string{`2`, `1`}, json(`2`)},
   846  			{[]string{`2`, `2`}, json(`[1, 2]`)},
   847  			{[]string{`2`, `2`, `0`}, json(`1`)},
   848  			{[]string{`2`, `2`, `1`}, json(`2`)},
   849  			{[]string{`-1`, `-1`, `-1`}, json(`2`)},
   850  		},
   851  	}
   852  
   853  	for k, tests := range cases {
   854  		left, err := ParseJSON(k)
   855  		if err != nil {
   856  			t.Fatal(err)
   857  		}
   858  
   859  		for _, tc := range tests {
   860  			t.Run(fmt.Sprintf("%s#>%v", k, tc.path), func(t *testing.T) {
   861  				result, err := FetchPath(left, tc.path)
   862  				if err != nil {
   863  					t.Fatal(err)
   864  				}
   865  				if result == nil || tc.expected == nil {
   866  					if result == tc.expected {
   867  						return
   868  					}
   869  					t.Fatalf("expected %s, got %s", tc.expected, result)
   870  				}
   871  				c, err := result.Compare(tc.expected)
   872  				if err != nil {
   873  					t.Fatal(err)
   874  				}
   875  				if c != 0 {
   876  					t.Fatalf("expected %s, got %s", tc.expected, result)
   877  				}
   878  			})
   879  		}
   880  
   881  		for _, tc := range tests {
   882  			t.Run(fmt.Sprintf("%s#>%v (encoded)", k, tc.path), func(t *testing.T) {
   883  				encoding, err := EncodeJSON(nil, left)
   884  				if err != nil {
   885  					t.Fatal(err)
   886  				}
   887  				encoded, err := newEncodedFromRoot(encoding)
   888  				if err != nil {
   889  					t.Fatal(err)
   890  				}
   891  				result, err := FetchPath(encoded, tc.path)
   892  				if err != nil {
   893  					t.Fatal(err)
   894  				}
   895  				if result == nil || tc.expected == nil {
   896  					if result == tc.expected {
   897  						return
   898  					}
   899  					t.Fatalf("expected %s, got %s", tc.expected, result)
   900  				}
   901  				c, err := result.Compare(tc.expected)
   902  				if err != nil {
   903  					t.Fatal(err)
   904  				}
   905  				if c != 0 {
   906  					t.Fatalf("expected %s, got %s", tc.expected, result)
   907  				}
   908  			})
   909  		}
   910  	}
   911  }
   912  
   913  func TestJSONDeepSet(t *testing.T) {
   914  	cases := map[string][]struct {
   915  		path          []string
   916  		to            string
   917  		createMissing bool
   918  		expected      string
   919  	}{
   920  		`{}`: {
   921  			{[]string{}, `1`, true, `{}`},
   922  			{[]string{`a`}, `1`, true, `{"a": 1}`},
   923  			{[]string{`a`}, `1`, false, `{}`},
   924  			{[]string{`a`, `b`}, `1`, true, `{}`},
   925  		},
   926  		`{"a": 1}`: {
   927  			{[]string{}, `2`, true, `{"a": 1}`},
   928  			{[]string{`a`}, `2`, true, `{"a": 2}`},
   929  			{[]string{`a`}, `2`, false, `{"a": 2}`},
   930  			{[]string{`a`, `b`}, `2`, true, `{"a": 1}`},
   931  		},
   932  		`{"a": {"b": 1}}`: {
   933  			{[]string{}, `2`, true, `{"a": {"b": 1}}`},
   934  			{[]string{`a`}, `2`, true, `{"a": 2}`},
   935  			{[]string{`a`, `b`}, `2`, true, `{"a": {"b": 2}}`},
   936  			{[]string{`a`, `b`}, `2`, false, `{"a": {"b": 2}}`},
   937  			{[]string{`a`, `c`}, `3`, true, `{"a": {"b": 1, "c": 3}}`},
   938  			{[]string{`a`, `c`}, `3`, false, `{"a": {"b": 1}}`},
   939  			{[]string{`b`}, `2`, true, `{"a": {"b": 1}, "b": 2}`},
   940  			{[]string{`b`}, `2`, false, `{"a": {"b": 1}}`},
   941  		},
   942  		`{"b": 1}`: {
   943  			{[]string{`a`}, `2`, true, `{"a": 2, "b": 1}`},
   944  			{[]string{`b`}, `2`, true, `{"b": 2}`},
   945  			{[]string{`c`}, `2`, true, `{"b": 1, "c": 2}`},
   946  		},
   947  		`[]`: {
   948  			{[]string{`-2`}, `1`, true, `[1]`},
   949  			{[]string{`-1`}, `1`, true, `[1]`},
   950  			{[]string{`0`}, `1`, true, `[1]`},
   951  			{[]string{`1`}, `1`, true, `[1]`},
   952  			{[]string{`2`}, `1`, true, `[1]`},
   953  			{[]string{`-2`}, `1`, false, `[]`},
   954  			{[]string{`-1`}, `1`, false, `[]`},
   955  			{[]string{`0`}, `1`, false, `[]`},
   956  			{[]string{`1`}, `1`, false, `[]`},
   957  			{[]string{`2`}, `1`, false, `[]`},
   958  			{[]string{`2`, `0`}, `1`, true, `[]`},
   959  		},
   960  		`[10]`: {
   961  			{[]string{`-2`}, `1`, true, `[1, 10]`},
   962  			{[]string{`-1`}, `1`, true, `[1]`},
   963  			{[]string{`0`}, `1`, true, `[1]`},
   964  			{[]string{`1`}, `1`, true, `[10, 1]`},
   965  			{[]string{`2`}, `1`, true, `[10, 1]`},
   966  			{[]string{`-2`}, `1`, false, `[10]`},
   967  			{[]string{`-1`}, `1`, false, `[1]`},
   968  			{[]string{`0`}, `1`, false, `[1]`},
   969  			{[]string{`1`}, `1`, false, `[10]`},
   970  			{[]string{`2`}, `1`, false, `[10]`},
   971  		},
   972  		`[10, 20]`: {
   973  			{[]string{`-3`}, `1`, true, `[1, 10, 20]`},
   974  			{[]string{`-2`}, `1`, true, `[1, 20]`},
   975  			{[]string{`-1`}, `1`, true, `[10, 1]`},
   976  			{[]string{`0`}, `1`, true, `[1, 20]`},
   977  			{[]string{`1`}, `1`, true, `[10, 1]`},
   978  			{[]string{`2`}, `1`, true, `[10, 20, 1]`},
   979  			{[]string{`3`}, `1`, true, `[10, 20, 1]`},
   980  			{[]string{`3`, `1`}, `1`, true, `[10, 20]`},
   981  		},
   982  		`[[10], [20, 30], {"a": 1}]`: {
   983  			{[]string{`0`}, `1`, true, `[1, [20, 30], {"a": 1}]`},
   984  			{[]string{`0`, `0`}, `1`, true, `[[1], [20, 30], {"a": 1}]`},
   985  			{[]string{`0`, `1`}, `1`, true, `[[10, 1], [20, 30], {"a": 1}]`},
   986  			{[]string{`1`, `0`}, `1`, true, `[[10], [1, 30], {"a": 1}]`},
   987  			{[]string{`2`, `a`}, `2`, true, `[[10], [20, 30], {"a": 2}]`},
   988  			{[]string{`2`, `b`}, `2`, true, `[[10], [20, 30], {"a": 1, "b": 2}]`},
   989  			{[]string{`2`, `a`, `c`}, `2`, true, `[[10], [20, 30], {"a": 1}]`},
   990  			{[]string{`2`, `b`, `c`}, `2`, true, `[[10], [20, 30], {"a": 1}]`},
   991  		},
   992  		`[{"a": [1]}]`: {
   993  			{[]string{`0`, `a`, `0`}, `2`, true, `[{"a": [2]}]`},
   994  			{[]string{`0`, `a`, `0`, `0`}, `2`, true, `[{"a": [1]}]`},
   995  		},
   996  	}
   997  
   998  	for k, tests := range cases {
   999  		j := jsonTestShorthand(k)
  1000  		for _, tc := range tests {
  1001  			t.Run(fmt.Sprintf(`set(%s, %s, %s)`, k, tc.path, tc.to), func(t *testing.T) {
  1002  				result, err := DeepSet(j, tc.path, jsonTestShorthand(tc.to), tc.createMissing)
  1003  				if err != nil {
  1004  					t.Fatal(err)
  1005  				}
  1006  
  1007  				cmp, err := result.Compare(jsonTestShorthand(tc.expected))
  1008  				if err != nil {
  1009  					t.Fatal(err)
  1010  				}
  1011  
  1012  				if cmp != 0 {
  1013  					t.Fatalf("expected %s, got %s", tc.expected, result)
  1014  				}
  1015  			})
  1016  		}
  1017  	}
  1018  }
  1019  
  1020  func TestJSONRemoveString(t *testing.T) {
  1021  	json := jsonTestShorthand
  1022  	cases := map[string][]struct {
  1023  		key      string
  1024  		ok       bool
  1025  		expected JSON
  1026  		errMsg   string
  1027  	}{
  1028  		`{}`: {
  1029  			{key: ``, ok: false, expected: json(`{}`)},
  1030  			{key: `foo`, ok: false, expected: json(`{}`)},
  1031  		},
  1032  		`{"foo": 1, "bar": "baz"}`: {
  1033  			{key: ``, ok: false, expected: json(`{"foo": 1, "bar": "baz"}`)},
  1034  			{key: `foo`, ok: true, expected: json(`{"bar": "baz"}`)},
  1035  			{key: `bar`, ok: true, expected: json(`{"foo": 1}`)},
  1036  			{key: `baz`, ok: false, expected: json(`{"foo": 1, "bar": "baz"}`)},
  1037  		},
  1038  		// Deleting a string key from an array never has any effect.
  1039  		`["a", "b", "c"]`: {
  1040  			{key: ``, ok: false, expected: json(`["a", "b", "c"]`)},
  1041  			{key: `foo`, ok: false, expected: json(`["a", "b", "c"]`)},
  1042  			{key: `0`, ok: false, expected: json(`["a", "b", "c"]`)},
  1043  			{key: `1`, ok: false, expected: json(`["a", "b", "c"]`)},
  1044  			{key: `-1`, ok: false, expected: json(`["a", "b", "c"]`)},
  1045  		},
  1046  		`5`:     {{key: `a`, errMsg: "cannot delete from scalar"}},
  1047  		`"b"`:   {{key: `a`, errMsg: "cannot delete from scalar"}},
  1048  		`true`:  {{key: `a`, errMsg: "cannot delete from scalar"}},
  1049  		`false`: {{key: `a`, errMsg: "cannot delete from scalar"}},
  1050  		`null`:  {{key: `a`, errMsg: "cannot delete from scalar"}},
  1051  	}
  1052  
  1053  	for k, tests := range cases {
  1054  		left, err := ParseJSON(k)
  1055  		if err != nil {
  1056  			t.Fatal(err)
  1057  		}
  1058  
  1059  		for _, tc := range tests {
  1060  			runDecodedAndEncoded(t, k+`-`+tc.key, left, func(t *testing.T, j JSON) {
  1061  				result, ok, err := j.RemoveString(tc.key)
  1062  				if tc.errMsg != "" {
  1063  					if err == nil {
  1064  						t.Fatal("expected error")
  1065  					} else if !strings.Contains(err.Error(), tc.errMsg) {
  1066  						t.Fatalf(`expected error message "%s" to contain "%s"`, err.Error(), tc.errMsg)
  1067  					}
  1068  					return
  1069  				}
  1070  				if err != nil {
  1071  					t.Fatal(err)
  1072  				}
  1073  				if tc.ok != ok {
  1074  					t.Fatalf("expected %t, got %t", tc.ok, ok)
  1075  				}
  1076  				c, err := result.Compare(tc.expected)
  1077  				if err != nil {
  1078  					t.Fatal(err)
  1079  				}
  1080  				if c != 0 {
  1081  					t.Fatalf("expected %s, got %s", tc.expected, result)
  1082  				}
  1083  			})
  1084  		}
  1085  	}
  1086  }
  1087  
  1088  func TestJSONRemoveIndex(t *testing.T) {
  1089  	json := jsonTestShorthand
  1090  	cases := map[string][]struct {
  1091  		idx      int
  1092  		ok       bool
  1093  		expected JSON
  1094  		errMsg   string
  1095  	}{
  1096  		`{"foo": 1, "bar": "baz"}`: {
  1097  			{idx: 0, errMsg: "cannot delete from object using integer"},
  1098  		},
  1099  		`["a", "b", "c"]`: {
  1100  			{idx: -4, ok: false, expected: json(`["a", "b", "c"]`)},
  1101  			{idx: -3, ok: true, expected: json(`["b", "c"]`)},
  1102  			{idx: -2, ok: true, expected: json(`["a", "c"]`)},
  1103  			{idx: -1, ok: true, expected: json(`["a", "b"]`)},
  1104  			{idx: 0, ok: true, expected: json(`["b", "c"]`)},
  1105  			{idx: 1, ok: true, expected: json(`["a", "c"]`)},
  1106  			{idx: 2, ok: true, expected: json(`["a", "b"]`)},
  1107  			{idx: 3, ok: false, expected: json(`["a", "b", "c"]`)},
  1108  		},
  1109  		`[{}, {"a":"b"}, {"c":"d"}]`: {
  1110  			{idx: 0, ok: true, expected: json(`[{"a":"b"},{"c":"d"}]`)},
  1111  			{idx: 1, ok: true, expected: json(`[{},{"c":"d"}]`)},
  1112  			{idx: 2, ok: true, expected: json(`[{},{"a":"b"}]`)},
  1113  		},
  1114  		`[]`: {
  1115  			{idx: -1, ok: false, expected: json(`[]`)},
  1116  			{idx: 0, ok: false, expected: json(`[]`)},
  1117  			{idx: 1, ok: false, expected: json(`[]`)},
  1118  		},
  1119  		`5`:     {{idx: 0, errMsg: "cannot delete from scalar"}},
  1120  		`"b"`:   {{idx: 0, errMsg: "cannot delete from scalar"}},
  1121  		`true`:  {{idx: 0, errMsg: "cannot delete from scalar"}},
  1122  		`false`: {{idx: 0, errMsg: "cannot delete from scalar"}},
  1123  		`null`:  {{idx: 0, errMsg: "cannot delete from scalar"}},
  1124  	}
  1125  
  1126  	for k, tests := range cases {
  1127  		left, err := ParseJSON(k)
  1128  		if err != nil {
  1129  			t.Fatal(err)
  1130  		}
  1131  
  1132  		for _, tc := range tests {
  1133  			runDecodedAndEncoded(t, fmt.Sprintf("%s-%d", k, tc.idx), left, func(t *testing.T, j JSON) {
  1134  				result, ok, err := j.RemoveIndex(tc.idx)
  1135  				if tc.errMsg != "" {
  1136  					if err == nil {
  1137  						t.Fatal("expected error")
  1138  					} else if !strings.Contains(err.Error(), tc.errMsg) {
  1139  						t.Fatalf(`expected error message "%s" to contain "%s"`, err.Error(), tc.errMsg)
  1140  					}
  1141  					return
  1142  				}
  1143  				if err != nil {
  1144  					t.Fatal(err)
  1145  				}
  1146  				if tc.ok != ok {
  1147  					t.Fatalf("expected %t, got %t", tc.ok, ok)
  1148  				}
  1149  				c, err := result.Compare(tc.expected)
  1150  				if err != nil {
  1151  					t.Fatal(err)
  1152  				}
  1153  				if c != 0 {
  1154  					t.Fatalf("expected %s, got %s", tc.expected, result)
  1155  				}
  1156  			})
  1157  		}
  1158  	}
  1159  }
  1160  
  1161  func TestEncodeDecodeJSONInvertedIndex(t *testing.T) {
  1162  	testCases := []struct {
  1163  		value  string
  1164  		expEnc []string
  1165  	}{
  1166  		{`{"a":"b"}`, []string{`/"a"/"b"`}},
  1167  		{`null`, []string{`/NULL`}},
  1168  		{`false`, []string{`/False`}},
  1169  		{`true`, []string{`/True`}},
  1170  		{`1.23`, []string{`/1.23`}},
  1171  		{`"a"`, []string{`/"a"`}},
  1172  		{`[]`, []string{`/[]`}},
  1173  		{`{}`, []string{`/{}`}},
  1174  		{`["c", {"a":"b"}]`, []string{`/Arr/"c"`, `/Arr/"a"/"b"`}},
  1175  		{`["c", {"a":["c","d"]}]`, []string{`/Arr/"c"`,
  1176  			`/Arr/"a"/Arr/"c"`,
  1177  			`/Arr/"a"/Arr/"d"`}},
  1178  		{`{"a":[]}`, []string{`/"a"/[]`}},
  1179  		{`{"a":[{}]}`, []string{`/"a"/Arr/{}`}},
  1180  		{`[[],{}]`, []string{`/Arr/[]`, `/Arr/{}`}},
  1181  		{`[["a"]]`, []string{`/Arr/Arr/"a"`}},
  1182  	}
  1183  
  1184  	for _, c := range testCases {
  1185  		enc, err := EncodeInvertedIndexKeys(nil, jsonTestShorthand(c.value))
  1186  		if err != nil {
  1187  			t.Fatal(err)
  1188  		}
  1189  
  1190  		for j, path := range enc {
  1191  			str := encoding.PrettyPrintValue(nil, path, "/")
  1192  			if str != c.expEnc[j] {
  1193  				t.Errorf("unexpected encoding mismatch for %v. expected [%s], got [%s]",
  1194  					c.value, c.expEnc[j], str)
  1195  			}
  1196  		}
  1197  	}
  1198  }
  1199  
  1200  func getApdEncoding(num float64) *apd.Decimal {
  1201  	dec := &apd.Decimal{}
  1202  	dec, _ = dec.SetFloat64(num)
  1203  	return dec
  1204  }
  1205  
  1206  func TestEncodeJSONInvertedIndex(t *testing.T) {
  1207  	jsonPrefix := make([]byte, 1, 100)
  1208  	jsonPrefix[0] = 0x37
  1209  
  1210  	terminator := make([]byte, 2, 100)
  1211  	terminator[0] = 0x00
  1212  	terminator[1] = 0x01
  1213  
  1214  	objectSeparator := make([]byte, 2, 100)
  1215  	objectSeparator[0] = 0x00
  1216  	objectSeparator[1] = 0x02
  1217  
  1218  	arrayPrefix := make([]byte, 2, 100)
  1219  	arrayPrefix[0] = 0x00
  1220  	arrayPrefix[1] = 0x03
  1221  
  1222  	aEncoding := make([]byte, 1, 100)
  1223  	aEncoding[0] = 0x61
  1224  
  1225  	bEncoding := make([]byte, 1, 100)
  1226  	bEncoding[0] = 0x62
  1227  
  1228  	emptyObjectEncoding := make([]byte, 1, 100)
  1229  	emptyObjectEncoding[0] = 0x39
  1230  
  1231  	emptyArrayEncoding := make([]byte, 1, 100)
  1232  	emptyArrayEncoding[0] = 0x38
  1233  
  1234  	testCases := []struct {
  1235  		value  string
  1236  		expEnc [][]byte
  1237  	}{
  1238  		{`{"a":"b"}`, [][]byte{bytes.Join([][]byte{jsonPrefix, aEncoding, terminator, encoding.EncodeStringAscending(nil, "b")},
  1239  			nil)}},
  1240  		{`{"a":{"b":"c"}}`, [][]byte{bytes.Join([][]byte{jsonPrefix, aEncoding, objectSeparator, bEncoding, terminator, encoding.EncodeStringAscending(nil, "c")},
  1241  			nil)}},
  1242  		{`{"a":{"b":[]}}`, [][]byte{bytes.Join([][]byte{jsonPrefix, aEncoding, objectSeparator, bEncoding, terminator, emptyArrayEncoding},
  1243  			nil)}},
  1244  		{`{"a":{"b":{}}}`, [][]byte{bytes.Join([][]byte{jsonPrefix, aEncoding, objectSeparator, bEncoding, terminator, emptyObjectEncoding},
  1245  			nil)}},
  1246  		{`null`, [][]byte{bytes.Join([][]byte{jsonPrefix, terminator, encoding.EncodeNullAscending(nil)},
  1247  			nil)}},
  1248  		{`false`, [][]byte{bytes.Join([][]byte{jsonPrefix, terminator, encoding.EncodeFalseAscending(nil)},
  1249  			nil)}},
  1250  		{`true`, [][]byte{bytes.Join([][]byte{jsonPrefix, terminator, encoding.EncodeTrueAscending(nil)},
  1251  			nil)}},
  1252  		{`1.23`, [][]byte{bytes.Join([][]byte{jsonPrefix, terminator, encoding.EncodeDecimalAscending(nil, getApdEncoding(1.23))},
  1253  			nil)}},
  1254  		{`"a"`, [][]byte{bytes.Join([][]byte{jsonPrefix, terminator, encoding.EncodeStringAscending(nil, "a")},
  1255  			nil)}},
  1256  		{`[["a"]]`, [][]byte{bytes.Join([][]byte{jsonPrefix, arrayPrefix, arrayPrefix, terminator, encoding.EncodeStringAscending(nil, "a")},
  1257  			nil)}},
  1258  		{`{"a":["b","c"]}]`, [][]byte{bytes.Join([][]byte{jsonPrefix, aEncoding, objectSeparator, arrayPrefix, terminator, encoding.EncodeStringAscending(nil, "b")}, nil),
  1259  			bytes.Join([][]byte{jsonPrefix, aEncoding, objectSeparator, arrayPrefix, terminator, encoding.EncodeStringAscending(nil, "c")}, nil)}},
  1260  		{`[]`, [][]byte{bytes.Join([][]byte{jsonPrefix, terminator, emptyArrayEncoding},
  1261  			nil)}},
  1262  		{`{}`, [][]byte{bytes.Join([][]byte{jsonPrefix, terminator, emptyObjectEncoding},
  1263  			nil)}},
  1264  		{`[{}, []]`, [][]byte{bytes.Join([][]byte{jsonPrefix, arrayPrefix, terminator, emptyObjectEncoding},
  1265  			nil),
  1266  			bytes.Join([][]byte{jsonPrefix, arrayPrefix, terminator, emptyArrayEncoding}, nil)}},
  1267  		{`[[[]]]`, [][]byte{bytes.Join([][]byte{jsonPrefix, arrayPrefix, arrayPrefix, terminator, emptyArrayEncoding},
  1268  			nil)}},
  1269  		{`[[{}]]`, [][]byte{bytes.Join([][]byte{jsonPrefix, arrayPrefix, arrayPrefix, terminator, emptyObjectEncoding},
  1270  			nil)}},
  1271  	}
  1272  
  1273  	for _, c := range testCases {
  1274  		enc, err := EncodeInvertedIndexKeys(nil, jsonTestShorthand(c.value))
  1275  		if err != nil {
  1276  			t.Fatal(err)
  1277  		}
  1278  		// Make sure that the expected encoding slice is sorted, as well as the
  1279  		// output of the function under test, because the function under test can
  1280  		// reorder the keys it's returning if there are arrays inside.
  1281  		enc = unique.UniquifyByteSlices(enc)
  1282  		c.expEnc = unique.UniquifyByteSlices(c.expEnc)
  1283  		for j, path := range enc {
  1284  			if !bytes.Equal(path, c.expEnc[j]) {
  1285  				t.Errorf("unexpected encoding mismatch for %v. expected [%#v], got [%#v]",
  1286  					c.value, c.expEnc[j], path)
  1287  			}
  1288  		}
  1289  	}
  1290  }
  1291  
  1292  func TestNumInvertedIndexEntries(t *testing.T) {
  1293  	testCases := []struct {
  1294  		value    string
  1295  		expCount int
  1296  	}{
  1297  		{`1`, 1},
  1298  		{`"a"`, 1},
  1299  		{`null`, 1},
  1300  		{`false`, 1},
  1301  		{`true`, 1},
  1302  		{`[]`, 1},
  1303  		{`{}`, 1},
  1304  		{`[[[]]]`, 1},
  1305  		{`[[{}]]`, 1},
  1306  		{`[{}, []]`, 2},
  1307  		{`[1]`, 1},
  1308  		{`[1, 2]`, 2},
  1309  		{`[1, [1]]`, 2},
  1310  		{`[1, 2, 1, 2]`, 2},
  1311  		{`[[1, 2], [2, 3]]`, 3},
  1312  		{`[{"a": 1, "b": 2}]`, 2},
  1313  		{`[{"a": 1, "b": 2}, {"a": 1, "b": 3}]`, 3},
  1314  		{`[{"a": [1, 2], "b": 2}, {"a": [1, 3], "b": 3}]`, 5},
  1315  	}
  1316  	for _, c := range testCases {
  1317  		n, err := NumInvertedIndexEntries(jsonTestShorthand(c.value))
  1318  		if err != nil {
  1319  			t.Fatal(err)
  1320  		}
  1321  		if n != c.expCount {
  1322  			t.Errorf("unexpected count of index entries for %v. expected %d, got %d",
  1323  				c.value, c.expCount, n)
  1324  		}
  1325  	}
  1326  }
  1327  
  1328  const expectError = "<<error>>"
  1329  
  1330  func TestConcat(t *testing.T) {
  1331  	cases := map[string][]struct {
  1332  		concatWith string
  1333  		expected   string
  1334  	}{
  1335  		`null`: {
  1336  			{`null`, `[null, null]`},
  1337  			{`[]`, `[null]`},
  1338  			{`[1]`, `[null, 1]`},
  1339  			{`{}`, expectError},
  1340  		},
  1341  		`true`: {
  1342  			{`null`, `[true, null]`},
  1343  			{`[]`, `[true]`},
  1344  			{`[1]`, `[true, 1]`},
  1345  			{`{}`, expectError},
  1346  		},
  1347  		`false`: {
  1348  			{`null`, `[false, null]`},
  1349  			{`[]`, `[false]`},
  1350  			{`[1]`, `[false, 1]`},
  1351  			{`{}`, expectError},
  1352  		},
  1353  		`123`: {
  1354  			{`null`, `[123, null]`},
  1355  			{`[]`, `[123]`},
  1356  			{`[1]`, `[123, 1]`},
  1357  			{`{}`, expectError},
  1358  		},
  1359  		`"hello"`: {
  1360  			{`null`, `["hello", null]`},
  1361  			{`[]`, `["hello"]`},
  1362  			{`[1]`, `["hello", 1]`},
  1363  			{`{}`, expectError},
  1364  		},
  1365  		`[1]`: {
  1366  			{`null`, `[1, null]`},
  1367  			{`1`, `[1, 1]`},
  1368  			{`"foo"`, `[1, "foo"]`},
  1369  			{`[2]`, `[1, 2]`},
  1370  			{`[2, 3]`, `[1, 2, 3]`},
  1371  			{`{"a": 1}`, `[1, {"a": 1}]`},
  1372  		},
  1373  		`[1, 2]`: {
  1374  			{`[3]`, `[1, 2, 3]`},
  1375  			{`[3, 4]`, `[1, 2, 3, 4]`},
  1376  		},
  1377  		`{"a": 1}`: {
  1378  			{`null`, expectError},
  1379  			{`1`, expectError},
  1380  			{`"foo"`, expectError},
  1381  			{`[2]`, `[{"a": 1}, 2]`},
  1382  			{`[2, 3]`, `[{"a": 1}, 2, 3]`},
  1383  			{`{"b": 2}`, `{"a": 1, "b": 2}`},
  1384  			{`{"a": 2}`, `{"a": 2}`},
  1385  		},
  1386  		`{"b": 2}`: {
  1387  			{`{"a": 1}`, `{"a": 1, "b": 2}`},
  1388  		},
  1389  		`{"a": 1, "b": 2}`: {
  1390  			{`{"b": 3, "c": 4}`, `{"a": 1, "b": 3, "c": 4}`},
  1391  		},
  1392  	}
  1393  
  1394  	for k, tcs := range cases {
  1395  		left := jsonTestShorthand(k)
  1396  		runDecodedAndEncoded(t, k, left, func(t *testing.T, left JSON) {
  1397  			for _, tc := range tcs {
  1398  				right := jsonTestShorthand(tc.concatWith)
  1399  				runDecodedAndEncoded(t, tc.concatWith, right, func(t *testing.T, right JSON) {
  1400  					if tc.expected == expectError {
  1401  						result, err := left.Concat(right)
  1402  						if err == nil {
  1403  							t.Fatalf("expected %s || %s to error, but got %s", left, right, result)
  1404  						}
  1405  					} else {
  1406  						result, err := left.Concat(right)
  1407  						if err != nil {
  1408  							t.Fatal(err)
  1409  						}
  1410  
  1411  						expectedResult := jsonTestShorthand(tc.expected)
  1412  
  1413  						cmp, err := result.Compare(expectedResult)
  1414  						if err != nil {
  1415  							t.Fatal(err)
  1416  						}
  1417  
  1418  						if cmp != 0 {
  1419  							t.Fatalf("expected %v || %v = %v, got %v", left, right, expectedResult, result)
  1420  						}
  1421  					}
  1422  				})
  1423  			}
  1424  		})
  1425  	}
  1426  }
  1427  
  1428  func TestJSONRandomRoundTrip(t *testing.T) {
  1429  	rng := rand.New(rand.NewSource(timeutil.Now().Unix()))
  1430  	for i := 0; i < 1000; i++ {
  1431  		j, err := Random(20, rng)
  1432  		if err != nil {
  1433  			t.Fatal(err)
  1434  		}
  1435  		j2, err := ParseJSON(j.String())
  1436  		if err != nil {
  1437  			t.Fatal(err)
  1438  		}
  1439  		c, err := j.Compare(j2)
  1440  		if err != nil {
  1441  			t.Fatal(err)
  1442  		}
  1443  		if c != 0 {
  1444  			t.Fatalf("%s did not round-trip, got %s", j.String(), j2.String())
  1445  		}
  1446  	}
  1447  }
  1448  
  1449  func TestJSONContains(t *testing.T) {
  1450  	cases := map[string][]struct {
  1451  		other    string
  1452  		expected bool
  1453  	}{
  1454  		`10`: {
  1455  			{`10`, true},
  1456  			{`9`, false},
  1457  		},
  1458  		`[1, 2, 3]`: {
  1459  			{`{}`, false},
  1460  			{`[]`, true},
  1461  			{`[1]`, true},
  1462  			{`[1.0]`, true},
  1463  			{`[1.00]`, true},
  1464  			{`[1, 2]`, true},
  1465  			{`[1, 2, 2]`, true},
  1466  			{`[2, 1]`, true},
  1467  			{`[1, 4]`, false},
  1468  			{`[4, 1]`, false},
  1469  			{`[4]`, false},
  1470  			// This is a unique, special case that only applies to arrays and
  1471  			// scalars.
  1472  			{`1`, true},
  1473  			{`2`, true},
  1474  			{`3`, true},
  1475  			{`4`, false},
  1476  		},
  1477  		`[[1, 2], 3]`: {
  1478  			{`[1, 2]`, false},
  1479  			{`[[1, 2]]`, true},
  1480  			{`[[2, 1]]`, true},
  1481  			{`[3, [1, 2]]`, true},
  1482  			{`[[1, 2], 3]`, true},
  1483  			{`[[1], [2], 3]`, true},
  1484  			{`[[1], 3]`, true},
  1485  			{`[[2]]`, true},
  1486  			{`[[3]]`, false},
  1487  		},
  1488  		`[]`: {
  1489  			{`[]`, true},
  1490  			{`[1]`, false},
  1491  			{`1`, false},
  1492  			{`{}`, false},
  1493  		},
  1494  		`{}`: {
  1495  			{`{}`, true},
  1496  			{`1`, false},
  1497  			{`{"a":"b"}`, false},
  1498  			{`{"":""}`, false},
  1499  		},
  1500  		`[[1, 2], [3, 4]]`: {
  1501  			{`[[1, 2]]`, true},
  1502  			{`[[3, 4]]`, true},
  1503  			{`[[3, 4, 5]]`, false},
  1504  			{`[[1, 3]]`, false},
  1505  			{`[[2, 4]]`, false},
  1506  			{`[1]`, false},
  1507  			{`[1, 2]`, false},
  1508  		},
  1509  		`{"a": "b", "c": "d"}`: {
  1510  			{`{}`, true},
  1511  			{`{"a": "b"}`, true},
  1512  			{`{"c": "d"}`, true},
  1513  			{`{"a": "b", "c": "d"}`, true},
  1514  			{`{"a": "x"}`, false},
  1515  			{`{"c": "x"}`, false},
  1516  			{`{"y": "x"}`, false},
  1517  			{`{"a": "b", "c": "x"}`, false},
  1518  			{`{"a": "x", "c": "y"}`, false},
  1519  		},
  1520  		`{"a": [1, 2, 3], "c": {"foo": "bar"}}`: {
  1521  			{`{}`, true},
  1522  			{`{"a": [1, 2, 3], "c": {"foo": "bar"}}`, true},
  1523  			{`{"a": [1, 2]}`, true},
  1524  			{`{"a": [2, 1]}`, true},
  1525  			{`{"a": []}`, true},
  1526  			{`{"a": [4]}`, false},
  1527  			{`{"a": [3], "c": {}}`, true},
  1528  			{`{"a": [4], "c": {}}`, false},
  1529  			{`{"a": [3], "c": {"foo": "gup"}}`, false},
  1530  			{`{"a": 3}`, false},
  1531  		},
  1532  		`[{"a": 1}, {"b": 2, "c": 3}, [1], true, false, null, "hello"]`: {
  1533  			{`[]`, true},
  1534  			{`{}`, false},
  1535  			{`{"a": 1}`, false},
  1536  			{`[{"a": 1}]`, true},
  1537  			{`[{"b": 2}]`, true},
  1538  			{`[{"b": 2, "d": 4}]`, false},
  1539  			{`[{"b": 2, "c": 3}]`, true},
  1540  			{`[{"a": 1}, {"b": 2}, {"c": 3}]`, true},
  1541  			{`[{}]`, true},
  1542  			{`[true]`, true},
  1543  			{`[true, false]`, true},
  1544  			{`[false, true]`, true},
  1545  			{`[[1]]`, true},
  1546  			{`[[]]`, true},
  1547  			{`[null, "hello"]`, true},
  1548  			{`["hello", "hello", []]`, true},
  1549  			{`["hello", {"a": 1}, "hello", []]`, true},
  1550  			{`["hello", {"a": 1, "b": 2}, "hello", []]`, false},
  1551  			{`"hello"`, true},
  1552  			{`true`, true},
  1553  			{`false`, true},
  1554  			{`null`, true},
  1555  			{`[1]`, false},
  1556  			{`[[1]]`, true},
  1557  			{`1`, false},
  1558  		},
  1559  		`[{"Ck@P":{"7RZ2\"mZBH":null,"|__v":[1.685483]},"EM%&":{"I{TH":[],"}p@]7sIKC\\$":[]},"f}?#z~":{"#e9>m\"v75'&+":false,"F;,+&r9":{}}},[{}],false,0.498401]`: {
  1560  			{`[false,{}]`, true},
  1561  		},
  1562  	}
  1563  
  1564  	for k, tests := range cases {
  1565  		left, err := ParseJSON(k)
  1566  		if err != nil {
  1567  			t.Fatal(err)
  1568  		}
  1569  
  1570  		for _, tc := range tests {
  1571  			t.Run(fmt.Sprintf("%s @> %s", k, tc.other), func(t *testing.T) {
  1572  				other, err := ParseJSON(tc.other)
  1573  				if err != nil {
  1574  					t.Fatal(err)
  1575  				}
  1576  				result, err := Contains(left, other)
  1577  				if err != nil {
  1578  					t.Fatal(err)
  1579  				}
  1580  
  1581  				checkResult := slowContains(left, other)
  1582  				if result != checkResult {
  1583  					t.Fatal("mismatch between actual contains and slowContains")
  1584  				}
  1585  
  1586  				if tc.expected && !result {
  1587  					t.Fatalf("expected %s @> %s", left, other)
  1588  				} else if !tc.expected && result {
  1589  					t.Fatalf("expected %s to not @> %s", left, other)
  1590  				}
  1591  			})
  1592  		}
  1593  	}
  1594  }
  1595  
  1596  // TestPositiveRandomJSONContains randomly generates a JSON document, generates
  1597  // a subdocument of it, then verifies that it matches under contains.
  1598  func TestPositiveRandomJSONContains(t *testing.T) {
  1599  	rng := rand.New(rand.NewSource(timeutil.Now().Unix()))
  1600  	for i := 0; i < 1000; i++ {
  1601  		j, err := Random(20, rng)
  1602  		if err != nil {
  1603  			t.Fatal(err)
  1604  		}
  1605  
  1606  		subdoc := j.(containsTester).subdocument(true /* isRoot */, rng)
  1607  
  1608  		c, err := Contains(j, subdoc)
  1609  		if err != nil {
  1610  			t.Fatal(err)
  1611  		}
  1612  		if !c {
  1613  			t.Fatal(fmt.Sprintf("%s should contain %s", j, subdoc))
  1614  		}
  1615  		if !slowContains(j, subdoc) {
  1616  			t.Fatal(fmt.Sprintf("%s should slowContains %s", j, subdoc))
  1617  		}
  1618  	}
  1619  }
  1620  
  1621  // We expect that this almost always results in a non-contained pair..
  1622  func TestNegativeRandomJSONContains(t *testing.T) {
  1623  	rng := rand.New(rand.NewSource(timeutil.Now().Unix()))
  1624  	for i := 0; i < 1000; i++ {
  1625  		j1, err := Random(20, rng)
  1626  		if err != nil {
  1627  			t.Fatal(err)
  1628  		}
  1629  
  1630  		j2, err := Random(20, rng)
  1631  		if err != nil {
  1632  			t.Fatal(err)
  1633  		}
  1634  
  1635  		realResult, err := Contains(j1, j2)
  1636  		if err != nil {
  1637  			t.Fatal(err)
  1638  		}
  1639  		slowResult := slowContains(j1, j2)
  1640  		if realResult != slowResult {
  1641  			t.Fatal("mismatch for document " + j1.String() + " @> " + j2.String())
  1642  		}
  1643  	}
  1644  }
  1645  
  1646  func TestPretty(t *testing.T) {
  1647  	cases := []struct {
  1648  		input    string
  1649  		expected string
  1650  	}{
  1651  		{`true`, `true`},
  1652  		{`1`, `1`},
  1653  		{`1.0`, `1.0`},
  1654  		{`1.00`, `1.00`},
  1655  		{`"hello"`, `"hello"`},
  1656  		{`["hello"]`,
  1657  			`[
  1658      "hello"
  1659  ]`},
  1660  		{`["hello", "world"]`,
  1661  			`[
  1662      "hello",
  1663      "world"
  1664  ]`},
  1665  		{`["hello", ["world"]]`,
  1666  			`[
  1667      "hello",
  1668      [
  1669          "world"
  1670      ]
  1671  ]`},
  1672  		{`{"a": 1}`,
  1673  			`{
  1674      "a": 1
  1675  }`},
  1676  		{`{"a": 1, "b": 2}`,
  1677  			`{
  1678      "a": 1,
  1679      "b": 2
  1680  }`},
  1681  		{`{"a": 1, "b": {"c": 3}}`,
  1682  			`{
  1683      "a": 1,
  1684      "b": {
  1685          "c": 3
  1686      }
  1687  }`},
  1688  	}
  1689  
  1690  	for _, tc := range cases {
  1691  		j := jsonTestShorthand(tc.input)
  1692  		runDecodedAndEncoded(t, tc.input, j, func(t *testing.T, j JSON) {
  1693  			pretty, err := Pretty(j)
  1694  			if err != nil {
  1695  				t.Fatal(err)
  1696  			}
  1697  			if pretty != tc.expected {
  1698  				t.Fatalf("expected:\n%s\ngot:\n%s\n", tc.expected, pretty)
  1699  			}
  1700  		})
  1701  	}
  1702  }
  1703  
  1704  func TestHasContainerLeaf(t *testing.T) {
  1705  	cases := []struct {
  1706  		input    string
  1707  		expected bool
  1708  	}{
  1709  		{`true`, false},
  1710  		{`false`, false},
  1711  		{`1`, false},
  1712  		{`[]`, true},
  1713  		{`{}`, true},
  1714  		{`{"a": 1}`, false},
  1715  		{`{"a": {"b": 3}, "x": "y", "c": []}`, true},
  1716  		{`{"a": {"b": 3}, "c": [], "x": "y"}`, true},
  1717  		{`{"a": {}}`, true},
  1718  		{`{"a": []}`, true},
  1719  		{`[]`, true},
  1720  		{`[[]]`, true},
  1721  		{`[1, 2, 3, []]`, true},
  1722  		{`[1, 2, [], 3]`, true},
  1723  		{`[[], 1, 2, 3]`, true},
  1724  		{`[1, 2, 3]`, false},
  1725  		{`[[1, 2, 3]]`, false},
  1726  		{`[[1, 2], 3]`, false},
  1727  		{`[1, 2, 3, [4]]`, false},
  1728  	}
  1729  
  1730  	for _, tc := range cases {
  1731  		j := jsonTestShorthand(tc.input)
  1732  		runDecodedAndEncoded(t, tc.input, j, func(t *testing.T, j JSON) {
  1733  			result, err := j.HasContainerLeaf()
  1734  			if err != nil {
  1735  				t.Fatal(err)
  1736  			}
  1737  			if result != tc.expected {
  1738  				t.Fatalf("expected:\n%v\ngot:\n%v\n", tc.expected, result)
  1739  			}
  1740  		})
  1741  	}
  1742  }
  1743  
  1744  func BenchmarkBuildJSONObject(b *testing.B) {
  1745  	for _, objectSize := range []int{1, 10, 100, 1000, 10000, 100000} {
  1746  		keys := make([]string, objectSize)
  1747  		for i := 0; i < objectSize; i++ {
  1748  			keys[i] = fmt.Sprintf("key%d", i)
  1749  		}
  1750  		for i := 0; i < objectSize; i++ {
  1751  			p := rand.Intn(objectSize-i) + i
  1752  			keys[i], keys[p] = keys[p], keys[i]
  1753  		}
  1754  		b.Run(fmt.Sprintf("object size %d", objectSize), func(b *testing.B) {
  1755  			b.Run("from builder", func(b *testing.B) {
  1756  				for n := 0; n < b.N; n++ {
  1757  					builder := NewObjectBuilder(0)
  1758  					for i, k := range keys {
  1759  						builder.Add(k, FromInt(i))
  1760  					}
  1761  					_ = builder.Build()
  1762  				}
  1763  			})
  1764  
  1765  			b.Run("from go map", func(b *testing.B) {
  1766  				for n := 0; n < b.N; n++ {
  1767  					m := map[string]interface{}{}
  1768  					for i, k := range keys {
  1769  						m[k] = FromInt(i)
  1770  					}
  1771  					if _, err := fromMap(m); err != nil {
  1772  						b.Fatal(err)
  1773  					}
  1774  				}
  1775  			})
  1776  		})
  1777  	}
  1778  }
  1779  
  1780  func BenchmarkArrayConcat(b *testing.B) {
  1781  	for _, arraySize := range []int{1, 10, 100, 1000, 10000} {
  1782  		b.Run(fmt.Sprintf("concat two arrays with size %d", arraySize), func(b *testing.B) {
  1783  			arr := make([]interface{}, arraySize)
  1784  			for i := 0; i < arraySize; i++ {
  1785  				arr[i] = i
  1786  			}
  1787  			left, err := MakeJSON(arr)
  1788  			if err != nil {
  1789  				b.Fatal(err)
  1790  			}
  1791  			right, err := MakeJSON(arr)
  1792  			if err != nil {
  1793  				b.Fatal(err)
  1794  			}
  1795  			b.ResetTimer()
  1796  			for i := 0; i < b.N; i++ {
  1797  				_, err = left.Concat(right)
  1798  				if err != nil {
  1799  					b.Fatal(err)
  1800  				}
  1801  			}
  1802  		})
  1803  	}
  1804  }
  1805  
  1806  func BenchmarkObjectStripNulls(b *testing.B) {
  1807  	for _, objectSize := range []int{1, 10, 100, 1000} {
  1808  		b.Run(fmt.Sprintf("object size %d no need to strip", objectSize), func(b *testing.B) {
  1809  			builder := NewObjectBuilder(0)
  1810  			for i := 0; i < objectSize; i++ {
  1811  				builder.Add(strconv.Itoa(i), FromInt(i))
  1812  			}
  1813  			obj := builder.Build()
  1814  			b.ResetTimer()
  1815  			for i := 0; i < b.N; i++ {
  1816  				_, _, err := obj.StripNulls()
  1817  				if err != nil {
  1818  					b.Fatal(err)
  1819  				}
  1820  			}
  1821  		})
  1822  		b.Run(fmt.Sprintf("object size %d need to strip", objectSize), func(b *testing.B) {
  1823  			builder := NewObjectBuilder(0)
  1824  			builder.Add(strconv.Itoa(0), NullJSONValue)
  1825  			for i := 1; i < objectSize; i++ {
  1826  				builder.Add(strconv.Itoa(i), FromInt(i))
  1827  			}
  1828  			obj := builder.Build()
  1829  			b.ResetTimer()
  1830  			for i := 0; i < b.N; i++ {
  1831  				_, _, err := obj.StripNulls()
  1832  				if err != nil {
  1833  					b.Fatal(err)
  1834  				}
  1835  			}
  1836  		})
  1837  	}
  1838  }
  1839  
  1840  func BenchmarkFetchFromArray(b *testing.B) {
  1841  	for _, arraySize := range []int{1, 10, 100, 1000} {
  1842  		b.Run(fmt.Sprintf("array size %d", arraySize), func(b *testing.B) {
  1843  			ary := make([]interface{}, arraySize)
  1844  			for i := 0; i < len(ary); i++ {
  1845  				ary[i] = i
  1846  			}
  1847  			j, err := MakeJSON(ary)
  1848  			if err != nil {
  1849  				b.Fatal(err)
  1850  			}
  1851  
  1852  			_, encoding, err := j.encode(nil)
  1853  			if err != nil {
  1854  				b.Fatal(err)
  1855  			}
  1856  
  1857  			encoded, err := newEncodedFromRoot(encoding)
  1858  			if err != nil {
  1859  				b.Fatal(err)
  1860  			}
  1861  
  1862  			b.ResetTimer()
  1863  
  1864  			for i := 0; i < b.N; i++ {
  1865  				_, _ = encoded.FetchValIdx(rand.Intn(arraySize))
  1866  			}
  1867  		})
  1868  	}
  1869  }
  1870  
  1871  func BenchmarkFetchKey(b *testing.B) {
  1872  	for _, objectSize := range []int{1, 10, 100, 1000} {
  1873  		b.Run(fmt.Sprintf("object size %d", objectSize), func(b *testing.B) {
  1874  			keys := make([]string, objectSize)
  1875  
  1876  			obj := make(map[string]interface{})
  1877  			for i := 0; i < objectSize; i++ {
  1878  				key := fmt.Sprintf("key%d", i)
  1879  				keys = append(keys, key)
  1880  				obj[key] = i
  1881  			}
  1882  			j, err := MakeJSON(obj)
  1883  			if err != nil {
  1884  				b.Fatal(err)
  1885  			}
  1886  
  1887  			b.Run("fetch key", func(b *testing.B) {
  1888  				for i := 0; i < b.N; i++ {
  1889  					_, _ = j.FetchValKey(keys[rand.Intn(len(keys))])
  1890  				}
  1891  			})
  1892  
  1893  			encoding, err := EncodeJSON(nil, j)
  1894  			if err != nil {
  1895  				b.Fatal(err)
  1896  			}
  1897  
  1898  			encoded, err := newEncodedFromRoot(encoding)
  1899  			if err != nil {
  1900  				b.Fatal(err)
  1901  			}
  1902  
  1903  			b.Run("fetch key by decoding and then reading", func(b *testing.B) {
  1904  				for i := 0; i < b.N; i++ {
  1905  					// This is a hack to get around the decoded caching.
  1906  					encoded.mu.cachedDecoded = nil
  1907  
  1908  					decoded, err := encoded.shallowDecode()
  1909  					if err != nil {
  1910  						b.Fatal(err)
  1911  					}
  1912  					_, _ = decoded.FetchValKey(keys[rand.Intn(len(keys))])
  1913  				}
  1914  			})
  1915  
  1916  			b.Run("fetch key encoded", func(b *testing.B) {
  1917  				encoded, err := newEncodedFromRoot(encoding)
  1918  				if err != nil {
  1919  					b.Fatal(err)
  1920  				}
  1921  				for i := 0; i < b.N; i++ {
  1922  					_, _ = encoded.FetchValKey(keys[rand.Intn(len(keys))])
  1923  				}
  1924  			})
  1925  		})
  1926  	}
  1927  }
  1928  
  1929  func BenchmarkJSONNumInvertedIndexEntries(b *testing.B) {
  1930  	j := jsonTestShorthand(sampleJSON)
  1931  	b.ResetTimer()
  1932  	for i := 0; i < b.N; i++ {
  1933  		_, _ = NumInvertedIndexEntries(j)
  1934  	}
  1935  }
  1936  
  1937  func TestJSONRemovePath(t *testing.T) {
  1938  	queryTests := map[string][]struct {
  1939  		path     []string
  1940  		ok       bool
  1941  		expected string
  1942  		errMsg   string
  1943  	}{
  1944  		`{"foo": 1}`: {
  1945  			{path: []string{"foa"}, ok: false, expected: `{"foo": 1}`},
  1946  			{path: []string{"foo"}, ok: true, expected: `{}`},
  1947  			{path: []string{"foz"}, ok: false, expected: `{"foo": 1}`},
  1948  			{path: []string{}, ok: false, expected: `{"foo": 1}`},
  1949  			{path: []string{"bar"}, ok: false, expected: `{"foo": 1}`},
  1950  		},
  1951  		`{"foo": {"bar": 1, "baz": 2}}`: {
  1952  			{path: []string{}, ok: false, expected: `{"foo": {"bar": 1, "baz": 2}}`},
  1953  			{path: []string{"foo"}, ok: true, expected: `{}`},
  1954  			{path: []string{"foo", "bar"}, ok: true, expected: `{"foo": {"baz": 2}}`},
  1955  			{path: []string{"foo", "bar", "gup"}, ok: false, expected: `{"foo": {"bar": 1, "baz": 2}}`},
  1956  			{path: []string{"foo", "baz"}, ok: true, expected: `{"foo": {"bar": 1}}`},
  1957  		},
  1958  		`{"foo": {"bar": 1, "baz": {"gup": 3}}}`: {
  1959  			{path: []string{}, ok: false, expected: `{"foo": {"bar": 1, "baz": {"gup": 3}}}`},
  1960  			{path: []string{"foo"}, ok: true, expected: `{}`},
  1961  			{path: []string{"foo", "bar"}, ok: true, expected: `{"foo": {"baz": {"gup": 3}}}`},
  1962  			{path: []string{"foo", "baz"}, ok: true, expected: `{"foo": {"bar": 1}}`},
  1963  			{path: []string{"foo", "baz", "gup"}, ok: true, expected: `{"foo": {"bar": 1, "baz": {}}}`},
  1964  		},
  1965  		`{"foo": [1, 2, {"bar": 3}]}`: {
  1966  			{path: []string{}, ok: false, expected: `{"foo": [1, 2, {"bar": 3}]}`},
  1967  			{path: []string{`foo`}, ok: true, expected: `{}`},
  1968  			{path: []string{`foo`, `0`}, ok: true, expected: `{"foo": [2, {"bar": 3}]}`},
  1969  			{path: []string{`foo`, `1`}, ok: true, expected: `{"foo": [1, {"bar": 3}]}`},
  1970  			{path: []string{`foo`, `2`}, ok: true, expected: `{"foo": [1, 2]}`},
  1971  			{path: []string{`foo`, `2`, `bar`}, ok: true, expected: `{"foo": [1, 2, {}]}`},
  1972  			{path: []string{`foo`, `-3`}, ok: true, expected: `{"foo": [2, {"bar": 3}]}`},
  1973  			{path: []string{`foo`, `-2`}, ok: true, expected: `{"foo": [1, {"bar": 3}]}`},
  1974  			{path: []string{`foo`, `-1`}, ok: true, expected: `{"foo": [1, 2]}`},
  1975  			{path: []string{`foo`, `-1`, `bar`}, ok: true, expected: `{"foo": [1, 2, {}]}`},
  1976  		},
  1977  		`[[1]]`: {
  1978  			{path: []string{"0", "0"}, ok: true, expected: `[[]]`},
  1979  		},
  1980  		`[1]`: {
  1981  			{path: []string{"foo"}, ok: false, expected: "", errMsg: "a path element is not an integer: foo"},
  1982  			{path: []string{""}, ok: false, expected: "", errMsg: "a path element is not an integer: "},
  1983  			{path: []string{"0"}, ok: true, expected: `[]`},
  1984  			{path: []string{"0", "0"}, ok: false, expected: `[1]`},
  1985  		},
  1986  		`1`: {
  1987  			{path: []string{"foo"}, errMsg: "cannot delete path in scalar"},
  1988  		},
  1989  	}
  1990  
  1991  	for k, tests := range queryTests {
  1992  		left, err := ParseJSON(k)
  1993  		if err != nil {
  1994  			t.Fatal(err)
  1995  		}
  1996  
  1997  		for _, tc := range tests {
  1998  			t.Run(fmt.Sprintf("%s #- %v", k, tc.path), func(t *testing.T) {
  1999  				result, ok, err := left.RemovePath(tc.path)
  2000  				if tc.errMsg != "" {
  2001  					if err == nil {
  2002  						t.Fatal("expected error")
  2003  					} else if !strings.Contains(err.Error(), tc.errMsg) {
  2004  						t.Fatalf(`expected error message "%s" to contain "%s"`, err.Error(), tc.errMsg)
  2005  					}
  2006  					return
  2007  				}
  2008  				if err != nil {
  2009  					t.Fatal(err)
  2010  				}
  2011  				if tc.ok != ok {
  2012  					t.Fatalf("expected %t, got %t", tc.ok, ok)
  2013  				}
  2014  				cmp, err := result.Compare(jsonTestShorthand(tc.expected))
  2015  				if err != nil {
  2016  					t.Fatal(err)
  2017  				}
  2018  				if cmp != 0 {
  2019  					t.Fatalf("expected %s, got %s", tc.expected, result.String())
  2020  				}
  2021  			})
  2022  		}
  2023  	}
  2024  }