From e0e76fb0c2a672204f3f7be0671203a7bded7c78 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Thu, 19 Oct 2023 14:39:15 +0300 Subject: [PATCH 1/7] Update go version + deps Signed-off-by: Kimmo Lehto --- go.mod | 10 ++++++++-- go.sum | 13 ++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 7a6b738..7c7bf40 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,14 @@ module github.com/k0sproject/dig -go 1.15 +go 1.21 require ( - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.8.4 gopkg.in/yaml.v2 v2.4.0 ) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum index 8fc3599..5af9e74 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,12 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 92840892a4429193faa1a9a555ff6d1d7fe3dc50 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Thu, 19 Oct 2023 14:39:29 +0300 Subject: [PATCH 2/7] Replace interface{} with any Signed-off-by: Kimmo Lehto --- mapping.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/mapping.go b/mapping.go index 84297d1..01899f5 100644 --- a/mapping.go +++ b/mapping.go @@ -1,16 +1,16 @@ -// Package dig provides a map[string]interface{} Mapping type that has ruby-like "dig" functionality. +// Package dig provides a map[string]any Mapping type that has ruby-like "dig" functionality. // // It can be used for example to access and manipulate arbitary nested YAML/JSON structures. package dig import "fmt" -// Mapping is a nested key-value map where the keys are strings and values are interface{}. In Ruby it is called a Hash (with string keys), in YAML it's called a "mapping". -type Mapping map[string]interface{} +// Mapping is a nested key-value map where the keys are strings and values are any. In Ruby it is called a Hash (with string keys), in YAML it's called a "mapping". +type Mapping map[string]any // UnmarshalYAML for supporting yaml.Unmarshal -func (m *Mapping) UnmarshalYAML(unmarshal func(interface{}) error) error { - var result map[interface{}]interface{} +func (m *Mapping) UnmarshalYAML(unmarshal func(any) error) error { + var result map[string]any if err := unmarshal(&result); err != nil { return err } @@ -21,7 +21,7 @@ func (m *Mapping) UnmarshalYAML(unmarshal func(interface{}) error) error { // Dig is a simplistic implementation of a Ruby-like Hash.dig functionality. // // It returns a value from a (deeply) nested tree structure. -func (m *Mapping) Dig(keys ...string) interface{} { +func (m *Mapping) Dig(keys ...string) any { v, ok := (*m)[keys[0]] if !ok { return nil @@ -111,8 +111,8 @@ func (m *Mapping) Dup() Mapping { } // Cleans up a slice of interfaces into slice of actual values -func cleanUpInterfaceArray(in []interface{}) []interface{} { - result := make([]interface{}, len(in)) +func cleanUpInterfaceArray(in []any) []any { + result := make([]any, len(in)) for i, v := range in { result[i] = cleanUpMapValue(v) } @@ -120,7 +120,7 @@ func cleanUpInterfaceArray(in []interface{}) []interface{} { } // Cleans up the map keys to be strings -func cleanUpInterfaceMap(in map[interface{}]interface{}) Mapping { +func cleanUpInterfaceMap(in map[string]any) Mapping { result := make(Mapping) for k, v := range in { result[fmt.Sprintf("%v", k)] = cleanUpMapValue(v) @@ -129,11 +129,11 @@ func cleanUpInterfaceMap(in map[interface{}]interface{}) Mapping { } // Cleans up the value in the map, recurses in case of arrays and maps -func cleanUpMapValue(v interface{}) interface{} { +func cleanUpMapValue(v any) any { switch v := v.(type) { - case []interface{}: + case []any: return cleanUpInterfaceArray(v) - case map[interface{}]interface{}: + case map[string]any: return cleanUpInterfaceMap(v) case string, int, bool, nil: return v From ab39755591676faf24e5aee1e341d186f71bb0bd Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Fri, 20 Oct 2023 09:58:01 +0300 Subject: [PATCH 3/7] Use dig_test as test package name Signed-off-by: Kimmo Lehto --- mapping_test.go | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/mapping_test.go b/mapping_test.go index 4a1be71..b30e414 100644 --- a/mapping_test.go +++ b/mapping_test.go @@ -1,16 +1,18 @@ -package dig +package dig_test import ( "fmt" "testing" + "github.com/k0sproject/dig" + "github.com/stretchr/testify/assert" "gopkg.in/yaml.v2" ) func TestDig(t *testing.T) { - m := Mapping{ - "foo": Mapping{ + m := dig.Mapping{ + "foo": dig.Mapping{ "bar": "foobar", }, } @@ -21,8 +23,8 @@ func TestDig(t *testing.T) { } func TestDigString(t *testing.T) { - m := Mapping{ - "foo": Mapping{ + m := dig.Mapping{ + "foo": dig.Mapping{ "bar": "foobar", }, } @@ -33,8 +35,8 @@ func TestDigString(t *testing.T) { } func TestDigMapping(t *testing.T) { - m := Mapping{ - "foo": Mapping{ + m := dig.Mapping{ + "foo": dig.Mapping{ "bar": "foobar", }, } @@ -52,14 +54,14 @@ func TestDigMapping(t *testing.T) { } func TestDup(t *testing.T) { - m := Mapping{ - "foo": Mapping{ + m := dig.Mapping{ + "foo": dig.Mapping{ "bar": "foobar", }, "array": []string{ "hello", }, - "mappingarray": []Mapping{ + "mappingarray": []dig.Mapping{ {"bar": "foobar"}, {"foo": "barfoo"}, }, @@ -72,7 +74,7 @@ func TestDup(t *testing.T) { arr = append(arr, "world") m["array"] = arr - ma := m["mappingarray"].([]Mapping) + ma := m["mappingarray"].([]dig.Mapping) maa := ma[0] maa["bar"] = "barbar" @@ -85,8 +87,8 @@ func TestDup(t *testing.T) { assert.Len(t, a, 2) assert.Len(t, b, 1) - am := m.Dig("mappingarray").([]Mapping) - bm := dup.Dig("mappingarray").([]Mapping) + am := m.Dig("mappingarray").([]dig.Mapping) + bm := dup.Dig("mappingarray").([]dig.Mapping) assert.Equal(t, "barbar", am[0]["bar"]) assert.Equal(t, "foobar", bm[0]["bar"]) @@ -94,15 +96,15 @@ func TestDup(t *testing.T) { func TestUnmarshalYamlWithNil(t *testing.T) { data := `foo: null` - var m Mapping + var m dig.Mapping err := yaml.Unmarshal([]byte(data), &m) assert.NoError(t, err) assert.Nil(t, m.Dig("foo")) } func ExampleMapping_Dig() { - h := Mapping{ - "greeting": Mapping{ + h := dig.Mapping{ + "greeting": dig.Mapping{ "target": "world", }, } @@ -111,14 +113,14 @@ func ExampleMapping_Dig() { } func ExampleMapping_DigMapping() { - h := Mapping{} + h := dig.Mapping{} h.DigMapping("greeting")["target"] = "world" fmt.Println("Hello,", h.Dig("greeting", "target")) // Output: Hello, world } func ExampleMapping_DigString() { - h := Mapping{} + h := dig.Mapping{} h.DigMapping("greeting")["target"] = "world" fmt.Println("Hello,", h.DigString("greeting", "target"), "!") fmt.Println("Hello,", h.Dig("greeting", "non-existing"), "!") From 48a623503e82c63725d37240e8fe39d05f5e9659 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Fri, 20 Oct 2023 10:02:35 +0300 Subject: [PATCH 4/7] Typo Signed-off-by: Kimmo Lehto --- mapping.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mapping.go b/mapping.go index 01899f5..cae51ea 100644 --- a/mapping.go +++ b/mapping.go @@ -1,6 +1,6 @@ // Package dig provides a map[string]any Mapping type that has ruby-like "dig" functionality. // -// It can be used for example to access and manipulate arbitary nested YAML/JSON structures. +// It can be used for example to access and manipulate arbitrary nested YAML/JSON structures. package dig import "fmt" From e0c7222a6be948d5a5e2c2bea28985cc40801c51 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Fri, 20 Oct 2023 10:07:56 +0300 Subject: [PATCH 5/7] Update GH workflow Signed-off-by: Kimmo Lehto --- .github/workflows/go.yml | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index da285a9..dce3291 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -1,41 +1,25 @@ name: Go -on: [push, pull_request] +on: [pull_request] jobs: - - build: + go: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v2 - if: github.ref != 'refs/heads/main' - with: - go-version: 1.15 - - - name: Go modules cache - uses: actions/cache@v2 - if: github.ref != 'refs/heads/main' - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - - name: Run golangci-lint + uses: actions/setup-go@v4 if: github.ref != 'refs/heads/main' - uses: golangci/golangci-lint-action@v2.3.0 with: - version: v1.35.2 - skip-go-installation: true - - - name: Build - if: github.ref != 'refs/heads/main' - run: go build -v ./... - + go-version-file: go.mod + check-latest: true + - name: Test - if: github.ref != 'refs/heads/main' run: go test -v ./... + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: latest + args: --verbose From 28ae5087f760b02330b519b6d138b472e9593164 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Fri, 20 Oct 2023 10:18:33 +0300 Subject: [PATCH 6/7] Update README Signed-off-by: Kimmo Lehto --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c063fa6..7d3d44f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Dig -A go package that provides a Ruby-like `Hash.dig` mechanism for `map[string]interface{}`, which in YAML terminology is refered to as "Mapping". +A go package that provides a Ruby-like `Hash.dig` mechanism for `map[string]any`, which in YAML is refered to as "Mapping". ## Usage -Dig's Mapping is useful for example to use as the Unmarshal target of arbitrary YAML/JSON documents. +The provided `dig.Mapping` is handy when unmarshaling arbitrary YAML/JSON documents. ### Example ```go @@ -21,7 +21,7 @@ var yamlDoc = []byte(`--- i18n: hello: se: Hejsan - fi: Morjens + fi: Moi world: se: Värld fi: Maailma @@ -55,7 +55,7 @@ func main() { Output: ``` -Morjens, Maailma! +Moi, Maailma! Hejsan, Värld! Hola, Mundo! ``` From c97c8bd7f8d6b4989536da26502ae2291ef30232 Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Fri, 20 Oct 2023 11:10:37 +0300 Subject: [PATCH 7/7] Rewrite tests, drop all dependencies Signed-off-by: Kimmo Lehto --- README.md | 2 +- examples/readme.go | 40 ---------------- go.mod | 11 ----- go.sum | 12 ----- mapping_test.go | 117 ++++++++++++++++++++++++++++----------------- 5 files changed, 75 insertions(+), 107 deletions(-) delete mode 100644 examples/readme.go diff --git a/README.md b/README.md index 7d3d44f..aaf409c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Dig -A go package that provides a Ruby-like `Hash.dig` mechanism for `map[string]any`, which in YAML is refered to as "Mapping". +A simple zero-dependency go package that provides a Ruby-like `Hash.dig` mechanism for `map[string]any`, which in YAML is refered to as "Mapping". ## Usage diff --git a/examples/readme.go b/examples/readme.go deleted file mode 100644 index 2b69fc7..0000000 --- a/examples/readme.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/k0sproject/dig" - "gopkg.in/yaml.v2" -) - -var yamlDoc = []byte(`--- -i18n: - hello: - se: Hejsan - fi: Morjens - world: - se: Värld - fi: Maailma -`) - -func main() { - m := dig.Mapping{} - if err := yaml.Unmarshal(yamlDoc, &m); err != nil { - panic(err) - } - - // You can use DigMapping to access a deeply nested map and set values. - // Any missing Mapping level in between will be created. - m.DigMapping("i18n", "hello")["es"] = "Hola" - m.DigMapping("i18n", "world")["es"] = "Mundo" - - langs := []string{"fi", "se", "es"} - for _, l := range langs { - // You can use Dig to access a deeply nested value - greeting := m.Dig("i18n", "hello", l).(string) - // ..or DigString to avoid having to cast it to string. - target := m.DigString("i18n", "world", l) - - fmt.Printf("%s, %s!\n", greeting, target) - } -} diff --git a/go.mod b/go.mod index 7c7bf40..e8d2a78 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,3 @@ module github.com/k0sproject/dig go 1.21 - -require ( - github.com/stretchr/testify v1.8.4 - gopkg.in/yaml.v2 v2.4.0 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/go.sum b/go.sum index 5af9e74..e69de29 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +0,0 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/mapping_test.go b/mapping_test.go index b30e414..cb2288a 100644 --- a/mapping_test.go +++ b/mapping_test.go @@ -1,15 +1,31 @@ package dig_test import ( + "encoding/json" "fmt" "testing" "github.com/k0sproject/dig" - - "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v2" ) +func mustEqualString(t *testing.T, expected, actual string) { + if expected != actual { + t.Errorf("Expected %v, got %v", expected, actual) + } +} + +func mustBeNil(t *testing.T, actual any) { + if actual != nil { + t.Errorf("Expected nil, got %v", actual) + } +} + +func mustEqual(t *testing.T, expected, actual any) { + if expected != actual { + t.Errorf("Expected %v, got %v", expected, actual) + } +} + func TestDig(t *testing.T) { m := dig.Mapping{ "foo": dig.Mapping{ @@ -17,9 +33,13 @@ func TestDig(t *testing.T) { }, } - assert.Equal(t, "foobar", m.Dig("foo", "bar")) + t.Run("fetch nested value", func(t *testing.T) { + mustEqualString(t, "foobar", m.Dig("foo", "bar").(string)) + }) - assert.Nil(t, m.Dig("foo", "non-existing", "key")) + t.Run("non-existing key should return nil", func(t *testing.T) { + mustBeNil(t, m.Dig("foo", "non-existing")) + }) } func TestDigString(t *testing.T) { @@ -29,9 +49,14 @@ func TestDigString(t *testing.T) { }, } - assert.Equal(t, "foobar", m.DigString("foo", "bar")) - assert.Equal(t, "", m.DigString("foo", "nonexisting")) - assert.Equal(t, "", m.DigString("nonexisting", "nonexisting")) + t.Run("fetch nested string", func(t *testing.T) { + mustEqualString(t, "foobar", m.DigString("foo", "bar")) + }) + + t.Run("non-existing key should return an empty string", func(t *testing.T) { + mustEqualString(t, "", m.DigString("foo", "non-existing")) + mustEqualString(t, "", m.DigString("non-existing", "non-existing")) + }) } func TestDigMapping(t *testing.T) { @@ -41,16 +66,23 @@ func TestDigMapping(t *testing.T) { }, } - assert.Equal(t, "foobar", m.DigMapping("foo")["bar"]) + t.Run("fetch nested mapping", func(t *testing.T) { + mustEqualString(t, "foobar", m.DigMapping("foo")["bar"].(string)) + }) + + t.Run("set a nested value", func(t *testing.T) { + m.DigMapping("foo", "baz")["dog"] = 1 + mustEqual(t, 1, m.Dig("foo", "baz", "dog")) - m.DigMapping("foo", "baz")["dog"] = 1 - assert.Equal(t, 1, m.Dig("foo", "baz", "dog")) - // Make sure foo.bar was left intact - assert.Equal(t, "foobar", m.Dig("foo", "bar")) + // Make sure foo.bar was left intact + mustEqualString(t, "foobar", m.DigString("foo", "bar")) + }) - // Overwrite foo.bar with a new mapping - m.DigMapping("foo", "bar")["baz"] = "hello" - assert.Equal(t, "hello", m.Dig("foo", "bar", "baz")) + t.Run("overwrite mapping", func(t *testing.T) { + m.DigMapping("foo", "bar")["baz"] = "hello" + mustEqualString(t, "hello", m.DigString("foo", "bar", "baz")) + mustBeNil(t, m.Dig("foo", "bar", "dog")) + }) } func TestDup(t *testing.T) { @@ -69,37 +101,36 @@ func TestDup(t *testing.T) { dup := m.Dup() - m.DigMapping("foo")["bar"] = "barbar" - arr := m.Dig("array").([]string) - arr = append(arr, "world") - m["array"] = arr - - ma := m["mappingarray"].([]dig.Mapping) - maa := ma[0] - maa["bar"] = "barbar" - - assert.Equal(t, "barbar", m.Dig("foo", "bar")) - assert.Equal(t, "foobar", dup.Dig("foo", "bar")) - - a := m.Dig("array").([]string) - b := dup.Dig("array").([]string) - - assert.Len(t, a, 2) - assert.Len(t, b, 1) - - am := m.Dig("mappingarray").([]dig.Mapping) - bm := dup.Dig("mappingarray").([]dig.Mapping) - - assert.Equal(t, "barbar", am[0]["bar"]) - assert.Equal(t, "foobar", bm[0]["bar"]) + t.Run("modifying clone's values should not modify original", func(t *testing.T) { + m.DigMapping("foo")["bar"] = "barbar" + mustEqualString(t, "foobar", dup.DigString("foo", "bar")) + mustEqualString(t, "barbar", m.DigString("foo", "bar")) + }) + + t.Run("modifying a cloned slice should not modify original", func(t *testing.T) { + arr := m.Dig("array").([]string) + arr = append(arr, "world") + m["array"] = arr + + ma := m["mappingarray"].([]dig.Mapping) + maa := ma[0] + maa["bar"] = "barbar" + + mustEqual(t, 1, len(dup.Dig("array").([]string))) + mustEqual(t, 2, len(m.Dig("array").([]string))) + + am := m.Dig("mappingarray").([]dig.Mapping) + bm := dup.Dig("mappingarray").([]dig.Mapping) + mustEqualString(t, "barbar", am[0]["bar"].(string)) + mustEqualString(t, "foobar", bm[0]["bar"].(string)) + }) } func TestUnmarshalYamlWithNil(t *testing.T) { - data := `foo: null` + data := []byte(`{"foo": null}`) var m dig.Mapping - err := yaml.Unmarshal([]byte(data), &m) - assert.NoError(t, err) - assert.Nil(t, m.Dig("foo")) + mustBeNil(t, json.Unmarshal(data, &m)) + mustBeNil(t, m.Dig("foo")) } func ExampleMapping_Dig() {