Require multiarr results to always exist

This commit is contained in:
tidwall 2019-06-28 05:24:28 -07:00
parent e91a88bec4
commit d95cbcaa9d
2 changed files with 80 additions and 10 deletions

View File

@ -1267,6 +1267,11 @@ func parseArray(c *parseContext, i int, path string) (int, bool) {
} else { } else {
i, val = parseSquash(c.json, i) i, val = parseSquash(c.json, i)
if rp.query.on { if rp.query.on {
if rp.query.all {
if len(multires) == 0 {
multires = append(multires, '[')
}
}
res := Get(val, rp.query.path) res := Get(val, rp.query.path)
if queryMatches(&rp, res) { if queryMatches(&rp, res) {
if rp.more { if rp.more {
@ -1281,10 +1286,6 @@ func parseArray(c *parseContext, i int, path string) (int, bool) {
res = Result{Raw: val, Type: JSON} res = Result{Raw: val, Type: JSON}
} }
if rp.query.all { if rp.query.all {
if len(multires) == 0 {
multires = append(multires, '[')
}
raw := res.Raw raw := res.Raw
if len(raw) == 0 { if len(raw) == 0 {
raw = res.String() raw = res.String()

View File

@ -154,6 +154,7 @@ func TestParseAny(t *testing.T) {
assert(t, Parse("100").Float() == 100) assert(t, Parse("100").Float() == 100)
assert(t, Parse("true").Bool()) assert(t, Parse("true").Bool())
assert(t, Parse("false").Bool() == false) assert(t, Parse("false").Bool() == false)
assert(t, Parse("yikes").Exists() == false)
} }
func TestManyVariousPathCounts(t *testing.T) { func TestManyVariousPathCounts(t *testing.T) {
@ -1104,6 +1105,7 @@ func makeRandomJSONChars(b []byte) {
} }
copy(b, bb[:len(b)]) copy(b, bb[:len(b)])
} }
func TestValidRandom(t *testing.T) { func TestValidRandom(t *testing.T) {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
b := make([]byte, 100000) b := make([]byte, 100000)
@ -1183,12 +1185,12 @@ func TestNullArray(t *testing.T) {
} }
} }
func TestRandomGetMany(t *testing.T) { // func TestRandomGetMany(t *testing.T) {
start := time.Now() // start := time.Now()
for time.Since(start) < time.Second*3 { // for time.Since(start) < time.Second*3 {
testRandomGetMany(t) // testRandomGetMany(t)
} // }
} // }
func testRandomGetMany(t *testing.T) { func testRandomGetMany(t *testing.T) {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
json, keys := randomJSON() json, keys := randomJSON()
@ -1760,4 +1762,71 @@ func TestMultiArrayEx(t *testing.T) {
t.Fatalf("expected '%v', got '%v'", ``, res) t.Fatalf("expected '%v', got '%v'", ``, res)
} }
res = Get(json, `i*.f*.#[kind="Other"]#`).String()
if res != `[]` {
t.Fatalf("expected '%v', got '%v'", `[]`, res)
}
}
func TestQueries(t *testing.T) {
json := `{
"info": {
"friends": [
{
"first": "Dale", "last": "Murphy", "kind": "Person",
"cust1": true,
"extra": [10,20,30],
"details": {
"city": "Tempe",
"state": "Arizona"
}
},
{
"first": "Roger", "last": "Craig", "kind": "Person",
"cust2": false,
"extra": [40,50,60],
"details": {
"city": "Phoenix",
"state": "Arizona"
}
}
]
}
}`
// numbers
assert(t, Get(json, "i*.f*.#[extra.0<11].first").Exists())
assert(t, Get(json, "i*.f*.#[extra.0<=11].first").Exists())
assert(t, !Get(json, "i*.f*.#[extra.0<10].first").Exists())
assert(t, Get(json, "i*.f*.#[extra.0<=10].first").Exists())
assert(t, Get(json, "i*.f*.#[extra.0=10].first").Exists())
assert(t, !Get(json, "i*.f*.#[extra.0=11].first").Exists())
assert(t, Get(json, "i*.f*.#[extra.0!=10].first").String() == "Roger")
assert(t, Get(json, "i*.f*.#[extra.0>10].first").String() == "Roger")
assert(t, Get(json, "i*.f*.#[extra.0>=10].first").String() == "Dale")
// strings
assert(t, Get(json, `i*.f*.#[extra.0<"11"].first`).Exists())
assert(t, Get(json, `i*.f*.#[first>"Dale"].last`).String() == "Craig")
assert(t, Get(json, `i*.f*.#[first>="Dale"].last`).String() == "Murphy")
assert(t, Get(json, `i*.f*.#[first="Dale"].last`).String() == "Murphy")
assert(t, Get(json, `i*.f*.#[first!="Dale"].last`).String() == "Craig")
assert(t, !Get(json, `i*.f*.#[first<"Dale"].last`).Exists())
assert(t, Get(json, `i*.f*.#[first<="Dale"].last`).Exists())
assert(t, Get(json, `i*.f*.#[first%"Da*"].last`).Exists())
assert(t, Get(json, `i*.f*.#[first%"Dale"].last`).Exists())
assert(t, Get(json, `i*.f*.#[first%"*a*"]#|#`).String() == "1")
assert(t, Get(json, `i*.f*.#[first%"*e*"]#|#`).String() == "2")
assert(t, Get(json, `i*.f*.#[first!%"*e*"]#|#`).String() == "0")
// trues
assert(t, Get(json, `i*.f*.#[cust1=true].first`).String() == "Dale")
assert(t, Get(json, `i*.f*.#[cust2=false].first`).String() == "Roger")
assert(t, Get(json, `i*.f*.#[cust1!=false].first`).String() == "Dale")
assert(t, Get(json, `i*.f*.#[cust2!=true].first`).String() == "Roger")
assert(t, !Get(json, `i*.f*.#[cust1>true].first`).Exists())
assert(t, Get(json, `i*.f*.#[cust1>=true].first`).Exists())
assert(t, !Get(json, `i*.f*.#[cust2<false].first`).Exists())
assert(t, Get(json, `i*.f*.#[cust2<=false].first`).Exists())
} }