create object fixes

This commit is contained in:
Mike Farah 2020-10-28 13:00:26 +11:00
parent 41c08891d3
commit 4edb3e9021
6 changed files with 78 additions and 22 deletions

View File

@ -28,6 +28,11 @@ func collect(d *dataTreeNavigator, aggregate *list.List, remainingMatches *list.
candidate := remainingMatches.Remove(remainingMatches.Front()).(*CandidateNode) candidate := remainingMatches.Remove(remainingMatches.Front()).(*CandidateNode)
splatted, err := Splat(d, nodeToMap(candidate)) splatted, err := Splat(d, nodeToMap(candidate))
for splatEl := splatted.Front(); splatEl != nil; splatEl = splatEl.Next() {
splatEl.Value.(*CandidateNode).Path = nil
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -44,10 +49,8 @@ func collect(d *dataTreeNavigator, aggregate *list.List, remainingMatches *list.
splatCandidate := splatEl.Value.(*CandidateNode) splatCandidate := splatEl.Value.(*CandidateNode)
newCandidate := aggCandidate.Copy() newCandidate := aggCandidate.Copy()
newCandidate.Path = nil newCandidate.Path = nil
splatCandidateClone := splatCandidate.Copy()
splatCandidateClone.Path = nil
newCandidate, err := multiply(d, newCandidate, splatCandidateClone) newCandidate, err := multiply(d, newCandidate, splatCandidate)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -9,15 +9,15 @@ var collectObjectOperatorScenarios = []expressionScenario{
document: `{name: Mike, age: 32}`, document: `{name: Mike, age: 32}`,
expression: `{.name: .age}`, expression: `{.name: .age}`,
expected: []string{ expected: []string{
"D0, P[0], (!!map)::Mike: 32\n", "D0, P[], (!!map)::Mike: 32\n",
}, },
}, },
{ {
document: `{name: Mike, pets: [cat, dog]}`, document: `{name: Mike, pets: [cat, dog]}`,
expression: `{.name: .pets[]}`, expression: `{.name: .pets[]}`,
expected: []string{ expected: []string{
"D0, P[0], (!!map)::Mike: cat\n", "D0, P[], (!!map)::Mike: cat\n",
"D0, P[1], (!!map)::Mike: dog\n", "D0, P[], (!!map)::Mike: dog\n",
}, },
}, },
{ {
@ -36,6 +36,29 @@ var collectObjectOperatorScenarios = []expressionScenario{
expected: []string{ expected: []string{
`D0, P[], (!!map)::a: Mike `D0, P[], (!!map)::a: Mike
b: {cows: [apl, bba]} b: {cows: [apl, bba]}
`,
},
},
{
document: ``,
expression: `{"wrap": "frog"}`,
expected: []string{
"D0, P[], (!!map)::wrap: frog\n",
},
},
{
document: `{name: Mike}`,
expression: `{"wrap": .}`,
expected: []string{
"D0, P[], (!!map)::wrap: {name: Mike}\n",
},
},
{
document: `{name: Mike}`,
expression: `{"wrap": {"further": .}}`,
expected: []string{
`D0, P[], (!!map)::wrap:
further: {name: Mike}
`, `,
}, },
}, },

View File

@ -19,11 +19,11 @@ func CreateMapOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode
mapPairs, err := crossFunction(d, matchingNodes, pathNode, mapPairs, err := crossFunction(d, matchingNodes, pathNode,
func(d *dataTreeNavigator, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) { func(d *dataTreeNavigator, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
node := yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"} node := yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"}
log.Debugf("LHS:", lhs.Node.Value) log.Debugf("LHS:", NodeToString(lhs))
log.Debugf("RHS:", rhs.Node.Value) log.Debugf("RHS:", NodeToString(rhs))
node.Content = []*yaml.Node{ node.Content = []*yaml.Node{
lhs.Node, UnwrapDoc(lhs.Node),
rhs.Node, UnwrapDoc(rhs.Node),
} }
return &CandidateNode{Node: &node, Document: document, Path: path}, nil return &CandidateNode{Node: &node, Document: document, Path: path}, nil

View File

@ -35,6 +35,13 @@ var createMapOperatorScenarios = []expressionScenario{
"D0, P[], (!!seq)::- b: {cows: [apl, bba]}\n", "D0, P[], (!!seq)::- b: {cows: [apl, bba]}\n",
}, },
}, },
{
document: `{name: Mike}`,
expression: `"wrap": .`,
expected: []string{
"D0, P[], (!!seq)::- wrap: {name: Mike}\n",
},
},
} }
func TestCreateMapOperatorScenarios(t *testing.T) { func TestCreateMapOperatorScenarios(t *testing.T) {

View File

@ -53,25 +53,41 @@ func multiply(d *dataTreeNavigator, lhs *CandidateNode, rhs *CandidateNode) (*Ca
if lhs.Node.Kind == yaml.MappingNode && rhs.Node.Kind == yaml.MappingNode || if lhs.Node.Kind == yaml.MappingNode && rhs.Node.Kind == yaml.MappingNode ||
(lhs.Node.Kind == yaml.SequenceNode && rhs.Node.Kind == yaml.SequenceNode) { (lhs.Node.Kind == yaml.SequenceNode && rhs.Node.Kind == yaml.SequenceNode) {
var results = list.New()
recursiveDecent(d, results, nodeToMap(rhs))
var pathIndexToStartFrom int = 0 var newBlank = &CandidateNode{
if results.Front() != nil { Path: lhs.Path,
pathIndexToStartFrom = len(results.Front().Value.(*CandidateNode).Path) Document: lhs.Document,
Filename: lhs.Filename,
Node: &yaml.Node{},
} }
var newThing, err = mergeObjects(d, newBlank, lhs)
if err != nil {
return nil, err
}
return mergeObjects(d, newThing, rhs)
for el := results.Front(); el != nil; el = el.Next() {
err := applyAssignment(d, pathIndexToStartFrom, lhs, el.Value.(*CandidateNode))
if err != nil {
return nil, err
}
}
return lhs, nil
} }
return nil, fmt.Errorf("Cannot multiply %v with %v", NodeToString(lhs), NodeToString(rhs)) return nil, fmt.Errorf("Cannot multiply %v with %v", NodeToString(lhs), NodeToString(rhs))
} }
func mergeObjects(d *dataTreeNavigator, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
var results = list.New()
recursiveDecent(d, results, nodeToMap(rhs))
var pathIndexToStartFrom int = 0
if results.Front() != nil {
pathIndexToStartFrom = len(results.Front().Value.(*CandidateNode).Path)
}
for el := results.Front(); el != nil; el = el.Next() {
err := applyAssignment(d, pathIndexToStartFrom, lhs, el.Value.(*CandidateNode))
if err != nil {
return nil, err
}
}
return lhs, nil
}
func createTraversalTree(path []interface{}) *PathTreeNode { func createTraversalTree(path []interface{}) *PathTreeNode {
if len(path) == 0 { if len(path) == 0 {
return &PathTreeNode{Operation: &Operation{OperationType: SelfReference}} return &PathTreeNode{Operation: &Operation{OperationType: SelfReference}}

View File

@ -74,6 +74,13 @@ b:
"D0, P[], (!!map)::{a: [3, 4, 5], b: [3, 4, 5]}\n", "D0, P[], (!!map)::{a: [3, 4, 5], b: [3, 4, 5]}\n",
}, },
}, },
{
document: `{a: cat}`,
expression: `. * {"a": {"c": .a}}`,
expected: []string{
"D0, P[], (!!map)::{a: {c: cat}}\n",
},
},
} }
func TestMultiplyOperatorScenarios(t *testing.T) { func TestMultiplyOperatorScenarios(t *testing.T) {