Merge pull request #17152 from daizuozhuo/jsonpath

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2015-11-24 04:45:38 -08:00
commit 5502aefa01
5 changed files with 23 additions and 19 deletions

View File

@ -85,7 +85,6 @@ Given the input:
Function | Description | Example | Result Function | Description | Example | Result
---------|--------------------|--------------------|------------------ ---------|--------------------|--------------------|------------------
text | the plain text | kind is {.kind} | kind is List text | the plain text | kind is {.kind} | kind is List
"" | quote | {"{"} | {
@ | the current object | {@} | the same as input @ | the current object | {@} | the same as input
. or [] | child operator | {.kind} or {['kind']}| List . or [] | child operator | {.kind} or {['kind']}| List
.. | recursive descent | {..name} | 127.0.0.1 127.0.0.2 myself e2e .. | recursive descent | {..name} | 127.0.0.1 127.0.0.2 myself e2e
@ -94,7 +93,7 @@ text | the plain text | kind is {.kind} | kind is List
[,] | union operator | {.items[*]['metadata.name', 'status.capacity']} | 127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8] [,] | union operator | {.items[*]['metadata.name', 'status.capacity']} | 127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8]
?() | filter | {.users[?(@.name=="e2e")].user.password} | secret ?() | filter | {.users[?(@.name=="e2e")].user.password} | secret
range, end | iterate list | {range .items[*]}[{.metadata.name}, {.status.capacity}] {end} | [127.0.0.1, map[cpu:4]] [127.0.0.2, map[cpu:8]] range, end | iterate list | {range .items[*]}[{.metadata.name}, {.status.capacity}] {end} | [127.0.0.1, map[cpu:4]] [127.0.0.2, map[cpu:8]]
"" | quote interpreted string | {range .items[*]}{.metadata.name}{"\t"}{end} | 127.0.0.1 127.0.0.2

View File

@ -130,7 +130,7 @@ func (j *JSONPath) walk(value []reflect.Value, node Node) ([]reflect.Value, erro
case *ListNode: case *ListNode:
return j.evalList(value, node) return j.evalList(value, node)
case *TextNode: case *TextNode:
return []reflect.Value{reflect.ValueOf(string(node.Text))}, nil return []reflect.Value{reflect.ValueOf(node.Text)}, nil
case *FieldNode: case *FieldNode:
return j.evalField(value, node) return j.evalField(value, node)
case *ArrayNode: case *ArrayNode:

View File

@ -52,7 +52,7 @@ func testJSONPath(tests []jsonpathTest, t *testing.T) {
} }
} }
// testJSONPathSortOutput test testcases related to map, the results may print in random order // testJSONPathSortOutput test cases related to map, the results may print in random order
func testJSONPathSortOutput(tests []jsonpathTest, t *testing.T) { func testJSONPathSortOutput(tests []jsonpathTest, t *testing.T) {
for _, test := range tests { for _, test := range tests {
j := New(test.name) j := New(test.name)
@ -66,7 +66,7 @@ func testJSONPathSortOutput(tests []jsonpathTest, t *testing.T) {
t.Errorf("in %s, execute error %v", test.name, err) t.Errorf("in %s, execute error %v", test.name, err)
} }
out := buf.String() out := buf.String()
//since map is itereated in random order, we need to sort the results. //since map is visited in random order, we need to sort the results.
sortedOut := strings.Fields(out) sortedOut := strings.Fields(out)
sort.Strings(sortedOut) sort.Strings(sortedOut)
sortedExpect := strings.Fields(test.expect) sortedExpect := strings.Fields(test.expect)
@ -233,16 +233,17 @@ func TestKubernetes(t *testing.T) {
} }
nodesTests := []jsonpathTest{ nodesTests := []jsonpathTest{
{"range item", "{range .items[*]}{.metadata.name}, {end}{.kind}", nodesData, `127.0.0.1, 127.0.0.2, List`}, {"range item", `{range .items[*]}{.metadata.name}, {end}{.kind}`, nodesData, "127.0.0.1, 127.0.0.2, List"},
{"range addresss", "{.items[*].status.addresses[*].address}", nodesData, {"range item with quote", `{range .items[*]}{.metadata.name}{"\t"}{end}`, nodesData, "127.0.0.1\t127.0.0.2\t"},
`127.0.0.1 127.0.0.2 127.0.0.3`}, {"range addresss", `{.items[*].status.addresses[*].address}`, nodesData,
{"double range", "{range .items[*]}{range .status.addresses[*]}{.address}, {end}{end}", nodesData, "127.0.0.1 127.0.0.2 127.0.0.3"},
`127.0.0.1, 127.0.0.2, 127.0.0.3, `}, {"double range", `{range .items[*]}{range .status.addresses[*]}{.address}, {end}{end}`, nodesData,
{"item name", "{.items[*].metadata.name}", nodesData, `127.0.0.1 127.0.0.2`}, "127.0.0.1, 127.0.0.2, 127.0.0.3, "},
{"union nodes capacity", "{.items[*]['metadata.name', 'status.capacity']}", nodesData, {"item name", `{.items[*].metadata.name}`, nodesData, "127.0.0.1 127.0.0.2"},
`127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8]`}, {"union nodes capacity", `{.items[*]['metadata.name', 'status.capacity']}`, nodesData,
{"range nodes capacity", "{range .items[*]}[{.metadata.name}, {.status.capacity}] {end}", nodesData, "127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8]"},
`[127.0.0.1, map[cpu:4]] [127.0.0.2, map[cpu:8]] `}, {"range nodes capacity", `{range .items[*]}[{.metadata.name}, {.status.capacity}] {end}`, nodesData,
"[127.0.0.1, map[cpu:4]] [127.0.0.2, map[cpu:8]] "},
{"user password", `{.users[?(@.name=="e2e")].user.password}`, &nodesData, "secret"}, {"user password", `{.users[?(@.name=="e2e")].user.password}`, &nodesData, "secret"},
} }
testJSONPath(nodesTests, t) testJSONPath(nodesTests, t)

View File

@ -84,11 +84,11 @@ func (l *ListNode) String() string {
// TextNode holds plain text. // TextNode holds plain text.
type TextNode struct { type TextNode struct {
NodeType NodeType
Text []byte // The text; may span newlines. Text string // The text; may span newlines.
} }
func newText(text string) *TextNode { func newText(text string) *TextNode {
return &TextNode{NodeType: NodeText, Text: []byte(text)} return &TextNode{NodeType: NodeText, Text: text}
} }
func (t *TextNode) String() string { func (t *TextNode) String() string {

View File

@ -359,7 +359,7 @@ Loop:
return p.parseInsideAction(cur) return p.parseInsideAction(cur)
} }
// parseQuote scans array index selection // parseQuote unquotes string inside double quote
func (p *Parser) parseQuote(cur *ListNode) error { func (p *Parser) parseQuote(cur *ListNode) error {
Loop: Loop:
for { for {
@ -371,7 +371,11 @@ Loop:
} }
} }
value := p.consumeText() value := p.consumeText()
cur.append(newText(value[1 : len(value)-1])) s, err := strconv.Unquote(value)
if err != nil {
return fmt.Errorf("unquote string %s error %v", value, err)
}
cur.append(newText(s))
return p.parseInsideAction(cur) return p.parseInsideAction(cur)
} }