mirror of
https://github.com/joohoi/acme-dns.git
synced 2025-01-22 02:07:23 +07:00
268 lines
7.7 KiB
Go
268 lines
7.7 KiB
Go
package jsonpath
|
|
|
|
import (
|
|
"encoding/json"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
var goessner = []byte(`{
|
|
"store": {
|
|
"book": [
|
|
{
|
|
"category": "reference",
|
|
"author": "Nigel Rees",
|
|
"title": "Sayings of the Century",
|
|
"price": 8.95
|
|
},
|
|
{
|
|
"category": "fiction",
|
|
"author": "Evelyn Waugh",
|
|
"title": "Sword of Honour",
|
|
"price": 12.99
|
|
},
|
|
{
|
|
"category": "fiction",
|
|
"author": "Herman Melville",
|
|
"title": "Moby Dick",
|
|
"isbn": "0-553-21311-3",
|
|
"price": 8.99
|
|
},
|
|
{
|
|
"category": "fiction",
|
|
"author": "J. R. R. Tolkien",
|
|
"title": "The Lord of the Rings",
|
|
"isbn": "0-395-19395-8",
|
|
"price": 22.99
|
|
}
|
|
],
|
|
"bicycle": {
|
|
"color": "red",
|
|
"price": 19.95
|
|
}
|
|
},
|
|
"expensive": 10
|
|
}`)
|
|
|
|
var sample = map[string]interface{}{
|
|
"A": []interface{}{
|
|
"string",
|
|
23.3,
|
|
3,
|
|
true,
|
|
false,
|
|
nil,
|
|
},
|
|
"B": "value",
|
|
"C": 3.14,
|
|
"D": map[string]interface{}{
|
|
"C": 3.1415,
|
|
"V": []interface{}{
|
|
"string2a",
|
|
"string2b",
|
|
map[string]interface{}{
|
|
"C": 3.141592,
|
|
},
|
|
},
|
|
},
|
|
"E": map[string]interface{}{
|
|
"A": []interface{}{"string3"},
|
|
"D": map[string]interface{}{
|
|
"V": map[string]interface{}{
|
|
"C": 3.14159265,
|
|
},
|
|
},
|
|
},
|
|
"F": map[string]interface{}{
|
|
"V": []interface{}{
|
|
"string4a",
|
|
"string4b",
|
|
map[string]interface{}{
|
|
"CC": 3.1415926535,
|
|
},
|
|
map[string]interface{}{
|
|
"CC": "hello",
|
|
},
|
|
[]interface{}{
|
|
"string5a",
|
|
"string5b",
|
|
},
|
|
[]interface{}{
|
|
"string6a",
|
|
"string6b",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
func TestGossner(t *testing.T) {
|
|
var data interface{}
|
|
json.Unmarshal(goessner, &data)
|
|
|
|
tests := map[string]interface{}{
|
|
"$.store.book[*].author": []interface{}{"Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"},
|
|
"$..author": []interface{}{"Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"},
|
|
}
|
|
assert(t, data, tests)
|
|
}
|
|
|
|
func TestParsing(t *testing.T) {
|
|
t.Run("pick", func(t *testing.T) {
|
|
assert(t, sample, map[string]interface{}{
|
|
"$": sample,
|
|
"$.A[0]": "string",
|
|
`$["A"][0]`: "string",
|
|
"$.A": []interface{}{"string", 23.3, 3, true, false, nil},
|
|
"$.A[*]": []interface{}{"string", 23.3, 3, true, false, nil},
|
|
"$.A.*": []interface{}{"string", 23.3, 3, true, false, nil},
|
|
"$.A.*.a": []interface{}{},
|
|
})
|
|
})
|
|
|
|
t.Run("slice", func(t *testing.T) {
|
|
assert(t, sample, map[string]interface{}{
|
|
"$.A[1,4,2]": []interface{}{23.3, false, 3},
|
|
`$["B","C"]`: []interface{}{"value", 3.14},
|
|
`$["C","B"]`: []interface{}{3.14, "value"},
|
|
"$.A[1:4]": []interface{}{23.3, 3, true},
|
|
"$.A[::2]": []interface{}{"string", 3, false},
|
|
"$.A[-2:]": []interface{}{false, nil},
|
|
"$.A[:-1]": []interface{}{"string", 23.3, 3, true, false},
|
|
"$.A[::-1]": []interface{}{nil, false, true, 3, 23.3, "string"},
|
|
"$.F.V[4:5][0,1]": []interface{}{"string5a", "string5b"},
|
|
"$.F.V[4:6][1]": []interface{}{"string5b", "string6b"},
|
|
"$.F.V[4:6][0,1]": []interface{}{"string5a", "string5b", "string6a", "string6b"},
|
|
"$.F.V[4,5][0:2]": []interface{}{"string5a", "string5b", "string6a", "string6b"},
|
|
"$.F.V[4:6]": []interface{}{
|
|
[]interface{}{
|
|
"string5a",
|
|
"string5b",
|
|
},
|
|
[]interface{}{
|
|
"string6a",
|
|
"string6b",
|
|
},
|
|
},
|
|
})
|
|
})
|
|
|
|
t.Run("quote", func(t *testing.T) {
|
|
assert(t, sample, map[string]interface{}{
|
|
`$[A][0]`: "string",
|
|
`$["A"][0]`: "string",
|
|
`$[B,C]`: []interface{}{"value", 3.14},
|
|
`$["B","C"]`: []interface{}{"value", 3.14},
|
|
})
|
|
})
|
|
|
|
t.Run("search", func(t *testing.T) {
|
|
assert(t, sample, map[string]interface{}{
|
|
"$..C": []interface{}{3.14, 3.1415, 3.141592, 3.14159265},
|
|
`$..["C"]`: []interface{}{3.14, 3.1415, 3.141592, 3.14159265},
|
|
"$.D.V..C": []interface{}{3.141592},
|
|
"$.D.V.*.C": []interface{}{3.141592},
|
|
"$.D.V..*.C": []interface{}{3.141592},
|
|
"$.D.*..C": []interface{}{3.141592},
|
|
"$.*.V..C": []interface{}{3.141592},
|
|
"$.*.D.V.C": []interface{}{3.14159265},
|
|
"$.*.D..C": []interface{}{3.14159265},
|
|
"$.*.D.V..*": []interface{}{3.14159265},
|
|
"$..D..V..C": []interface{}{3.141592, 3.14159265},
|
|
"$.*.*.*.C": []interface{}{3.141592, 3.14159265},
|
|
"$..V..C": []interface{}{3.141592, 3.14159265},
|
|
"$.D.V..*": []interface{}{
|
|
"string2a",
|
|
"string2b",
|
|
map[string]interface{}{
|
|
"C": 3.141592,
|
|
},
|
|
3.141592,
|
|
},
|
|
"$..A": []interface{}{
|
|
[]interface{}{"string", 23.3, 3, true, false, nil},
|
|
[]interface{}{"string3"},
|
|
},
|
|
"$..A..*": []interface{}{"string", 23.3, 3, true, false, nil, "string3"},
|
|
"$.A..*": []interface{}{"string", 23.3, 3, true, false, nil},
|
|
"$.A.*": []interface{}{"string", 23.3, 3, true, false, nil},
|
|
"$..A[0,1]": []interface{}{"string", 23.3},
|
|
"$..A[0]": []interface{}{"string", "string3"},
|
|
"$.*.V[0]": []interface{}{"string2a", "string4a"},
|
|
"$.*.V[1]": []interface{}{"string2b", "string4b"},
|
|
"$.*.V[0,1]": []interface{}{"string2a", "string2b", "string4a", "string4b"},
|
|
"$.*.V[0:2]": []interface{}{"string2a", "string2b", "string4a", "string4b"},
|
|
"$.*.V[2].C": []interface{}{3.141592},
|
|
"$..V[2].C": []interface{}{3.141592},
|
|
"$..V[*].C": []interface{}{3.141592},
|
|
"$.*.V[2].*": []interface{}{3.141592, 3.1415926535},
|
|
"$.*.V[2:3].*": []interface{}{3.141592, 3.1415926535},
|
|
"$.*.V[2:4].*": []interface{}{3.141592, 3.1415926535, "hello"},
|
|
"$..V[2,3].CC": []interface{}{3.1415926535, "hello"},
|
|
"$..V[2:4].CC": []interface{}{3.1415926535, "hello"},
|
|
"$..V[*].*": []interface{}{
|
|
3.141592,
|
|
3.1415926535,
|
|
"hello",
|
|
"string5a",
|
|
"string5b",
|
|
"string6a",
|
|
"string6b",
|
|
},
|
|
"$..[0]": []interface{}{
|
|
"string",
|
|
"string2a",
|
|
"string3",
|
|
"string4a",
|
|
"string5a",
|
|
"string6a",
|
|
},
|
|
"$..ZZ": []interface{}{},
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestErrors(t *testing.T) {
|
|
tests := map[string]string{
|
|
".A": "path must start with a '$'",
|
|
"$.": "expected JSON child identifier after '.'",
|
|
"$.1": "unexpected token .1",
|
|
"$.A[]": "expected at least one key, index or expression",
|
|
`$["]`: "bad string invalid syntax",
|
|
`$[A][0`: "unexpected end of path",
|
|
"$.ZZZ": "child 'ZZZ' not found in JSON object",
|
|
"$.A*]": "unexpected token *",
|
|
"$.*V": "unexpected token V",
|
|
"$[B,C": "unexpected end of path",
|
|
"$.A[1,4.2]": "unexpected token '.'",
|
|
"$[C:B]": "expected JSON array",
|
|
"$.A[1:4:0:0]": "bad range syntax [start:end:step]",
|
|
"$.A[:,]": "unexpected token ','",
|
|
"$..": "cannot end with a scan '..'",
|
|
"$..1": "unexpected token '1' after deep search '..'",
|
|
}
|
|
assertError(t, sample, tests)
|
|
}
|
|
|
|
func assert(t *testing.T, json interface{}, tests map[string]interface{}) {
|
|
for path, expected := range tests {
|
|
actual, err := Read(json, path)
|
|
if err != nil {
|
|
t.Error("failed:", path, err)
|
|
} else if !reflect.DeepEqual(actual, expected) {
|
|
t.Errorf("failed: mismatch for %s\nexpected: %+v\nactual: %+v", path, expected, actual)
|
|
}
|
|
}
|
|
}
|
|
|
|
func assertError(t *testing.T, json interface{}, tests map[string]string) {
|
|
for path, expectedError := range tests {
|
|
_, err := Read(json, path)
|
|
if err == nil {
|
|
t.Error("path", path, "should fail with", expectedError)
|
|
} else if !strings.Contains(err.Error(), expectedError) {
|
|
t.Error("path", path, "shoud fail with ", expectedError, "but failed with:", err)
|
|
}
|
|
}
|
|
}
|