blob: ec05f07535a8b397abd341a9fb4da1edb516a076 [file]
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),
})
}