package jsonpath import ( "testing") func TestEval(t *testing.T) { type Scenario struct { Name string Path string Data string ExpectedOutput string ExpectedOutputLength int ExpectedError bool } scenarios := []Scenario{ { Name: "simple", Path: "key", Data: `{"key": "value"}`, ExpectedOutput: "value", ExpectedOutputLength: 5, ExpectedError: false, }, { Name: "simple-with-invalid-data", Path: "key", Data: "invalid data", ExpectedOutput: "", ExpectedOutputLength: 0, ExpectedError: true, }, { Name: "invalid-path", Path: "key", Data: `{}`, ExpectedOutput: "", ExpectedOutputLength: 0, ExpectedError: true, }, { Name: "long-simple-walk", Path: "long.simple.walk", Data: `{"long": {"simple": {"walk": "value"}}}`, ExpectedOutput: "value", ExpectedOutputLength: 5, ExpectedError: false, }, { Name: "array-of-objects", Path: "ids[1].id", Data: `{"ids": [{"id": 1}, {"id": 2}]}`, ExpectedOutput: "2", ExpectedOutputLength: 1, ExpectedError: false, }, { Name: "array-of-values", Path: "ids[0]", Data: `{"ids": [1, 2]}`, ExpectedOutput: "1", ExpectedOutputLength: 1, ExpectedError: false, }, { Name: "array-of-values-with-no-path", Path: "", Data: `[1, 2]`, ExpectedOutput: "[1 2]", // the output is an array ExpectedOutputLength: 2, ExpectedError: false, }, { Name: "array-of-values-and-invalid-index", Path: "ids[wat]", Data: `{"ids": [1, 2]}`, ExpectedOutput: "", ExpectedOutputLength: 0, ExpectedError: true, }, { Name: "array-of-values-at-root", Path: "[1]", Data: `[1, 2]`, ExpectedOutput: "2", ExpectedOutputLength: 1, ExpectedError: false, }, { 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", ExpectedOutputLength: 1, ExpectedError: false, }, { Name: "array-of-objects-at-root-and-invalid-index", Path: "[5].id", Data: `[{"id": 1}, {"id": 2}]`, ExpectedOutput: "", ExpectedOutputLength: 0, ExpectedError: true, }, { Name: "long-walk-and-array", Path: "data.ids[0].id", Data: `{"data": {"ids": [{"id": 1}, {"id": 2}, {"id": 3}]}}`, ExpectedOutput: "1", ExpectedOutputLength: 1, ExpectedError: false, }, { Name: "nested-array", Path: "[3][2]", Data: `[[1, 2], [3, 4], [], [5, 6, 7]]`, ExpectedOutput: "7", ExpectedOutputLength: 1, ExpectedError: false, }, { Name: "object-with-nested-arrays", Path: "data[1][1]", Data: `{"data": [["a", "b", "c"], ["d", "eeeee", "f"]]}`, ExpectedOutput: "eeeee", ExpectedOutputLength: 5, ExpectedError: false, }, { Name: "object-with-arrays-of-objects", Path: "data[0].apps[1].name", Data: `{"data": [{"apps": [{"name":"app1"}, {"name":"app2"}, {"name":"app3"}]}]}`, ExpectedOutput: "app2", ExpectedOutputLength: 4, ExpectedError: false, }, { Name: "object-with-arrays-of-objects-with-missing-element", Path: "data[0].apps[1].name", Data: `{"data": [{"apps": []}]}`, ExpectedOutput: "", ExpectedOutputLength: 0, ExpectedError: true, }, { Name: "partially-invalid-path-issue122", Path: "data.name.invalid", Data: `{"data": {"name": "john"}}`, ExpectedOutput: "", ExpectedOutputLength: 0, ExpectedError: true, }, { Name: "float-as-string", Path: "balance", Data: `{"balance": "123.40000000000005"}`, ExpectedOutput: "123.40000000000005", ExpectedOutputLength: 18, ExpectedError: false, }, { Name: "float-as-number", Path: "balance", Data: `{"balance": 123.40000000000005}`, ExpectedOutput: "123.40000000000005", ExpectedOutputLength: 18, ExpectedError: false, }, { Name: "negative-index-on-keyed-array", Path: "data[-1]", Data: `{"data": [1, 2, 3]}`, ExpectedOutput: "", ExpectedOutputLength: 0, ExpectedError: true, }, { Name: "negative-index-on-root-array", Path: "[-1]", Data: `[1, 2, 3]`, ExpectedOutput: "", ExpectedOutputLength: 0, ExpectedError: true, }, { Name: "negative-index-followed-by-key", Path: "data[-1].name", Data: `{"data": [{"name": "value"}]}`, ExpectedOutput: "", ExpectedOutputLength: 0, ExpectedError: true, }, { Name: "negative-index-nested-array", Path: "data[0][-1]", Data: `{"data": [[1, 2, 3]]}`, ExpectedOutput: "", ExpectedOutputLength: 0, ExpectedError: true, }, } for _, scenario := range scenarios { t.Run(scenario.Name, func(t *testing.T) { output, outputLength, err := Eval(scenario.Path, []byte(scenario.Data)) if (err != nil) != scenario.ExpectedError { if scenario.ExpectedError { t.Errorf("Expected error, got '%v'", err) } else { t.Errorf("Expected no error, got '%v'", err) } } if outputLength != scenario.ExpectedOutputLength { t.Errorf("Expected output length to be %v, but was %v", scenario.ExpectedOutputLength, outputLength) } if output != scenario.ExpectedOutput { t.Errorf("Expected output to be %v, but was %v", scenario.ExpectedOutput, output) } }) }}
package jsonpath
import (
"testing"
)
func TestEval(t *testing.T) {
type Scenario struct {
Name string
Path string
Data string
ExpectedOutput string
ExpectedOutputLength int
ExpectedError bool
}
scenarios := []Scenario{
{
Name: "simple",
Path: "key",
Data: `{"key": "value"}`,
ExpectedOutput: "value",
ExpectedOutputLength: 5,
ExpectedError: false,
},
{
Name: "simple-with-invalid-data",
Path: "key",
Data: "invalid data",
ExpectedOutput: "",
ExpectedOutputLength: 0,
ExpectedError: true,
},
{
Name: "invalid-path",
Path: "key",
Data: `{}`,
ExpectedOutput: "",
ExpectedOutputLength: 0,
ExpectedError: true,
},
{
Name: "long-simple-walk",
Path: "long.simple.walk",
Data: `{"long": {"simple": {"walk": "value"}}}`,
ExpectedOutput: "value",
ExpectedOutputLength: 5,
ExpectedError: false,
},
{
Name: "array-of-objects",
Path: "ids[1].id",
Data: `{"ids": [{"id": 1}, {"id": 2}]}`,
ExpectedOutput: "2",
ExpectedOutputLength: 1,
ExpectedError: false,
},
{
Name: "array-of-values",
Path: "ids[0]",
Data: `{"ids": [1, 2]}`,
ExpectedOutput: "1",
ExpectedOutputLength: 1,
ExpectedError: false,
},
{
Name: "array-of-values-with-no-path",
Path: "",
Data: `[1, 2]`,
ExpectedOutput: "[1 2]", // the output is an array
ExpectedOutputLength: 2,
ExpectedError: false,
},
{
Name: "array-of-values-and-invalid-index",
Path: "ids[wat]",
Data: `{"ids": [1, 2]}`,
ExpectedOutput: "",
ExpectedOutputLength: 0,
ExpectedError: true,
},
{
Name: "array-of-values-at-root",
Path: "[1]",
Data: `[1, 2]`,
ExpectedOutput: "2",
ExpectedOutputLength: 1,
ExpectedError: false,
},
{
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",
ExpectedOutputLength: 1,
ExpectedError: false,
},
{
Name: "array-of-objects-at-root-and-invalid-index",
Path: "[5].id",
Data: `[{"id": 1}, {"id": 2}]`,
ExpectedOutput: "",
ExpectedOutputLength: 0,
ExpectedError: true,
},
{
Name: "long-walk-and-array",
Path: "data.ids[0].id",
Data: `{"data": {"ids": [{"id": 1}, {"id": 2}, {"id": 3}]}}`,
ExpectedOutput: "1",
ExpectedOutputLength: 1,
ExpectedError: false,
},
{
Name: "nested-array",
Path: "[3][2]",
Data: `[[1, 2], [3, 4], [], [5, 6, 7]]`,
ExpectedOutput: "7",
ExpectedOutputLength: 1,
ExpectedError: false,
},
{
Name: "object-with-nested-arrays",
Path: "data[1][1]",
Data: `{"data": [["a", "b", "c"], ["d", "eeeee", "f"]]}`,
ExpectedOutput: "eeeee",
ExpectedOutputLength: 5,
ExpectedError: false,
},
{
Name: "object-with-arrays-of-objects",
Path: "data[0].apps[1].name",
Data: `{"data": [{"apps": [{"name":"app1"}, {"name":"app2"}, {"name":"app3"}]}]}`,
ExpectedOutput: "app2",
ExpectedOutputLength: 4,
ExpectedError: false,
},
{
Name: "object-with-arrays-of-objects-with-missing-element",
Path: "data[0].apps[1].name",
Data: `{"data": [{"apps": []}]}`,
ExpectedOutput: "",
ExpectedOutputLength: 0,
ExpectedError: true,
},
{
Name: "partially-invalid-path-issue122",
Path: "data.name.invalid",
Data: `{"data": {"name": "john"}}`,
ExpectedOutput: "",
ExpectedOutputLength: 0,
ExpectedError: true,
},
{
Name: "float-as-string",
Path: "balance",
Data: `{"balance": "123.40000000000005"}`,
ExpectedOutput: "123.40000000000005",
ExpectedOutputLength: 18,
ExpectedError: false,
},
{
Name: "float-as-number",
Path: "balance",
Data: `{"balance": 123.40000000000005}`,
ExpectedOutput: "123.40000000000005",
ExpectedOutputLength: 18,
ExpectedError: false,
},
{
Name: "negative-index-on-keyed-array",
Path: "data[-1]",
Data: `{"data": [1, 2, 3]}`,
ExpectedOutput: "",
ExpectedOutputLength: 0,
ExpectedError: true,
},
{
Name: "negative-index-on-root-array",
Path: "[-1]",
Data: `[1, 2, 3]`,
ExpectedOutput: "",
ExpectedOutputLength: 0,
ExpectedError: true,
},
{
Name: "negative-index-followed-by-key",
Path: "data[-1].name",
Data: `{"data": [{"name": "value"}]}`,
ExpectedOutput: "",
ExpectedOutputLength: 0,
ExpectedError: true,
},
{
Name: "negative-index-nested-array",
Path: "data[0][-1]",
Data: `{"data": [[1, 2, 3]]}`,
ExpectedOutput: "",
ExpectedOutputLength: 0,
ExpectedError: true,
},
}
for _, scenario := range scenarios {
t.Run(scenario.Name, func(t *testing.T) {
output, outputLength, err := Eval(scenario.Path, []byte(scenario.Data))
if (err != nil) != scenario.ExpectedError {
if scenario.ExpectedError {
t.Errorf("Expected error, got '%v'", err)
} else {
t.Errorf("Expected no error, got '%v'", err)
}
}
if outputLength != scenario.ExpectedOutputLength {
t.Errorf("Expected output length to be %v, but was %v", scenario.ExpectedOutputLength, outputLength)
}
if output != scenario.ExpectedOutput {
t.Errorf("Expected output to be %v, but was %v", scenario.ExpectedOutput, output)
}
})
}
}