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
|
||||
}
|
||||
|
||||
if !params[2].Known {
|
||||
value = value.Slice(params[0].Value, params[1].Value)
|
||||
} else {
|
||||
value = value.Slice3(params[0].Value, params[1].Value, params[2].Value)
|
||||
value = value.Slice(params[0].Value, params[1].Value)
|
||||
|
||||
step := 1
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,12 +40,15 @@ func testJSONPath(tests []jsonpathTest, allowMissingKeys bool, t *testing.T) {
|
|||
j.AllowMissingKeys(allowMissingKeys)
|
||||
err := j.Parse(test.template)
|
||||
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)
|
||||
err = j.Execute(buf, test.input)
|
||||
if test.expectError {
|
||||
if test.expectError && err == nil {
|
||||
if err == nil {
|
||||
t.Errorf("in %s, expected execute error", test.name)
|
||||
}
|
||||
continue
|
||||
|
@ -519,3 +522,133 @@ func TestNegativeIndex(t *testing.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 (
|
||||
ErrSyntax = errors.New("invalid syntax")
|
||||
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.
|
||||
|
|
|
@ -140,7 +140,6 @@ func TestFailParser(t *testing.T) {
|
|||
{"unrecognized character", "{*}", "unrecognized character in action: U+002A '*'"},
|
||||
{"invalid number", "{+12.3.0}", "cannot parse number +12.3.0"},
|
||||
{"unterminated array", "{[1}", "unterminated array"},
|
||||
{"invalid index", "{[::-1]}", "invalid array index ::-1"},
|
||||
{"unterminated filter", "{[?(.price]}", "unterminated filter"},
|
||||
}
|
||||
for _, test := range failParserTests {
|
||||
|
|
Loading…
Reference in New Issue