265 lines
5.0 KiB
Go
265 lines
5.0 KiB
Go
package jpath
|
|
|
|
import (
|
|
"fmt"
|
|
. "github.com/pelletier/go-toml"
|
|
"testing"
|
|
)
|
|
|
|
func assertQuery(t *testing.T, toml, query string, ref []interface{}) {
|
|
tree, err := Load(toml)
|
|
if err != nil {
|
|
t.Errorf("Non-nil toml parse error: %v", err)
|
|
return
|
|
}
|
|
results := Compile(query).Execute(tree)
|
|
assertValue(t, results, ref, "(("+query+")) -> ")
|
|
}
|
|
|
|
func assertValue(t *testing.T, result, ref interface{}, location string) {
|
|
switch node := ref.(type) {
|
|
case []interface{}:
|
|
if resultNode, ok := result.([]interface{}); !ok {
|
|
t.Errorf("{%s} result value not of type %T: %T",
|
|
location, node, resultNode)
|
|
} else {
|
|
if len(node) != len(resultNode) {
|
|
t.Errorf("{%s} lengths do not match: %v vs %v",
|
|
location, node, resultNode)
|
|
} else {
|
|
for i, v := range node {
|
|
assertValue(t, resultNode[i], v, fmt.Sprintf("%s[%d]", location, i))
|
|
}
|
|
}
|
|
}
|
|
case map[string]interface{}:
|
|
if resultNode, ok := result.(*TomlTree); !ok {
|
|
t.Errorf("{%s} result value not of type %T: %T",
|
|
location, node, resultNode)
|
|
} else {
|
|
for k, v := range node {
|
|
assertValue(t, resultNode.GetPath([]string{k}), v, location+"."+k)
|
|
}
|
|
}
|
|
case int64:
|
|
if resultNode, ok := result.(int64); !ok {
|
|
t.Errorf("{%s} result value not of type %T: %T",
|
|
location, node, resultNode)
|
|
} else {
|
|
if node != resultNode {
|
|
t.Errorf("{%s} result value does not match", location)
|
|
}
|
|
}
|
|
case string:
|
|
if resultNode, ok := result.(string); !ok {
|
|
t.Errorf("{%s} result value not of type %T: %T",
|
|
location, node, resultNode)
|
|
} else {
|
|
if node != resultNode {
|
|
t.Errorf("{%s} result value does not match", location)
|
|
}
|
|
}
|
|
default:
|
|
if fmt.Sprintf("%v", node) != fmt.Sprintf("%v", ref) {
|
|
t.Errorf("{%s} result value does not match: %v != %v",
|
|
location, node, ref)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestQueryRoot(t *testing.T) {
|
|
assertQuery(t,
|
|
"a = 42",
|
|
"$",
|
|
[]interface{}{
|
|
map[string]interface{}{
|
|
"a": int64(42),
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestQueryKey(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo]\na = 42",
|
|
"$.foo.a",
|
|
[]interface{}{
|
|
int64(42),
|
|
})
|
|
}
|
|
|
|
func TestQueryKeyString(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo]\na = 42",
|
|
"$.foo['a']",
|
|
[]interface{}{
|
|
int64(42),
|
|
})
|
|
}
|
|
|
|
func TestQueryIndex(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo]\na = [1,2,3,4,5,6,7,8,9,0]",
|
|
"$.foo.a[0]",
|
|
[]interface{}{
|
|
int64(1),
|
|
})
|
|
}
|
|
|
|
func TestQuerySliceRange(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo]\na = [1,2,3,4,5,6,7,8,9,0]",
|
|
"$.foo.a[0:5]",
|
|
[]interface{}{
|
|
int64(1),
|
|
int64(2),
|
|
int64(3),
|
|
int64(4),
|
|
int64(5),
|
|
})
|
|
}
|
|
|
|
func TestQuerySliceStep(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo]\na = [1,2,3,4,5,6,7,8,9,0]",
|
|
"$.foo.a[0:5:2]",
|
|
[]interface{}{
|
|
int64(1),
|
|
int64(3),
|
|
int64(5),
|
|
})
|
|
}
|
|
|
|
func TestQueryAny(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo.bar]\na=1\nb=2\n[foo.baz]\na=3\nb=4",
|
|
"$.foo.*",
|
|
[]interface{}{
|
|
map[string]interface{}{
|
|
"a": int64(1),
|
|
"b": int64(2),
|
|
},
|
|
map[string]interface{}{
|
|
"a": int64(3),
|
|
"b": int64(4),
|
|
},
|
|
})
|
|
}
|
|
func TestQueryUnionSimple(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6",
|
|
"$.*[bar,foo]",
|
|
[]interface{}{
|
|
map[string]interface{}{
|
|
"a": int64(1),
|
|
"b": int64(2),
|
|
},
|
|
map[string]interface{}{
|
|
"a": int64(3),
|
|
"b": int64(4),
|
|
},
|
|
map[string]interface{}{
|
|
"a": int64(5),
|
|
"b": int64(6),
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestQueryRecursionAll(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6",
|
|
"$..*",
|
|
[]interface{}{
|
|
map[string]interface{}{
|
|
"bar": map[string]interface{}{
|
|
"a": int64(1),
|
|
"b": int64(2),
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"a": int64(1),
|
|
"b": int64(2),
|
|
},
|
|
int64(1),
|
|
int64(2),
|
|
map[string]interface{}{
|
|
"foo": map[string]interface{}{
|
|
"a": int64(3),
|
|
"b": int64(4),
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"a": int64(3),
|
|
"b": int64(4),
|
|
},
|
|
int64(3),
|
|
int64(4),
|
|
map[string]interface{}{
|
|
"foo": map[string]interface{}{
|
|
"a": int64(5),
|
|
"b": int64(6),
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"a": int64(5),
|
|
"b": int64(6),
|
|
},
|
|
int64(5),
|
|
int64(6),
|
|
})
|
|
}
|
|
|
|
func TestQueryRecursionUnionSimple(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6",
|
|
"$..['foo','bar']",
|
|
[]interface{}{
|
|
map[string]interface{}{
|
|
"a": int64(1),
|
|
"b": int64(2),
|
|
},
|
|
map[string]interface{}{
|
|
"a": int64(3),
|
|
"b": int64(4),
|
|
},
|
|
map[string]interface{}{
|
|
"a": int64(5),
|
|
"b": int64(6),
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestQueryScriptFnLast(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo]\na = [0,1,2,3,4,5,6,7,8,9]",
|
|
"$.foo.a[(last)]",
|
|
[]interface{}{
|
|
int64(9),
|
|
})
|
|
}
|
|
|
|
func TestQueryFilterFnOdd(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo]\na = [0,1,2,3,4,5,6,7,8,9]",
|
|
"$.foo.a[?(odd)]",
|
|
[]interface{}{
|
|
int64(1),
|
|
int64(3),
|
|
int64(5),
|
|
int64(7),
|
|
int64(9),
|
|
})
|
|
}
|
|
|
|
func TestQueryFilterFnEven(t *testing.T) {
|
|
assertQuery(t,
|
|
"[foo]\na = [0,1,2,3,4,5,6,7,8,9]",
|
|
"$.foo.a[?(even)]",
|
|
[]interface{}{
|
|
int64(0),
|
|
int64(2),
|
|
int64(4),
|
|
int64(6),
|
|
int64(8),
|
|
})
|
|
}
|