fix(jsonpath): Properly handle len of object in array, len of int and len of bool (#372)
This commit is contained in:
@ -20,6 +20,7 @@ func Eval(path string, b []byte) (string, int, error) {
|
||||
return walk(path, object)
|
||||
}
|
||||
|
||||
// walk traverses the object and returns the value as a string as well as its length
|
||||
func walk(path string, object interface{}) (string, int, error) {
|
||||
var keys []string
|
||||
startOfCurrentKey, bracketDepth := 0, 0
|
||||
@ -41,7 +42,15 @@ func walk(path string, object interface{}) (string, int, error) {
|
||||
currentKey := keys[0]
|
||||
switch value := extractValue(currentKey, object).(type) {
|
||||
case map[string]interface{}:
|
||||
return walk(strings.Replace(path, fmt.Sprintf("%s.", currentKey), "", 1), value)
|
||||
newPath := strings.Replace(path, fmt.Sprintf("%s.", currentKey), "", 1)
|
||||
if path == newPath {
|
||||
// If the path hasn't changed, it means we're at the end of the path
|
||||
// So we'll treat it as a string by re-marshaling it to JSON since it's a map.
|
||||
// Note that the output JSON will be minified.
|
||||
b, err := json.Marshal(value)
|
||||
return string(b), len(b), err
|
||||
}
|
||||
return walk(newPath, value)
|
||||
case string:
|
||||
if len(keys) > 1 {
|
||||
return "", 0, fmt.Errorf("couldn't walk through '%s', because '%s' was a string instead of an object", keys[1], currentKey)
|
||||
@ -50,7 +59,8 @@ func walk(path string, object interface{}) (string, int, error) {
|
||||
case []interface{}:
|
||||
return fmt.Sprintf("%v", value), len(value), nil
|
||||
case interface{}:
|
||||
return fmt.Sprintf("%v", value), 1, nil
|
||||
newValue := fmt.Sprintf("%v", value)
|
||||
return newValue, len(newValue), nil
|
||||
default:
|
||||
return "", 0, fmt.Errorf("couldn't walk through '%s' because type was '%T', but expected 'map[string]interface{}'", currentKey, value)
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ func TestEval(t *testing.T) {
|
||||
ExpectedError: false,
|
||||
},
|
||||
{
|
||||
Name: "array-of-maps",
|
||||
Name: "array-of-objects",
|
||||
Path: "ids[1].id",
|
||||
Data: `{"ids": [{"id": 1}, {"id": 2}]}`,
|
||||
ExpectedOutput: "2",
|
||||
@ -87,7 +87,15 @@ func TestEval(t *testing.T) {
|
||||
ExpectedError: false,
|
||||
},
|
||||
{
|
||||
Name: "array-of-maps-at-root",
|
||||
Name: "array-of-objects-at-root",
|
||||
Path: "[0]",
|
||||
Data: `[{"id": 1}, {"id": 2}]`,
|
||||
ExpectedOutput: `{"id":1}`,
|
||||
ExpectedOutputLength: 8,
|
||||
ExpectedError: false,
|
||||
},
|
||||
{
|
||||
Name: "array-of-objects-with-int-at-root",
|
||||
Path: "[0].id",
|
||||
Data: `[{"id": 1}, {"id": 2}]`,
|
||||
ExpectedOutput: "1",
|
||||
@ -95,7 +103,7 @@ func TestEval(t *testing.T) {
|
||||
ExpectedError: false,
|
||||
},
|
||||
{
|
||||
Name: "array-of-maps-at-root-and-invalid-index",
|
||||
Name: "array-of-objects-at-root-and-invalid-index",
|
||||
Path: "[5].id",
|
||||
Data: `[{"id": 1}, {"id": 2}]`,
|
||||
ExpectedOutput: "",
|
||||
@ -119,7 +127,7 @@ func TestEval(t *testing.T) {
|
||||
ExpectedError: false,
|
||||
},
|
||||
{
|
||||
Name: "map-of-nested-arrays",
|
||||
Name: "object-with-nested-arrays",
|
||||
Path: "data[1][1]",
|
||||
Data: `{"data": [["a", "b", "c"], ["d", "eeeee", "f"]]}`,
|
||||
ExpectedOutput: "eeeee",
|
||||
@ -127,7 +135,7 @@ func TestEval(t *testing.T) {
|
||||
ExpectedError: false,
|
||||
},
|
||||
{
|
||||
Name: "map-of-arrays-of-maps",
|
||||
Name: "object-with-arrays-of-objects",
|
||||
Path: "data[0].apps[1].name",
|
||||
Data: `{"data": [{"apps": [{"name":"app1"}, {"name":"app2"}, {"name":"app3"}]}]}`,
|
||||
ExpectedOutput: "app2",
|
||||
@ -135,7 +143,7 @@ func TestEval(t *testing.T) {
|
||||
ExpectedError: false,
|
||||
},
|
||||
{
|
||||
Name: "map-of-arrays-of-maps-with-missing-element",
|
||||
Name: "object-with-arrays-of-objects-with-missing-element",
|
||||
Path: "data[0].apps[1].name",
|
||||
Data: `{"data": [{"apps": []}]}`,
|
||||
ExpectedOutput: "",
|
||||
|
Reference in New Issue
Block a user