From 5f9ab56069f604c3ebe0062a9226f1e2b5da9437 Mon Sep 17 00:00:00 2001 From: George Blue Date: Tue, 2 Feb 2021 15:05:31 +0000 Subject: [PATCH] fix: print value type for interface{} containers When a value is contained in an interface{} we should show the type of the value as well as the interface{} type Consider the test: Expect([]interface{}{1}).To(Equal([]interface{}{uint(1)})) Previous message: Expected <[]interface {} | len:1, cap:1>: [1] to equal <[]interface {} | len:1, cap:1>: [1] New message: Expected <[]interface {} | len:1, cap:1>: [1] to equal <[]interface {} | len:1, cap:1>: [1] By showing the type, it's much easier to work out what is going on --- format/format.go | 6 +++++- format/format_test.go | 24 ++++++++++++++++++++--- matchers/consist_of_test.go | 4 ++-- matchers/contain_elements_matcher_test.go | 4 ++-- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/format/format.go b/format/format.go index 128e7e060..4f7462ab1 100644 --- a/format/format.go +++ b/format/format.go @@ -271,7 +271,7 @@ func formatValue(value reflect.Value, indentation uint) string { } return formatStruct(value, indentation) case reflect.Interface: - return formatValue(value.Elem(), indentation) + return formatInterface(value, indentation) default: if value.CanInterface() { return fmt.Sprintf("%#v", value.Interface()) @@ -366,6 +366,10 @@ func formatStruct(v reflect.Value, indentation uint) string { return fmt.Sprintf("{%s}", strings.Join(result, ", ")) } +func formatInterface(v reflect.Value, indentation uint) string { + return fmt.Sprintf("<%s>%s", formatType(v.Elem()), formatValue(v.Elem(), indentation)) +} + func isNilValue(a reflect.Value) bool { switch a.Kind() { case reflect.Invalid: diff --git a/format/format_test.go b/format/format_test.go index 42a363a5b..8f20767e8 100644 --- a/format/format_test.go +++ b/format/format_test.go @@ -95,7 +95,7 @@ var _ = Describe("Format", func() { for i := range arr { arr[i] = entriesSwitch } - return "{" + strings.Join(arr, ", ") + "}" + return "{\\s*" + strings.Join(arr, ",\\s* ") + ",?\\s*}" } Describe("Message", func() { @@ -526,6 +526,24 @@ var _ = Describe("Format", func() { }) }) + Describe("formatting nested interface{} types", func() { + It("should print out the types of the container and value", func() { + Expect(Object([]interface{}{"foo"}, 1)). + To(match("[]interface {} | len:1, cap:1", `["foo"]`)) + + Expect(Object(map[string]interface{}{"foo": true}, 1)). + To(match("map[string]interface {} | len:1", `{"foo": true}`)) + + Expect(Object(struct{ A interface{} }{A: 1}, 1)). + To(match("struct { A interface {} }", "{A: 1}")) + + v := struct{ A interface{} }{A: struct{ B string }{B: "foo"}} + Expect(Object(v, 1)).To(match(`struct { A interface {} }`, `{ + A: {B: "foo"}, + }`)) + }) + }) + Describe("formatting times", func() { It("should format time as RFC3339", func() { t := time.Date(2016, 10, 31, 9, 57, 23, 12345, time.UTC) @@ -574,7 +592,7 @@ var _ = Describe("Format", func() { byteArrValue: \[17, 20, 32\], mapValue: %s, structValue: {Exported: "exported"}, - interfaceValue: {"a key": 17}, + interfaceValue: {"a key": 17}, }`, s.chanValue, s.funcValue, hashMatchingRegexp(`"a key": 20`, `"b key": 30`)) Expect(Object(s, 1)).Should(matchRegexp(`format_test\.SecretiveStruct`, expected)) @@ -590,7 +608,7 @@ var _ = Describe("Format", func() { outerHash["integer"] = 2 outerHash["map"] = innerHash - expected := hashMatchingRegexp(`"integer": 2`, `"map": {"inner": 3}`) + expected := hashMatchingRegexp(`"integer": 2`, `"map": {"inner": 3}`) Expect(Object(outerHash, 1)).Should(matchRegexp(`map\[string\]interface {} \| len:2`, expected)) }) }) diff --git a/matchers/consist_of_test.go b/matchers/consist_of_test.go index 0e71f92e4..e1d8d8cd9 100644 --- a/matchers/consist_of_test.go +++ b/matchers/consist_of_test.go @@ -160,7 +160,7 @@ the extra elements were }) expected := `to consist of -\s*<\[\]interface {} \| len:2, cap:2>: \[1, "C"\] +\s*<\[\]interface {} \| len:2, cap:2>: \[1, "C"\] the missing elements were \s*<\[\]string \| len:1, cap:1>: \["C"\] the extra elements were @@ -173,7 +173,7 @@ the extra elements were Expect([]interface{}{1, "B"}).NotTo(ConsistOf(1, "B")) }) - expected := `not to consist of\n\s*<\[\]interface {} \| len:2, cap:2>: \[1, "B"\]` + expected := `not to consist of\n\s*<\[\]interface {} \| len:2, cap:2>: \[1, "B"\]` Expect(failures).To(ConsistOf(MatchRegexp(expected))) }) }) diff --git a/matchers/contain_elements_matcher_test.go b/matchers/contain_elements_matcher_test.go index 2fcef0d8d..0ab187bc6 100644 --- a/matchers/contain_elements_matcher_test.go +++ b/matchers/contain_elements_matcher_test.go @@ -133,7 +133,7 @@ the missing elements were }) expected := `to contain elements -\s*<\[\]interface {} \| len:2, cap:2>: \[1, "C"\] +\s*<\[\]interface {} \| len:2, cap:2>: \[1, "C"\] the missing elements were \s*<\[\]string \| len:1, cap:1>: \["C"\]` Expect(failures).To(ConsistOf(MatchRegexp(expected))) @@ -144,7 +144,7 @@ the missing elements were Expect([]interface{}{1, "B"}).NotTo(ContainElements(1, "B")) }) - expected := `not to contain elements\n\s*<\[\]interface {} \| len:2, cap:2>: \[1, "B"\]` + expected := `not to contain elements\n\s*<\[\]interface {} \| len:2, cap:2>: \[1, "B"\]` Expect(failures).To(ConsistOf(MatchRegexp(expected))) }) })