From e256eac18651c4b1c59dbc2674429e11bc3c90f4 Mon Sep 17 00:00:00 2001 From: Matt Farina Date: Tue, 1 Oct 2019 16:58:26 -0400 Subject: [PATCH] Documenting and testing for deep copying with merging of dicts Two things happen here: 1. A test is put into place for this situation to show the merge with and without a deep copy 2. Documentation is updated to show how to use deepCopy with merging --- docs/dicts.md | 16 ++++++++++++++-- issue_188_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 issue_188_test.go diff --git a/docs/dicts.md b/docs/dicts.md index 74f2660f..d4400df8 100644 --- a/docs/dicts.md +++ b/docs/dicts.md @@ -83,7 +83,13 @@ Merge two or more dictionaries into one, giving precedence to the dest dictionar $newdict := merge $dest $source1 $source2 ``` -This is a deep merge operation. +This is a deep merge operation but not a deep copy operation. Nested objects that +are merged are the same instance on both dicts. If you want a deep copy along +with the merge than use the `deepCopy` function along with merging. For example, + +``` +deepCopy $source | merge $dest +``` ## mergeOverwrite @@ -116,7 +122,13 @@ newdict: $newdict := mergeOverwrite $dest $source1 $source2 ``` -This is a deep merge operation. +This is a deep merge operation but not a deep copy operation. Nested objects that +are merged are the same instance on both dicts. If you want a deep copy along +with the merge than use the `deepCopy` function along with merging. For example, + +``` +deepCopy $source | mergeOverwrite $dest +``` ## keys diff --git a/issue_188_test.go b/issue_188_test.go new file mode 100644 index 00000000..c159ffbf --- /dev/null +++ b/issue_188_test.go @@ -0,0 +1,33 @@ +package sprig + +import ( + "testing" +) + +func TestIssue188(t *testing.T) { + tests := map[string]string{ + + // This first test shows two merges and the merge is NOT A DEEP COPY MERGE. + // The first merge puts $one on to $target. When the second merge of $two + // on to $target the nested dict brought over from $one is changed on + // $one as well as $target. + `{{- $target := dict -}} + {{- $one := dict "foo" (dict "bar" "baz") "qux" true -}} + {{- $two := dict "foo" (dict "bar" "baz2") "qux" false -}} + {{- mergeOverwrite $target $one | toString | trunc 0 }}{{ $__ := mergeOverwrite $target $two }}{{ $one }}`: "map[foo:map[bar:baz2] qux:true]", + + // This test uses deepCopy on $one to create a deep copy and then merge + // that. In this case the merge of $two on to $target does not affect + // $one because a deep copy was used for that merge. + `{{- $target := dict -}} + {{- $one := dict "foo" (dict "bar" "baz") "qux" true -}} + {{- $two := dict "foo" (dict "bar" "baz2") "qux" false -}} + {{- deepCopy $one | mergeOverwrite $target | toString | trunc 0 }}{{ $__ := mergeOverwrite $target $two }}{{ $one }}`: "map[foo:map[bar:baz] qux:true]", + } + + for tpl, expect := range tests { + if err := runt(tpl, expect); err != nil { + t.Error(err) + } + } +}