Skip to content

Commit

Permalink
Allow collections matchers to work correctly when expected has nil el…
Browse files Browse the repository at this point in the history
…ements
  • Loading branch information
onsi committed Mar 30, 2023
1 parent 67b869d commit 60e7cf3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
29 changes: 19 additions & 10 deletions matchers/consist_of.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ func neighbours(value, matcher interface{}) (bool, error) {

func equalMatchersToElements(matchers []interface{}) (elements []interface{}) {
for _, matcher := range matchers {
equalMatcher, ok := matcher.(*EqualMatcher)
if ok {
matcher = equalMatcher.Expected
if equalMatcher, ok := matcher.(*EqualMatcher); ok {
elements = append(elements, equalMatcher.Expected)
} else if _, ok := matcher.(*BeNilMatcher); ok {
elements = append(elements, nil)
} else {
elements = append(elements, matcher)
}
elements = append(elements, matcher)
}
return
}
Expand All @@ -72,11 +74,13 @@ func flatten(elems []interface{}) []interface{} {

func matchers(expectedElems []interface{}) (matchers []interface{}) {
for _, e := range flatten(expectedElems) {
matcher, isMatcher := e.(omegaMatcher)
if !isMatcher {
matcher = &EqualMatcher{Expected: e}
if e == nil {
matchers = append(matchers, &BeNilMatcher{})
} else if matcher, isMatcher := e.(omegaMatcher); isMatcher {
matchers = append(matchers, matcher)
} else {
matchers = append(matchers, &EqualMatcher{Expected: e})
}
matchers = append(matchers, matcher)
}
return
}
Expand All @@ -89,9 +93,14 @@ func presentable(elems []interface{}) interface{} {
}

sv := reflect.ValueOf(elems)
tt := sv.Index(0).Elem().Type()
firstEl := sv.Index(0)
if firstEl.IsNil() {
return elems
}
tt := firstEl.Elem().Type()
for i := 1; i < sv.Len(); i++ {
if sv.Index(i).Elem().Type() != tt {
el := sv.Index(i)
if el.IsNil() || (sv.Index(i).Elem().Type() != tt) {
return elems
}
}
Expand Down
18 changes: 18 additions & 0 deletions matchers/consist_of_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ var _ = Describe("ConsistOf", func() {
})
})

When("provided an expectation that has a nil value", func() {
It("should match without failure", func() {
Expect([]any{1, "two", nil}).Should(ConsistOf([]any{nil, 1, "two"}))
Expect([]any{1, "two", "nil", nil}).ShouldNot(ConsistOf([]any{nil, nil, 1, "two"}))
})
})

Describe("FailureMessage", func() {
When("actual contains an extra element", func() {
It("prints the extra element", func() {
Expand All @@ -97,6 +104,17 @@ var _ = Describe("ConsistOf", func() {
})
})

When("actual misses a nil element", func() {
It("prints the missing element", func() {
failures := InterceptGomegaFailures(func() {
Expect([]int{2}).Should(ConsistOf(nil, 2))
})

expected := "Expected\n.*\\[2\\]\nto consist of\n.*\\[nil, <int>2\\]\nthe missing elements were\n.*\\[nil\\]"
Expect(failures).To(ConsistOf(MatchRegexp(expected)))
})
})

When("actual contains an extra element and misses an element", func() {
It("prints both the extra and missing element", func() {
failures := InterceptGomegaFailures(func() {
Expand Down
4 changes: 4 additions & 0 deletions matchers/have_exact_elements_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ var _ = Describe("HaveExactElements", func() {
Expect([]string{"foo", "bar"}).ShouldNot(HaveExactElements("foo", "bar", "baz"))
Expect([]string{"foo", "bar"}).ShouldNot(HaveExactElements("bar", "foo"))
})

It("should work with arbitrary types, including nil", func() {
Expect([]any{"foo", nil, "bar", 17, true, []string{"hi", "there"}}).Should(HaveExactElements("foo", nil, "bar", 17, true, []string{"hi", "there"}))
})
})
Context("with an array", func() {
It("should do the right thing", func() {
Expand Down

0 comments on commit 60e7cf3

Please sign in to comment.