203 lines
3.4 KiB
Go
203 lines
3.4 KiB
Go
|
package query
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"github.com/pelletier/go-toml"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
// dump path tree to a string
|
||
|
func pathString(root pathFn) string {
|
||
|
result := fmt.Sprintf("%T:", root)
|
||
|
switch fn := root.(type) {
|
||
|
case *terminatingFn:
|
||
|
result += "{}"
|
||
|
case *matchKeyFn:
|
||
|
result += fmt.Sprintf("{%s}", fn.Name)
|
||
|
result += pathString(fn.next)
|
||
|
case *matchIndexFn:
|
||
|
result += fmt.Sprintf("{%d}", fn.Idx)
|
||
|
result += pathString(fn.next)
|
||
|
case *matchSliceFn:
|
||
|
result += fmt.Sprintf("{%d:%d:%d}",
|
||
|
fn.Start, fn.End, fn.Step)
|
||
|
result += pathString(fn.next)
|
||
|
case *matchAnyFn:
|
||
|
result += "{}"
|
||
|
result += pathString(fn.next)
|
||
|
case *matchUnionFn:
|
||
|
result += "{["
|
||
|
for _, v := range fn.Union {
|
||
|
result += pathString(v) + ", "
|
||
|
}
|
||
|
result += "]}"
|
||
|
case *matchRecursiveFn:
|
||
|
result += "{}"
|
||
|
result += pathString(fn.next)
|
||
|
case *matchFilterFn:
|
||
|
result += fmt.Sprintf("{%s}", fn.Name)
|
||
|
result += pathString(fn.next)
|
||
|
}
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func assertPathMatch(t *testing.T, path, ref *Query) bool {
|
||
|
pathStr := pathString(path.root)
|
||
|
refStr := pathString(ref.root)
|
||
|
if pathStr != refStr {
|
||
|
t.Errorf("paths do not match")
|
||
|
t.Log("test:", pathStr)
|
||
|
t.Log("ref: ", refStr)
|
||
|
return false
|
||
|
}
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func assertPath(t *testing.T, query string, ref *Query) {
|
||
|
path, _ := parseQuery(lexQuery(query))
|
||
|
assertPathMatch(t, path, ref)
|
||
|
}
|
||
|
|
||
|
func buildPath(parts ...pathFn) *Query {
|
||
|
query := newQuery()
|
||
|
for _, v := range parts {
|
||
|
query.appendPath(v)
|
||
|
}
|
||
|
return query
|
||
|
}
|
||
|
|
||
|
func TestPathRoot(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$",
|
||
|
buildPath(
|
||
|
// empty
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathKey(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$.foo",
|
||
|
buildPath(
|
||
|
newMatchKeyFn("foo"),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathBracketKey(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[foo]",
|
||
|
buildPath(
|
||
|
newMatchKeyFn("foo"),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathBracketStringKey(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$['foo']",
|
||
|
buildPath(
|
||
|
newMatchKeyFn("foo"),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathIndex(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[123]",
|
||
|
buildPath(
|
||
|
newMatchIndexFn(123),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathSliceStart(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[123:]",
|
||
|
buildPath(
|
||
|
newMatchSliceFn(123, maxInt, 1),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathSliceStartEnd(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[123:456]",
|
||
|
buildPath(
|
||
|
newMatchSliceFn(123, 456, 1),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathSliceStartEndColon(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[123:456:]",
|
||
|
buildPath(
|
||
|
newMatchSliceFn(123, 456, 1),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathSliceStartStep(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[123::7]",
|
||
|
buildPath(
|
||
|
newMatchSliceFn(123, maxInt, 7),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathSliceEndStep(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[:456:7]",
|
||
|
buildPath(
|
||
|
newMatchSliceFn(0, 456, 7),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathSliceStep(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[::7]",
|
||
|
buildPath(
|
||
|
newMatchSliceFn(0, maxInt, 7),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathSliceAll(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[123:456:7]",
|
||
|
buildPath(
|
||
|
newMatchSliceFn(123, 456, 7),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathAny(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$.*",
|
||
|
buildPath(
|
||
|
newMatchAnyFn(),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathUnion(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[foo, bar, baz]",
|
||
|
buildPath(
|
||
|
&matchUnionFn{[]pathFn{
|
||
|
newMatchKeyFn("foo"),
|
||
|
newMatchKeyFn("bar"),
|
||
|
newMatchKeyFn("baz"),
|
||
|
}},
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathRecurse(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$..*",
|
||
|
buildPath(
|
||
|
newMatchRecursiveFn(),
|
||
|
))
|
||
|
}
|
||
|
|
||
|
func TestPathFilterExpr(t *testing.T) {
|
||
|
assertPath(t,
|
||
|
"$[?('foo'),?(bar)]",
|
||
|
buildPath(
|
||
|
&matchUnionFn{[]pathFn{
|
||
|
newMatchFilterFn("foo", toml.Position{}),
|
||
|
newMatchFilterFn("bar", toml.Position{}),
|
||
|
}},
|
||
|
))
|
||
|
}
|