2020-11-03 23:48:43 +00:00
|
|
|
package yqlib
|
2020-09-17 11:58:01 +00:00
|
|
|
|
|
|
|
import (
|
2020-10-17 11:10:47 +00:00
|
|
|
"fmt"
|
2020-09-17 11:58:01 +00:00
|
|
|
"testing"
|
|
|
|
|
2020-10-27 05:45:16 +00:00
|
|
|
"github.com/mikefarah/yq/v4/test"
|
2020-09-17 11:58:01 +00:00
|
|
|
)
|
|
|
|
|
2020-10-17 11:10:47 +00:00
|
|
|
var pathTests = []struct {
|
|
|
|
path string
|
|
|
|
expectedTokens []interface{}
|
|
|
|
expectedPostFix []interface{}
|
2020-12-01 07:08:41 +00:00
|
|
|
}{
|
2020-11-22 02:50:32 +00:00
|
|
|
{
|
|
|
|
`[]`,
|
|
|
|
append(make([]interface{}, 0), "[", "]"),
|
2020-12-01 07:08:41 +00:00
|
|
|
append(make([]interface{}, 0), "EMPTY", "COLLECT", "SHORT_PIPE"),
|
2020-11-22 02:50:32 +00:00
|
|
|
},
|
2020-12-26 10:37:08 +00:00
|
|
|
{
|
|
|
|
`.[]`,
|
|
|
|
append(make([]interface{}, 0), "TRAVERSE_ARRAY", "[", "]"),
|
|
|
|
append(make([]interface{}, 0), "EMPTY", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY"),
|
|
|
|
},
|
2020-12-09 01:15:14 +00:00
|
|
|
{
|
|
|
|
`.a[]`,
|
2020-12-26 10:37:08 +00:00
|
|
|
append(make([]interface{}, 0), "a", "SHORT_PIPE", "TRAVERSE_ARRAY", "[", "]"),
|
|
|
|
append(make([]interface{}, 0), "a", "EMPTY", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY", "SHORT_PIPE"),
|
2020-12-09 01:15:14 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
`.a.[]`,
|
2020-12-26 10:37:08 +00:00
|
|
|
append(make([]interface{}, 0), "a", "SHORT_PIPE", "TRAVERSE_ARRAY", "[", "]"),
|
|
|
|
append(make([]interface{}, 0), "a", "EMPTY", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY", "SHORT_PIPE"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
`.a[0]`,
|
|
|
|
append(make([]interface{}, 0), "a", "SHORT_PIPE", "TRAVERSE_ARRAY", "[", "0 (int64)", "]"),
|
|
|
|
append(make([]interface{}, 0), "a", "0 (int64)", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY", "SHORT_PIPE"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
`.a.[0]`,
|
|
|
|
append(make([]interface{}, 0), "a", "SHORT_PIPE", "TRAVERSE_ARRAY", "[", "0 (int64)", "]"),
|
|
|
|
append(make([]interface{}, 0), "a", "0 (int64)", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY", "SHORT_PIPE"),
|
2020-12-09 01:15:14 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
`.a[].c`,
|
2020-12-26 10:37:08 +00:00
|
|
|
append(make([]interface{}, 0), "a", "SHORT_PIPE", "TRAVERSE_ARRAY", "[", "]", "SHORT_PIPE", "c"),
|
|
|
|
append(make([]interface{}, 0), "a", "EMPTY", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY", "SHORT_PIPE", "c", "SHORT_PIPE"),
|
2020-12-09 01:15:14 +00:00
|
|
|
},
|
2020-11-28 00:24:16 +00:00
|
|
|
{
|
|
|
|
`[3]`,
|
|
|
|
append(make([]interface{}, 0), "[", "3 (int64)", "]"),
|
2020-12-01 07:08:41 +00:00
|
|
|
append(make([]interface{}, 0), "3 (int64)", "COLLECT", "SHORT_PIPE"),
|
2020-11-28 00:24:16 +00:00
|
|
|
},
|
2020-10-19 09:05:38 +00:00
|
|
|
{
|
|
|
|
`d0.a`,
|
2020-12-01 07:08:41 +00:00
|
|
|
append(make([]interface{}, 0), "d0", "SHORT_PIPE", "a"),
|
|
|
|
append(make([]interface{}, 0), "d0", "a", "SHORT_PIPE"),
|
2020-10-19 09:05:38 +00:00
|
|
|
},
|
2020-10-17 11:10:47 +00:00
|
|
|
{
|
2020-12-01 07:08:41 +00:00
|
|
|
`.a | .[].b == "apple"`,
|
2020-12-26 10:37:08 +00:00
|
|
|
append(make([]interface{}, 0), "a", "PIPE", "TRAVERSE_ARRAY", "[", "]", "SHORT_PIPE", "b", "EQUALS", "apple (string)"),
|
|
|
|
append(make([]interface{}, 0), "a", "EMPTY", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY", "b", "SHORT_PIPE", "apple (string)", "EQUALS", "PIPE"),
|
2020-10-17 11:10:47 +00:00
|
|
|
},
|
2020-12-01 07:10:10 +00:00
|
|
|
{
|
|
|
|
`(.a | .[].b) == "apple"`,
|
2020-12-26 10:37:08 +00:00
|
|
|
append(make([]interface{}, 0), "(", "a", "PIPE", "TRAVERSE_ARRAY", "[", "]", "SHORT_PIPE", "b", ")", "EQUALS", "apple (string)"),
|
|
|
|
append(make([]interface{}, 0), "a", "EMPTY", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY", "b", "SHORT_PIPE", "PIPE", "apple (string)", "EQUALS"),
|
2020-12-01 07:10:10 +00:00
|
|
|
},
|
2020-10-17 11:10:47 +00:00
|
|
|
{
|
|
|
|
`.[] | select(. == "*at")`,
|
2020-12-26 10:37:08 +00:00
|
|
|
append(make([]interface{}, 0), "TRAVERSE_ARRAY", "[", "]", "PIPE", "SELECT", "(", "SELF", "EQUALS", "*at (string)", ")"),
|
|
|
|
append(make([]interface{}, 0), "EMPTY", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY", "SELF", "*at (string)", "EQUALS", "SELECT", "PIPE"),
|
2020-10-17 11:10:47 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
`[true]`,
|
2020-10-20 04:33:20 +00:00
|
|
|
append(make([]interface{}, 0), "[", "true (bool)", "]"),
|
2020-12-01 07:08:41 +00:00
|
|
|
append(make([]interface{}, 0), "true (bool)", "COLLECT", "SHORT_PIPE"),
|
2020-10-17 11:10:47 +00:00
|
|
|
},
|
2020-10-21 02:54:51 +00:00
|
|
|
{
|
|
|
|
`[true, false]`,
|
|
|
|
append(make([]interface{}, 0), "[", "true (bool)", "UNION", "false (bool)", "]"),
|
2020-12-01 07:08:41 +00:00
|
|
|
append(make([]interface{}, 0), "true (bool)", "false (bool)", "UNION", "COLLECT", "SHORT_PIPE"),
|
2020-10-21 02:54:51 +00:00
|
|
|
},
|
2020-10-21 01:54:58 +00:00
|
|
|
{
|
|
|
|
`"mike": .a`,
|
|
|
|
append(make([]interface{}, 0), "mike (string)", "CREATE_MAP", "a"),
|
|
|
|
append(make([]interface{}, 0), "mike (string)", "a", "CREATE_MAP"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
`.a: "mike"`,
|
|
|
|
append(make([]interface{}, 0), "a", "CREATE_MAP", "mike (string)"),
|
|
|
|
append(make([]interface{}, 0), "a", "mike (string)", "CREATE_MAP"),
|
|
|
|
},
|
2020-10-21 02:54:51 +00:00
|
|
|
{
|
|
|
|
`{"mike": .a}`,
|
|
|
|
append(make([]interface{}, 0), "{", "mike (string)", "CREATE_MAP", "a", "}"),
|
2020-12-01 07:08:41 +00:00
|
|
|
append(make([]interface{}, 0), "mike (string)", "a", "CREATE_MAP", "COLLECT_OBJECT", "SHORT_PIPE"),
|
2020-10-21 02:54:51 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
`{.a: "mike"}`,
|
|
|
|
append(make([]interface{}, 0), "{", "a", "CREATE_MAP", "mike (string)", "}"),
|
2020-12-01 07:08:41 +00:00
|
|
|
append(make([]interface{}, 0), "a", "mike (string)", "CREATE_MAP", "COLLECT_OBJECT", "SHORT_PIPE"),
|
2020-10-21 02:54:51 +00:00
|
|
|
},
|
|
|
|
{
|
2020-11-22 02:50:32 +00:00
|
|
|
`{.a: .c, .b.[]: .f.g.[]}`,
|
2020-12-26 10:37:08 +00:00
|
|
|
append(make([]interface{}, 0), "{", "a", "CREATE_MAP", "c", "UNION", "b", "SHORT_PIPE", "TRAVERSE_ARRAY", "[", "]", "CREATE_MAP", "f", "SHORT_PIPE", "g", "SHORT_PIPE", "TRAVERSE_ARRAY", "[", "]", "}"),
|
|
|
|
append(make([]interface{}, 0), "a", "c", "CREATE_MAP", "b", "EMPTY", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY", "SHORT_PIPE", "f", "g", "SHORT_PIPE", "EMPTY", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY", "SHORT_PIPE", "CREATE_MAP", "UNION", "COLLECT_OBJECT", "SHORT_PIPE"),
|
2020-10-21 02:54:51 +00:00
|
|
|
},
|
2020-11-02 00:20:38 +00:00
|
|
|
{
|
|
|
|
`explode(.a.b)`,
|
2020-12-01 07:08:41 +00:00
|
|
|
append(make([]interface{}, 0), "EXPLODE", "(", "a", "SHORT_PIPE", "b", ")"),
|
|
|
|
append(make([]interface{}, 0), "a", "b", "SHORT_PIPE", "EXPLODE"),
|
2020-11-02 00:20:38 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
`.a.b style="folded"`,
|
2020-12-01 07:08:41 +00:00
|
|
|
append(make([]interface{}, 0), "a", "SHORT_PIPE", "b", "ASSIGN_STYLE", "folded (string)"),
|
|
|
|
append(make([]interface{}, 0), "a", "b", "SHORT_PIPE", "folded (string)", "ASSIGN_STYLE"),
|
2020-11-02 00:20:38 +00:00
|
|
|
},
|
2020-11-19 05:45:05 +00:00
|
|
|
{
|
|
|
|
`tag == "str"`,
|
|
|
|
append(make([]interface{}, 0), "GET_TAG", "EQUALS", "str (string)"),
|
|
|
|
append(make([]interface{}, 0), "GET_TAG", "str (string)", "EQUALS"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
`. tag= "str"`,
|
|
|
|
append(make([]interface{}, 0), "SELF", "ASSIGN_TAG", "str (string)"),
|
|
|
|
append(make([]interface{}, 0), "SELF", "str (string)", "ASSIGN_TAG"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
`lineComment == "str"`,
|
|
|
|
append(make([]interface{}, 0), "GET_COMMENT", "EQUALS", "str (string)"),
|
|
|
|
append(make([]interface{}, 0), "GET_COMMENT", "str (string)", "EQUALS"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
`. lineComment= "str"`,
|
|
|
|
append(make([]interface{}, 0), "SELF", "ASSIGN_COMMENT", "str (string)"),
|
|
|
|
append(make([]interface{}, 0), "SELF", "str (string)", "ASSIGN_COMMENT"),
|
|
|
|
},
|
2020-12-01 07:08:41 +00:00
|
|
|
{
|
|
|
|
`.a.b tag="!!str"`,
|
|
|
|
append(make([]interface{}, 0), "a", "SHORT_PIPE", "b", "ASSIGN_TAG", "!!str (string)"),
|
|
|
|
append(make([]interface{}, 0), "a", "b", "SHORT_PIPE", "!!str (string)", "ASSIGN_TAG"),
|
|
|
|
},
|
2020-11-02 00:20:38 +00:00
|
|
|
{
|
|
|
|
`""`,
|
|
|
|
append(make([]interface{}, 0), " (string)"),
|
|
|
|
append(make([]interface{}, 0), " (string)"),
|
|
|
|
},
|
2020-11-02 02:43:45 +00:00
|
|
|
{
|
|
|
|
`.foo* | (. style="flow")`,
|
|
|
|
append(make([]interface{}, 0), "foo*", "PIPE", "(", "SELF", "ASSIGN_STYLE", "flow (string)", ")"),
|
|
|
|
append(make([]interface{}, 0), "foo*", "SELF", "flow (string)", "ASSIGN_STYLE", "PIPE"),
|
|
|
|
},
|
2020-11-13 02:19:54 +00:00
|
|
|
{
|
|
|
|
`{}`,
|
|
|
|
append(make([]interface{}, 0), "{", "}"),
|
2020-12-01 07:08:41 +00:00
|
|
|
append(make([]interface{}, 0), "EMPTY", "COLLECT_OBJECT", "SHORT_PIPE"),
|
2020-11-13 02:19:54 +00:00
|
|
|
},
|
2020-09-17 11:58:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var tokeniser = NewPathTokeniser()
|
2020-10-20 02:53:26 +00:00
|
|
|
var postFixer = NewPathPostFixer()
|
2020-09-17 11:58:01 +00:00
|
|
|
|
2020-10-17 11:10:47 +00:00
|
|
|
func TestPathParsing(t *testing.T) {
|
|
|
|
for _, tt := range pathTests {
|
2020-09-17 11:58:01 +00:00
|
|
|
tokens, err := tokeniser.Tokenise(tt.path)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(tt.path, err)
|
|
|
|
}
|
|
|
|
var tokenValues []interface{}
|
|
|
|
for _, token := range tokens {
|
2020-10-20 04:33:20 +00:00
|
|
|
tokenValues = append(tokenValues, token.toString())
|
2020-09-17 11:58:01 +00:00
|
|
|
}
|
2020-10-17 11:10:47 +00:00
|
|
|
test.AssertResultComplexWithContext(t, tt.expectedTokens, tokenValues, fmt.Sprintf("tokenise: %v", tt.path))
|
|
|
|
|
|
|
|
results, errorP := postFixer.ConvertToPostfix(tokens)
|
|
|
|
|
|
|
|
var readableResults []interface{}
|
|
|
|
for _, token := range results {
|
|
|
|
readableResults = append(readableResults, token.toString())
|
|
|
|
}
|
|
|
|
|
|
|
|
if errorP != nil {
|
|
|
|
t.Error(tt.path, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
test.AssertResultComplexWithContext(t, tt.expectedPostFix, readableResults, fmt.Sprintf("postfix: %v", tt.path))
|
|
|
|
|
2020-09-17 11:58:01 +00:00
|
|
|
}
|
|
|
|
}
|