mirror of https://github.com/k3s-io/k3s
Fix jsonpath slice step handling
parent
f788854e98
commit
233d7e4962
|
@ -273,12 +273,16 @@ func (j *JSONPath) evalArray(input []reflect.Value, node *ArrayNode) ([]reflect.
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !params[2].Known {
|
value = value.Slice(params[0].Value, params[1].Value)
|
||||||
value = value.Slice(params[0].Value, params[1].Value)
|
|
||||||
} else {
|
step := 1
|
||||||
value = value.Slice3(params[0].Value, params[1].Value, params[2].Value)
|
if params[2].Known {
|
||||||
|
if params[2].Value <= 0 {
|
||||||
|
return input, fmt.Errorf("step must be >= 0")
|
||||||
|
}
|
||||||
|
step = params[2].Value
|
||||||
}
|
}
|
||||||
for i := 0; i < value.Len(); i++ {
|
for i := 0; i < value.Len(); i += step {
|
||||||
result = append(result, value.Index(i))
|
result = append(result, value.Index(i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,15 @@ func testJSONPath(tests []jsonpathTest, allowMissingKeys bool, t *testing.T) {
|
||||||
j.AllowMissingKeys(allowMissingKeys)
|
j.AllowMissingKeys(allowMissingKeys)
|
||||||
err := j.Parse(test.template)
|
err := j.Parse(test.template)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("in %s, parse %s error %v", test.name, test.template, err)
|
if !test.expectError {
|
||||||
|
t.Errorf("in %s, parse %s error %v", test.name, test.template, err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err = j.Execute(buf, test.input)
|
err = j.Execute(buf, test.input)
|
||||||
if test.expectError {
|
if test.expectError {
|
||||||
if test.expectError && err == nil {
|
if err == nil {
|
||||||
t.Errorf("in %s, expected execute error", test.name)
|
t.Errorf("in %s, expected execute error", test.name)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
@ -519,3 +522,133 @@ func TestNegativeIndex(t *testing.T) {
|
||||||
t,
|
t,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStep(t *testing.T) {
|
||||||
|
var input = []byte(
|
||||||
|
`{
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "Pod",
|
||||||
|
"spec": {
|
||||||
|
"containers": [
|
||||||
|
{
|
||||||
|
"image": "radial/busyboxplus:curl",
|
||||||
|
"name": "fake0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"image": "radial/busyboxplus:curl",
|
||||||
|
"name": "fake1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"image": "radial/busyboxplus:curl",
|
||||||
|
"name": "fake2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"image": "radial/busyboxplus:curl",
|
||||||
|
"name": "fake3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"image": "radial/busyboxplus:curl",
|
||||||
|
"name": "fake4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"image": "radial/busyboxplus:curl",
|
||||||
|
"name": "fake5"
|
||||||
|
}]}}`)
|
||||||
|
|
||||||
|
var data interface{}
|
||||||
|
err := json.Unmarshal(input, &data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testJSONPath(
|
||||||
|
[]jsonpathTest{
|
||||||
|
{
|
||||||
|
"test containers[0:], it equals containers[0:6:1]",
|
||||||
|
`{.spec.containers[0:].name}`,
|
||||||
|
data,
|
||||||
|
"fake0 fake1 fake2 fake3 fake4 fake5",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[0:6:], it equals containers[0:6:1]",
|
||||||
|
`{.spec.containers[0:6:].name}`,
|
||||||
|
data,
|
||||||
|
"fake0 fake1 fake2 fake3 fake4 fake5",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[0:6:1]",
|
||||||
|
`{.spec.containers[0:6:1].name}`,
|
||||||
|
data,
|
||||||
|
"fake0 fake1 fake2 fake3 fake4 fake5",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[0:6:0], it errors",
|
||||||
|
`{.spec.containers[0:6:0].name}`,
|
||||||
|
data,
|
||||||
|
"",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[0:6:-1], it errors",
|
||||||
|
`{.spec.containers[0:6:-1].name}`,
|
||||||
|
data,
|
||||||
|
"",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[1:4:2]",
|
||||||
|
`{.spec.containers[1:4:2].name}`,
|
||||||
|
data,
|
||||||
|
"fake1 fake3",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[1:4:3]",
|
||||||
|
`{.spec.containers[1:4:3].name}`,
|
||||||
|
data,
|
||||||
|
"fake1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[1:4:4]",
|
||||||
|
`{.spec.containers[1:4:4].name}`,
|
||||||
|
data,
|
||||||
|
"fake1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[0:6:2]",
|
||||||
|
`{.spec.containers[0:6:2].name}`,
|
||||||
|
data,
|
||||||
|
"fake0 fake2 fake4",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[0:6:3]",
|
||||||
|
`{.spec.containers[0:6:3].name}`,
|
||||||
|
data,
|
||||||
|
"fake0 fake3",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[0:6:5]",
|
||||||
|
`{.spec.containers[0:6:5].name}`,
|
||||||
|
data,
|
||||||
|
"fake0 fake5",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test containers[0:6:6]",
|
||||||
|
`{.spec.containers[0:6:6].name}`,
|
||||||
|
data,
|
||||||
|
"fake0",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
t,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ type Parser struct {
|
||||||
var (
|
var (
|
||||||
ErrSyntax = errors.New("invalid syntax")
|
ErrSyntax = errors.New("invalid syntax")
|
||||||
dictKeyRex = regexp.MustCompile(`^'([^']*)'$`)
|
dictKeyRex = regexp.MustCompile(`^'([^']*)'$`)
|
||||||
sliceOperatorRex = regexp.MustCompile(`^(-?[\d]*)(:-?[\d]*)?(:[\d]*)?$`)
|
sliceOperatorRex = regexp.MustCompile(`^(-?[\d]*)(:-?[\d]*)?(:-?[\d]*)?$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parse parsed the given text and return a node Parser.
|
// Parse parsed the given text and return a node Parser.
|
||||||
|
|
|
@ -140,7 +140,6 @@ func TestFailParser(t *testing.T) {
|
||||||
{"unrecognized character", "{*}", "unrecognized character in action: U+002A '*'"},
|
{"unrecognized character", "{*}", "unrecognized character in action: U+002A '*'"},
|
||||||
{"invalid number", "{+12.3.0}", "cannot parse number +12.3.0"},
|
{"invalid number", "{+12.3.0}", "cannot parse number +12.3.0"},
|
||||||
{"unterminated array", "{[1}", "unterminated array"},
|
{"unterminated array", "{[1}", "unterminated array"},
|
||||||
{"invalid index", "{[::-1]}", "invalid array index ::-1"},
|
|
||||||
{"unterminated filter", "{[?(.price]}", "unterminated filter"},
|
{"unterminated filter", "{[?(.price]}", "unterminated filter"},
|
||||||
}
|
}
|
||||||
for _, test := range failParserTests {
|
for _, test := range failParserTests {
|
||||||
|
|
Loading…
Reference in New Issue