mirror of
https://github.com/taigrr/yq
synced 2025-01-18 04:53:17 -08:00
value parse test
This commit is contained in:
@@ -628,81 +628,6 @@ func TestDataTreeNavigatorArraySimple(t *testing.T) {
|
||||
test.AssertResult(t, expected, resultsToString(results))
|
||||
}
|
||||
|
||||
func TestDataTreeNavigatorSimpleAssignCmd(t *testing.T) {
|
||||
|
||||
nodes := readDoc(t, `a:
|
||||
b: apple`)
|
||||
|
||||
path, errPath := treeCreator.ParsePath(`.a.b |= "frog"`)
|
||||
if errPath != nil {
|
||||
t.Error(errPath)
|
||||
}
|
||||
results, errNav := treeNavigator.GetMatchingNodes(nodes, path)
|
||||
|
||||
if errNav != nil {
|
||||
t.Error(errNav)
|
||||
}
|
||||
|
||||
expected := `
|
||||
-- Node --
|
||||
Document 0, path: [a b]
|
||||
Tag: !!str, Kind: ScalarNode, Anchor:
|
||||
frog
|
||||
`
|
||||
|
||||
test.AssertResult(t, expected, resultsToString(results))
|
||||
}
|
||||
|
||||
func TestDataTreeNavigatorSimpleAssignNumberCmd(t *testing.T) {
|
||||
|
||||
nodes := readDoc(t, `a:
|
||||
b: apple`)
|
||||
|
||||
path, errPath := treeCreator.ParsePath(`.a.b |= 5`)
|
||||
if errPath != nil {
|
||||
t.Error(errPath)
|
||||
}
|
||||
results, errNav := treeNavigator.GetMatchingNodes(nodes, path)
|
||||
|
||||
if errNav != nil {
|
||||
t.Error(errNav)
|
||||
}
|
||||
|
||||
expected := `
|
||||
-- Node --
|
||||
Document 0, path: [a b]
|
||||
Tag: !!int, Kind: ScalarNode, Anchor:
|
||||
5
|
||||
`
|
||||
|
||||
test.AssertResult(t, expected, resultsToString(results))
|
||||
}
|
||||
|
||||
func TestDataTreeNavigatorSimpleAssignFloatCmd(t *testing.T) {
|
||||
|
||||
nodes := readDoc(t, `a:
|
||||
b: apple`)
|
||||
|
||||
path, errPath := treeCreator.ParsePath(`.a.b |= 3.142`)
|
||||
if errPath != nil {
|
||||
t.Error(errPath)
|
||||
}
|
||||
results, errNav := treeNavigator.GetMatchingNodes(nodes, path)
|
||||
|
||||
if errNav != nil {
|
||||
t.Error(errNav)
|
||||
}
|
||||
|
||||
expected := `
|
||||
-- Node --
|
||||
Document 0, path: [a b]
|
||||
Tag: !!float, Kind: ScalarNode, Anchor:
|
||||
3.142
|
||||
`
|
||||
|
||||
test.AssertResult(t, expected, resultsToString(results))
|
||||
}
|
||||
|
||||
func TestDataTreeNavigatorSimpleAssignBooleanCmd(t *testing.T) {
|
||||
|
||||
nodes := readDoc(t, `a:
|
||||
|
||||
27
pkg/yqlib/treeops/operator_assign.go
Normal file
27
pkg/yqlib/treeops/operator_assign.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package treeops
|
||||
|
||||
import "github.com/elliotchance/orderedmap"
|
||||
|
||||
func AssignOperator(d *dataTreeNavigator, matchingNodes *orderedmap.OrderedMap, pathNode *PathTreeNode) (*orderedmap.OrderedMap, error) {
|
||||
lhs, err := d.getMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for el := lhs.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
rhs, err := d.getMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// grab the first value
|
||||
first := rhs.Front()
|
||||
|
||||
if first != nil {
|
||||
candidate.UpdateFrom(first.Value.(*CandidateNode))
|
||||
}
|
||||
}
|
||||
return matchingNodes, nil
|
||||
}
|
||||
62
pkg/yqlib/treeops/operator_assign_test.go
Normal file
62
pkg/yqlib/treeops/operator_assign_test.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package treeops
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var assignOperatorScenarios = []expressionScenario{
|
||||
{
|
||||
document: `{a: {b: apple}}`,
|
||||
expression: `.a.b |= "frog"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {b: frog}}\n",
|
||||
},
|
||||
}, {
|
||||
document: `{a: {b: apple}}`,
|
||||
expression: `.a.b | (. |= "frog")`,
|
||||
expected: []string{
|
||||
"D0, P[a b], (!!str)::frog\n",
|
||||
},
|
||||
}, {
|
||||
document: `{a: {b: apple}}`,
|
||||
expression: `.a.b |= 5`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {b: 5}}\n",
|
||||
},
|
||||
}, {
|
||||
document: `{a: {b: apple}}`,
|
||||
expression: `.a.b |= 3.142`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {b: 3.142}}\n",
|
||||
},
|
||||
// document: `{}`,
|
||||
// expression: `["cat", "dog"]`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!seq)::- cat\n- dog\n",
|
||||
// },
|
||||
// }, {
|
||||
// document: `{}`,
|
||||
// expression: `1 | collect`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!seq)::- 1\n",
|
||||
// },
|
||||
// }, {
|
||||
// document: `[1,2,3]`,
|
||||
// expression: `[.[]]`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!seq)::- 1\n- 2\n- 3\n",
|
||||
// },
|
||||
// }, {
|
||||
// document: `a: {b: [1,2,3]}`,
|
||||
// expression: `[.a.b[]]`,
|
||||
// expected: []string{
|
||||
// "D0, P[a b], (!!seq)::- 1\n- 2\n- 3\n",
|
||||
// },
|
||||
},
|
||||
}
|
||||
|
||||
func TestAssignOperatorScenarios(t *testing.T) {
|
||||
for _, tt := range assignOperatorScenarios {
|
||||
testScenario(t, &tt)
|
||||
}
|
||||
}
|
||||
75
pkg/yqlib/treeops/operator_value_test.go
Normal file
75
pkg/yqlib/treeops/operator_value_test.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package treeops
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var valueOperatorScenarios = []expressionScenario{
|
||||
{
|
||||
document: ``,
|
||||
expression: `1`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::1\n",
|
||||
},
|
||||
}, {
|
||||
document: ``,
|
||||
expression: `-1`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::-1\n",
|
||||
},
|
||||
}, {
|
||||
document: ``,
|
||||
expression: `1.2`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!float)::1.2\n",
|
||||
},
|
||||
}, {
|
||||
document: ``,
|
||||
expression: `-5.2e11`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!float)::-5.2e11\n",
|
||||
},
|
||||
}, {
|
||||
document: ``,
|
||||
expression: `5e-10`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!float)::5e-10\n",
|
||||
},
|
||||
}, {
|
||||
document: ``,
|
||||
expression: `"cat"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::cat\n",
|
||||
},
|
||||
}, {
|
||||
document: ``,
|
||||
expression: `"1.3"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::\"1.3\"\n",
|
||||
},
|
||||
}, {
|
||||
document: ``,
|
||||
expression: `"true"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::\"true\"\n",
|
||||
},
|
||||
}, {
|
||||
document: ``,
|
||||
expression: `true`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!bool)::true\n",
|
||||
},
|
||||
}, {
|
||||
document: ``,
|
||||
expression: `false`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!bool)::false\n",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestValueOperatorScenarios(t *testing.T) {
|
||||
for _, tt := range valueOperatorScenarios {
|
||||
testScenario(t, &tt)
|
||||
}
|
||||
}
|
||||
@@ -32,30 +32,6 @@ func nodeToMap(candidate *CandidateNode) *orderedmap.OrderedMap {
|
||||
return elMap
|
||||
}
|
||||
|
||||
func AssignOperator(d *dataTreeNavigator, matchingNodes *orderedmap.OrderedMap, pathNode *PathTreeNode) (*orderedmap.OrderedMap, error) {
|
||||
lhs, err := d.getMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for el := lhs.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
rhs, err := d.getMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// grab the first value
|
||||
first := rhs.Front()
|
||||
|
||||
if first != nil {
|
||||
candidate.UpdateFrom(first.Value.(*CandidateNode))
|
||||
}
|
||||
}
|
||||
return lhs, nil
|
||||
}
|
||||
|
||||
func IntersectionOperator(d *dataTreeNavigator, matchingNodes *orderedmap.OrderedMap, pathNode *PathTreeNode) (*orderedmap.OrderedMap, error) {
|
||||
lhs, err := d.getMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
|
||||
@@ -76,6 +76,17 @@ func numberValue() lex.Action {
|
||||
}
|
||||
}
|
||||
|
||||
func floatValue() lex.Action {
|
||||
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
|
||||
var numberString = string(m.Bytes)
|
||||
var number, errParsingInt = strconv.ParseFloat(numberString, 64) // nolint
|
||||
if errParsingInt != nil {
|
||||
return nil, errParsingInt
|
||||
}
|
||||
return &Token{PathElementType: Value, OperationType: None, Value: number, StringValue: numberString}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func booleanValue(val bool) lex.Action {
|
||||
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
|
||||
return &Token{PathElementType: Value, OperationType: None, Value: val, StringValue: string(m.Bytes)}, nil
|
||||
@@ -111,7 +122,7 @@ func initLexer() (*lex.Lexer, error) {
|
||||
lexer.Add([]byte(`length`), opToken(Length))
|
||||
lexer.Add([]byte(`select`), opToken(Select))
|
||||
lexer.Add([]byte(`or`), opToken(Or))
|
||||
lexer.Add([]byte(`and`), opToken(And))
|
||||
// lexer.Add([]byte(`and`), opToken())
|
||||
lexer.Add([]byte(`collect`), opToken(Collect))
|
||||
|
||||
lexer.Add([]byte(`\s*==\s*`), opToken(Equals))
|
||||
@@ -131,7 +142,9 @@ func initLexer() (*lex.Lexer, error) {
|
||||
|
||||
lexer.Add([]byte(`\|`), opToken(Pipe))
|
||||
|
||||
lexer.Add([]byte(`-?[0-9]+`), numberValue())
|
||||
lexer.Add([]byte(`-?\d+(\.\d+)`), floatValue())
|
||||
lexer.Add([]byte(`-?[1-9](\.\d+)?[Ee][-+]?\d+`), floatValue())
|
||||
lexer.Add([]byte(`-?\d+`), numberValue())
|
||||
|
||||
lexer.Add([]byte(`[Tt][Rr][Uu][Ee]`), booleanValue(true))
|
||||
lexer.Add([]byte(`[Ff][Aa][Ll][Ss][Ee]`), booleanValue(false))
|
||||
|
||||
Reference in New Issue
Block a user