Skip to content

Commit bba25dd

Browse files
authored
Merge pull request #128 from maxatome/fix-iface-nil
fix: reflect.Interface containing nil
2 parents d7d9068 + e6b86a4 commit bba25dd

4 files changed

Lines changed: 41 additions & 23 deletions

File tree

td/equal.go

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -116,19 +116,19 @@ func isCustomEqual(a, b reflect.Value) (bool, bool) {
116116
}
117117

118118
func deepValueEqual(ctx ctxerr.Context, got, expected reflect.Value) (err *ctxerr.Error) {
119+
// "got" must not implement testDeeper
120+
if got.IsValid() && got.Type().Implements(testDeeper) {
121+
panic(color.Bad("Found a TestDeep operator in got param, " +
122+
"can only use it in expected one!"))
123+
}
124+
119125
if !got.IsValid() || !expected.IsValid() {
120126
if got.IsValid() == expected.IsValid() {
121127
return
122128
}
123129
return nilHandler(ctx, got, expected)
124130
}
125131

126-
// "got" must not implement testDeeper
127-
if got.Type().Implements(testDeeper) {
128-
panic(color.Bad("Found a TestDeep operator in got param, " +
129-
"can only use it in expected one!"))
130-
}
131-
132132
// Check if a Smuggle hook matches got type
133133
if handled, e := ctx.Hooks.Smuggle(&got); handled {
134134
if e != nil {
@@ -308,19 +308,6 @@ func deepValueEqual(ctx ctxerr.Context, got, expected reflect.Value) (err *ctxer
308308
return
309309

310310
case reflect.Interface:
311-
if got.IsNil() || expected.IsNil() {
312-
if got.IsNil() == expected.IsNil() {
313-
return
314-
}
315-
if ctx.BooleanError {
316-
return ctxerr.BooleanError
317-
}
318-
return ctx.CollectError(&ctxerr.Error{
319-
Message: "nil interface",
320-
Got: isNilStr(got.IsNil()),
321-
Expected: isNilStr(expected.IsNil()),
322-
})
323-
}
324311
return deepValueEqual(ctx, got.Elem(), expected.Elem())
325312

326313
case reflect.Ptr:

td/equal_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,17 +234,17 @@ func TestEqualInterface(t *testing.T) {
234234

235235
checkError(t, []interface{}{1, nil}, []interface{}{1, "foo"},
236236
expectedError{
237-
Message: mustBe("nil interface"),
237+
Message: mustBe("values differ"),
238238
Path: mustBe("DATA[1]"),
239239
Got: mustBe("nil"),
240-
Expected: mustBe("not nil"),
240+
Expected: mustBe(`"foo"`),
241241
})
242242

243243
checkError(t, []interface{}{1, "foo"}, []interface{}{1, nil},
244244
expectedError{
245-
Message: mustBe("nil interface"),
245+
Message: mustBe("values differ"),
246246
Path: mustBe("DATA[1]"),
247-
Got: mustBe("not nil"),
247+
Got: mustBe(`"foo"`),
248248
Expected: mustBe("nil"),
249249
})
250250

td/td_json_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package td_test
88

99
import (
10+
"encoding/json"
1011
"errors"
1112
"io/ioutil"
1213
"os"
@@ -116,6 +117,32 @@ func TestJSON(t *testing.T) {
116117
td.Tag("age", td.Between(40, 45)),
117118
td.Tag("name", td.Re(`^Bob`))))
118119

120+
//
121+
// nil++
122+
checkOK(t, nil, td.JSON(`$1`, nil))
123+
checkOK(t, (*int)(nil), td.JSON(`$1`, td.Nil()))
124+
125+
checkOK(t, nil, td.JSON(`$x`, td.Tag("x", nil)))
126+
checkOK(t, (*int)(nil), td.JSON(`$x`, td.Tag("x", nil)))
127+
128+
checkOK(t, json.RawMessage(`{"foo": null}`), td.JSON(`{"foo": null}`))
129+
130+
checkOK(t,
131+
json.RawMessage(`{"foo": null}`),
132+
td.JSON(`{"foo": $1}`, nil))
133+
134+
checkOK(t,
135+
json.RawMessage(`{"foo": null}`),
136+
td.JSON(`{"foo": $1}`, td.Nil()))
137+
138+
checkOK(t,
139+
json.RawMessage(`{"foo": null}`),
140+
td.JSON(`{"foo": $x}`, td.Tag("x", nil)))
141+
142+
checkOK(t,
143+
json.RawMessage(`{"foo": null}`),
144+
td.JSON(`{"foo": $x}`, td.Tag("x", td.Nil())))
145+
119146
//
120147
// Loading a file
121148
tmpDir, err := ioutil.TempDir("", "")

td/td_nil_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ func TestNil(t *testing.T) {
2222
checkOK(t, (*int)(nil), td.Nil())
2323
checkOK(t, (chan int)(nil), td.Nil())
2424
checkOK(t, nil, td.Nil())
25+
checkOK(t,
26+
map[string]interface{}{"foo": nil},
27+
map[string]interface{}{"foo": td.Nil()},
28+
)
2529

2630
var got fmt.Stringer = (*bytes.Buffer)(nil)
2731
checkOK(t, got, td.Nil())

0 commit comments

Comments
 (0)