blob: 5e7f73c0318b5ebab8ac3de7250416e794d12a2b [file]
package jpath
import (
"fmt"
"math"
"testing"
)
func pathString(path QueryPath) string {
result := "["
for _, v := range path {
result += fmt.Sprintf("%T:%v, ", v, v)
}
return result + "]"
}
func assertPathMatch(t *testing.T, path, ref QueryPath) bool {
if len(path) != len(ref) {
t.Errorf("lengths do not match: %v vs %v",
pathString(path), pathString(ref))
return false
} else {
for i, v := range ref {
pass := false
node := path[i]
// compare by value
switch refNode := v.(type) {
case *matchKeyFn:
castNode, ok := node.(*matchKeyFn)
pass = ok && (*refNode == *castNode)
case *matchIndexFn:
castNode, ok := node.(*matchIndexFn)
pass = ok && (*refNode == *castNode)
case *matchSliceFn:
castNode, ok := node.(*matchSliceFn)
pass = ok && (*refNode == *castNode)
case *matchAnyFn:
castNode, ok := node.(*matchAnyFn)
pass = ok && (*refNode == *castNode)
case *matchUnionFn:
castNode, ok := node.(*matchUnionFn)
// special case - comapre all contents
pass = ok && assertPathMatch(t, castNode.Union, refNode.Union)
case *matchRecursiveFn:
castNode, ok := node.(*matchRecursiveFn)
pass = ok && (*refNode == *castNode)
}
if !pass {
t.Errorf("paths do not match at index %d: %v vs %v",
i, pathString(path), pathString(ref))
return false
}
}
}
return true
}
func assertPath(t *testing.T, query string, ref QueryPath) {
_, flow := lex(query)
path := parse(flow)
assertPathMatch(t, path, ref)
}
func TestPathRoot(t *testing.T) {
assertPath(t,
"$",
QueryPath{
// empty
})
}
func TestPathKey(t *testing.T) {
assertPath(t,
"$.foo",
QueryPath{
&matchKeyFn{ "foo" },
})
}
func TestPathBracketKey(t *testing.T) {
assertPath(t,
"$[foo]",
QueryPath{
&matchKeyFn{ "foo" },
})
}
func TestPathBracketStringKey(t *testing.T) {
assertPath(t,
"$['foo']",
QueryPath{
&matchKeyFn{ "foo" },
})
}
func TestPathIndex(t *testing.T) {
assertPath(t,
"$[123]",
QueryPath{
&matchIndexFn{ 123 },
})
}
func TestPathSliceStart(t *testing.T) {
assertPath(t,
"$[123:]",
QueryPath{
&matchSliceFn{ 123, math.MaxInt64, 1 },
})
}
func TestPathSliceStartEnd(t *testing.T) {
assertPath(t,
"$[123:456]",
QueryPath{
&matchSliceFn{ 123, 456, 1 },
})
}
func TestPathSliceStartEndColon(t *testing.T) {
assertPath(t,
"$[123:456:]",
QueryPath{
&matchSliceFn{ 123, 456, 1 },
})
}
func TestPathSliceStartStep(t *testing.T) {
assertPath(t,
"$[123::7]",
QueryPath{
&matchSliceFn{ 123, math.MaxInt64, 7 },
})
}
func TestPathSliceEndStep(t *testing.T) {
assertPath(t,
"$[:456:7]",
QueryPath{
&matchSliceFn{ 0, 456, 7 },
})
}
func TestPathSliceStep(t *testing.T) {
assertPath(t,
"$[::7]",
QueryPath{
&matchSliceFn{ 0, math.MaxInt64, 7 },
})
}
func TestPathSliceAll(t *testing.T) {
assertPath(t,
"$[123:456:7]",
QueryPath{
&matchSliceFn{ 123, 456, 7 },
})
}
func TestPathAny(t *testing.T) {
assertPath(t,
"$.*",
QueryPath{
&matchAnyFn{},
})
}
func TestPathUnion(t *testing.T) {
assertPath(t,
"$[foo, bar, baz]",
QueryPath{
&matchUnionFn{ []PathFn {
&matchKeyFn{ "foo" },
&matchKeyFn{ "bar" },
&matchKeyFn{ "baz" },
}},
})
}
func TestPathRecurse(t *testing.T) {
assertPath(t,
"$..*",
QueryPath{
&matchRecursiveFn{},
})
}