Skip to content

Commit

Permalink
resolves #696: make HaveField great on pointer receivers given only a…
Browse files Browse the repository at this point in the history
… non-addressable value

Signed-off-by: thediveo <thediveo@gmx.eu>
  • Loading branch information
thediveo authored and onsi committed Dec 6, 2024
1 parent f1ff459 commit 4feb9d7
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
7 changes: 6 additions & 1 deletion matchers/have_field.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ func extractField(actual interface{}, field string, matchername string) (any, er
extractedValue = actualValue.Addr().MethodByName(strings.TrimSuffix(fields[0], "()"))
}
if extractedValue == (reflect.Value{}) {
return nil, missingFieldError(fmt.Sprintf("%s could not find method named '%s' in struct of type %T.", matchername, fields[0], actual))
ptr := reflect.New(actualValue.Type())
ptr.Elem().Set(actualValue)
extractedValue = ptr.MethodByName(strings.TrimSuffix(fields[0], "()"))
if extractedValue == (reflect.Value{}) {
return nil, missingFieldError(fmt.Sprintf("%s could not find method named '%s' in struct of type %T.", matchername, fields[0], actual))
}
}
t := extractedValue.Type()
if t.NumIn() != 0 || t.NumOut() != 1 {
Expand Down
10 changes: 5 additions & 5 deletions matchers/have_field_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,23 +162,23 @@ var _ = Describe("HaveField", func() {
})

Describe("receiver lookup", func() {
DescribeTable("(pointer) receiver lookup works",
DescribeTable("(pointer) receiver lookup on book pointer works",
func(field string, expected interface{}) {
Ω(&book).Should(HaveField(field, expected))
},
Entry("non-pointer receiver", "ReceiverTitle()", "Les Miserables"),
Entry("pointer receiver", "PointerReceiverTitle()", "Les Miserables"),
)

It("correctly looks up a pointer receiver on a book value", func() {
Ω(book).Should(HaveField("PointerReceiverTitle()", "Les Miserables"))
})

It("correctly fails", func() {
matcher := HaveField("ReceiverTitle()", "Les Miserables")
answer := struct{}{}
Ω(matcher.Match(answer)).Error().Should(MatchError(
"HaveField could not find method named 'ReceiverTitle()' in struct of type struct {}."))

matcher = HaveField("PointerReceiverTitle()", "Les Miserables")
Ω(matcher.Match(book)).Error().Should(MatchError(
"HaveField could not find method named 'PointerReceiverTitle()' in struct of type matchers_test.Book."))
})
})

Expand Down

0 comments on commit 4feb9d7

Please sign in to comment.