mirror of https://github.com/tidwall/tile38.git
Add expression errors test. Make parser stricter.
This commit is contained in:
parent
0c3a5d02ca
commit
2d83e18934
|
@ -712,7 +712,7 @@ func (ps *parentStack) pop() (e *areaExpression, empty bool) {
|
|||
func (s *Server) parseAreaExpression(vsin []string, doClip bool) (vsout []string, ae *areaExpression, err error) {
|
||||
ps := &parentStack{}
|
||||
vsout = vsin[:]
|
||||
var negate bool
|
||||
var negate, needObj bool
|
||||
loop:
|
||||
for {
|
||||
nvs, wtok, ok := tokenval(vsout)
|
||||
|
@ -723,6 +723,7 @@ loop:
|
|||
case tokenLParen:
|
||||
newExpr := &areaExpression{negate: negate, op: NOOP}
|
||||
negate = false
|
||||
needObj = false
|
||||
if ae != nil {
|
||||
ae.children = append(ae.children, newExpr)
|
||||
}
|
||||
|
@ -730,8 +731,8 @@ loop:
|
|||
ps.push(ae)
|
||||
vsout = nvs
|
||||
case tokenRParen:
|
||||
if negate {
|
||||
err = errInvalidArgument(tokenNOT)
|
||||
if needObj {
|
||||
err = errInvalidArgument(tokenRParen)
|
||||
return
|
||||
}
|
||||
if parent, empty := ps.pop(); empty {
|
||||
|
@ -743,12 +744,14 @@ loop:
|
|||
vsout = nvs
|
||||
case tokenNOT:
|
||||
negate = true
|
||||
needObj = true
|
||||
vsout = nvs
|
||||
case tokenAND:
|
||||
if negate {
|
||||
err = errInvalidArgument(tokenNOT)
|
||||
if needObj {
|
||||
err = errInvalidArgument(tokenAND)
|
||||
return
|
||||
}
|
||||
needObj = true
|
||||
if ae == nil {
|
||||
err = errInvalidArgument(tokenAND)
|
||||
return
|
||||
|
@ -774,10 +777,11 @@ loop:
|
|||
}
|
||||
vsout = nvs
|
||||
case tokenOR:
|
||||
if negate {
|
||||
err = errInvalidArgument(tokenNOT)
|
||||
if needObj {
|
||||
err = errInvalidArgument(tokenOR)
|
||||
return
|
||||
}
|
||||
needObj = true
|
||||
if ae == nil {
|
||||
err = errInvalidArgument(tokenOR)
|
||||
return
|
||||
|
@ -804,6 +808,7 @@ loop:
|
|||
} else {
|
||||
newExpr := &areaExpression{negate: negate, obj: parsedObj, op: NOOP}
|
||||
negate = false
|
||||
needObj = false
|
||||
if ae == nil {
|
||||
ae = newExpr
|
||||
} else {
|
||||
|
@ -812,12 +817,15 @@ loop:
|
|||
vsout = parsedVs
|
||||
}
|
||||
default:
|
||||
if negate {
|
||||
err = errInvalidArgument(tokenNOT)
|
||||
if needObj {
|
||||
err = errInvalidArgument(wtok)
|
||||
return
|
||||
}
|
||||
break loop
|
||||
}
|
||||
}
|
||||
if !ps.isEmpty() || needObj || ae == nil || (ae.obj == nil && len(ae.children) == 0) {
|
||||
err = errInvalidNumberOfArguments
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ func subTestTestCmd(t *testing.T, mc *mockServer) {
|
|||
runStep(t, mc, "WITHIN", testcmd_WITHIN_test)
|
||||
runStep(t, mc, "INTERSECTS", testcmd_INTERSECTS_test)
|
||||
runStep(t, mc, "INTERSECTS_CLIP", testcmd_INTERSECTS_CLIP_test)
|
||||
runStep(t, mc, "ExpressionErrors", testcmd_expressionErrors_test)
|
||||
runStep(t, mc, "Expressions", testcmd_expression_test)
|
||||
}
|
||||
|
||||
|
@ -117,6 +118,40 @@ func testcmd_INTERSECTS_CLIP_test(mc *mockServer) error {
|
|||
})
|
||||
}
|
||||
|
||||
func testcmd_expressionErrors_test(mc *mockServer) error {
|
||||
return mc.DoBatch([][]interface{}{
|
||||
{"SET", "mykey", "foo", "OBJECT", `{"type":"LineString","coordinates":[[-122.4408378,37.7341129],[-122.4408378,37.733]]}`}, {"OK"},
|
||||
{"SET", "mykey", "bar", "OBJECT", `{"type":"LineString","coordinates":[[-122.4408378,37.7341129],[-122.4408378,37.733]]}`}, {"OK"},
|
||||
{"SET", "mykey", "baz", "OBJECT", `{"type":"LineString","coordinates":[[-122.4408378,37.7341129],[-122.4408378,37.733]]}`}, {"OK"},
|
||||
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "(", "GET", "mykey", "bar"}, {
|
||||
"ERR wrong number of arguments for 'test' command"},
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "GET", "mykey", "bar", ")"}, {
|
||||
"ERR invalid argument ')'"},
|
||||
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "OR", "GET", "mykey", "bar"}, {
|
||||
"ERR invalid argument 'or'"},
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "AND", "GET", "mykey", "bar"}, {
|
||||
"ERR invalid argument 'and'"},
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "GET", "mykey", "bar", "OR", "AND", "GET", "mykey", "baz"}, {
|
||||
"ERR invalid argument 'and'"},
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "GET", "mykey", "bar", "AND", "OR", "GET", "mykey", "baz"}, {
|
||||
"ERR invalid argument 'or'"},
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "GET", "mykey", "bar", "OR", "OR", "GET", "mykey", "baz"}, {
|
||||
"ERR invalid argument 'or'"},
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "GET", "mykey", "bar", "AND", "AND", "GET", "mykey", "baz"}, {
|
||||
"ERR invalid argument 'and'"},
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "GET", "mykey", "bar", "OR"}, {
|
||||
"ERR wrong number of arguments for 'test' command"},
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "GET", "mykey", "bar", "AND"}, {
|
||||
"ERR wrong number of arguments for 'test' command"},
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "GET", "mykey", "bar", "NOT"}, {
|
||||
"ERR wrong number of arguments for 'test' command"},
|
||||
{"TEST", "GET", "mykey", "foo", "INTERSECTS", "GET", "mykey", "bar", "NOT", "AND", "GET", "mykey", "baz"}, {
|
||||
"ERR invalid argument 'and'"},
|
||||
})
|
||||
}
|
||||
|
||||
func testcmd_expression_test(mc *mockServer) error {
|
||||
poly := `{
|
||||
"type": "Polygon",
|
||||
|
|
Loading…
Reference in New Issue