...
1 package matchers_test
2
3 import (
4 "errors"
5
6 . "github.com/onsi/ginkgo/v2"
7 . "github.com/onsi/gomega"
8 )
9
10 var _ = Describe("SatisfyMatcher", func() {
11
12 var isEven = func(x int) bool { return x%2 == 0 }
13
14 Context("Panic if predicate is invalid", func() {
15 panicsWithPredicate := func(predicate interface{}) {
16 Expect(func() { Satisfy(predicate) }).WithOffset(1).To(Panic())
17 }
18 It("nil", func() {
19 panicsWithPredicate(nil)
20 })
21 Context("Invalid number of args, but correct return value count", func() {
22 It("zero", func() {
23 panicsWithPredicate(func() int { return 5 })
24 })
25 It("two", func() {
26 panicsWithPredicate(func(i, j int) int { return 5 })
27 })
28 })
29 Context("Invalid return types, but correct number of arguments", func() {
30 It("zero", func() {
31 panicsWithPredicate(func(i int) {})
32 })
33 It("two", func() {
34 panicsWithPredicate(func(i int) (int, int) { return 5, 6 })
35 })
36 It("invalid type", func() {
37 panicsWithPredicate(func(i int) string { return "" })
38 })
39 })
40 })
41
42 When("the actual value is incompatible", func() {
43 It("fails to pass int to func(string)", func() {
44 actual, predicate := int(0), func(string) bool { return false }
45 success, err := Satisfy(predicate).Match(actual)
46 Expect(success).To(BeFalse())
47 Expect(err).To(HaveOccurred())
48 Expect(err.Error()).To(ContainSubstring("expects 'string'"))
49 Expect(err.Error()).To(ContainSubstring("have 'int'"))
50 })
51
52 It("fails to pass string to func(interface)", func() {
53 actual, predicate := "bang", func(error) bool { return false }
54 success, err := Satisfy(predicate).Match(actual)
55 Expect(success).To(BeFalse())
56 Expect(err).To(HaveOccurred())
57 Expect(err.Error()).To(ContainSubstring("expects 'error'"))
58 Expect(err.Error()).To(ContainSubstring("have 'string'"))
59 })
60
61 It("fails to pass nil interface to func(int)", func() {
62 actual, predicate := error(nil), func(int) bool { return false }
63 success, err := Satisfy(predicate).Match(actual)
64 Expect(success).To(BeFalse())
65 Expect(err).To(HaveOccurred())
66 Expect(err.Error()).To(ContainSubstring("expects 'int'"))
67 Expect(err.Error()).To(ContainSubstring("have '<nil>'"))
68 })
69
70 It("fails to pass nil interface to func(pointer)", func() {
71 actual, predicate := error(nil), func(*string) bool { return false }
72 success, err := Satisfy(predicate).Match(actual)
73 Expect(success).To(BeFalse())
74 Expect(err).To(HaveOccurred())
75 Expect(err.Error()).To(ContainSubstring("expects '*string'"))
76 Expect(err.Error()).To(ContainSubstring("have '<nil>'"))
77 })
78 })
79
80 It("works with positive cases", func() {
81 Expect(2).To(Satisfy(isEven))
82
83
84 takesError := func(error) bool { return true }
85 Expect(nil).To(Satisfy(takesError), "handles nil actual values")
86 Expect(errors.New("abc")).To(Satisfy(takesError))
87 })
88
89 It("works with negative cases", func() {
90 Expect(1).ToNot(Satisfy(isEven))
91 })
92
93 Context("failure messages", func() {
94 When("match fails", func() {
95 It("gives a descriptive message", func() {
96 m := Satisfy(isEven)
97 Expect(m.Match(1)).To(BeFalse())
98 Expect(m.FailureMessage(1)).To(ContainSubstring("Expected\n <int>: 1\nto satisfy predicate\n <func(int) bool>: "))
99 })
100 })
101
102 When("match succeeds, but expected it to fail", func() {
103 It("gives a descriptive message", func() {
104 m := Not(Satisfy(isEven))
105 Expect(m.Match(2)).To(BeFalse())
106 Expect(m.FailureMessage(2)).To(ContainSubstring("Expected\n <int>: 2\nto not satisfy predicate\n <func(int) bool>: "))
107 })
108 })
109
110 Context("actual value is incompatible with predicate's argument type", func() {
111 It("gracefully fails", func() {
112 m := Satisfy(isEven)
113 result, err := m.Match("hi")
114 Expect(result).To(BeFalse())
115 Expect(err).To(MatchError("predicate expects 'int' but we have 'string'"))
116 })
117 })
118 })
119 })
120
View as plain text