Merge pull request #2877 from monopole/rnodeCopy

RNode copier
This commit is contained in:
Jeff Regan
2020-08-21 18:33:17 -07:00
committed by GitHub
4 changed files with 106 additions and 0 deletions

View File

@@ -168,6 +168,16 @@ type RNode struct {
Match []string
}
// Copy returns a distinct copy.
func (rn *RNode) Copy() *RNode {
if rn == nil {
return nil
}
result := *rn
result.value = CopyYNode(rn.value)
return &result
}
var ErrMissingMetadata = fmt.Errorf("missing Resource metadata")
// Field names

View File

@@ -4,6 +4,7 @@
package yaml
import (
"reflect"
"strings"
"testing"
@@ -206,6 +207,33 @@ func TestIsMissingOrNull(t *testing.T) {
}
}
func TestCopy(t *testing.T) {
rn := RNode{
fieldPath: []string{"fp1", "fp2"},
value: &Node{
Kind: 200,
},
Match: []string{"m1", "m2"},
}
rnC := rn.Copy()
if !reflect.DeepEqual(&rn, rnC) {
t.Fatalf("copy %v is not deep equal to %v", rnC, rn)
}
tmp := rn.value.Kind
rn.value.Kind = 666
if reflect.DeepEqual(rn, rnC) {
t.Fatalf("changing component should break equality")
}
rn.value.Kind = tmp
if !reflect.DeepEqual(&rn, rnC) {
t.Fatalf("should be back to normal")
}
rn.fieldPath[0] = "Different"
if reflect.DeepEqual(rn, rnC) {
t.Fatalf("changing fieldpath should break equality")
}
}
func TestFieldRNodes(t *testing.T) {
testCases := []struct {
testName string

View File

@@ -12,6 +12,23 @@ import (
"sigs.k8s.io/kustomize/kyaml/sets"
)
// CopyYNode returns a distinct copy of its argument.
// Use https://github.com/jinzhu/copier instead?
func CopyYNode(n *yaml.Node) *yaml.Node {
if n == nil {
return nil
}
c := *n
if len(n.Content) > 0 {
// Using Go 'copy' here doesn't yield independent slices.
c.Content = make([]*Node, len(n.Content))
for i, item := range n.Content {
c.Content[i] = CopyYNode(item)
}
}
return &c
}
// IsYNodeTaggedNull returns true if the node is explicitly tagged Null.
func IsYNodeTaggedNull(n *yaml.Node) bool {
return n != nil && n.Tag == NodeTagNull

View File

@@ -4,9 +4,60 @@
package yaml
import (
"reflect"
"testing"
)
func TestCopyYNode(t *testing.T) {
ynSub1 := Node{
Kind: 100,
}
ynSub2 := Node{
Kind: 200,
}
ynSub3 := Node{
Kind: 300,
}
yn := Node{
Kind: 5000,
Style: 6000,
Tag: "red",
Value: "green",
Anchor: "blue",
Alias: &ynSub3,
Content: []*Node{&ynSub1, &ynSub2},
HeadComment: "apple",
LineComment: "peach",
FootComment: "banana",
Line: 7000,
Column: 8000,
}
ynAddr := &yn
if !reflect.DeepEqual(&yn, ynAddr) {
t.Fatalf("truly %v should equal %v", &yn, ynAddr)
}
ynC := CopyYNode(&yn)
if !reflect.DeepEqual(yn.Content, ynC.Content) {
t.Fatalf("copy content %v is not deep equal to %v", ynC, yn)
}
if !reflect.DeepEqual(&yn, ynC) {
t.Fatalf("\noriginal: %v\n copy: %v\nShould be equal.", yn, ynC)
}
tmp := yn.Content[0].Kind
yn.Content[0].Kind = 666
if reflect.DeepEqual(&yn, ynC) {
t.Fatalf("changing component should break equality")
}
yn.Content[0].Kind = tmp
if !reflect.DeepEqual(&yn, ynC) {
t.Fatalf("should be okay now")
}
yn.Tag = "Different"
if yn.Tag == ynC.Tag {
t.Fatalf("field aliased!")
}
}
func TestIsYNodeTaggedNull(t *testing.T) {
if IsYNodeTaggedNull(nil) {
t.Fatalf("nil cannot be tagged null")