| package jpath |
| |
| import ( |
| "fmt" |
| . "github.com/pelletier/go-toml" |
| "testing" |
| "sort" |
| "strings" |
| ) |
| |
| func valueString(root interface{}) string { |
| result := "" //fmt.Sprintf("%T:", root) |
| switch node := root.(type) { |
| case []interface{}: |
| items := []string{} |
| for _, v := range node { |
| items = append(items, valueString(v)) |
| } |
| sort.Strings(items) |
| result = "[" + strings.Join(items, ", ") + "]" |
| case *TomlTree: |
| // workaround for unreliable map key ordering |
| items := []string{} |
| for _, k := range node.Keys() { |
| v := node.GetPath([]string{k}) |
| items = append(items, k + ":" + valueString(v)) |
| } |
| sort.Strings(items) |
| result = "{" + strings.Join(items, ", ") + "}" |
| case map[string]interface{}: |
| // workaround for unreliable map key ordering |
| items := []string{} |
| for k, v := range node { |
| items = append(items, k + ":" + valueString(v)) |
| } |
| sort.Strings(items) |
| result = "{" + strings.Join(items, ", ") + "}" |
| case int64: |
| result += fmt.Sprintf("%d", node) |
| case string: |
| result += "'" + node + "'" |
| } |
| return result |
| } |
| |
| func assertValue(t *testing.T, result, ref interface{}) { |
| pathStr := valueString(result) |
| refStr := valueString(ref) |
| if pathStr != refStr { |
| t.Errorf("values do not match") |
| t.Log("test:", pathStr) |
| t.Log("ref: ", refStr) |
| } |
| } |
| |
| 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.Values(), 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), |
| }) |
| } |