| 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), |
| }) |
| } |