1 package asyncassertion_test
7 . "github.com/onsi/ginkgo"
8 . "github.com/onsi/gomega"
9 . "github.com/onsi/gomega/internal/asyncassertion"
12 var _ = Describe("Async Assertion", func() {
18 var fakeFailHandler = func(message string, skip ...int) {
19 failureMessage = message
28 Describe("Eventually", func() {
29 Context("the positive case", func() {
30 It("should poll the function and matcher", func() {
32 a := New(AsyncAssertionTypeEventually, func() int {
35 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
37 a.Should(BeNumerically("==", 5))
38 Ω(failureMessage).Should(BeZero())
41 It("should continue when the matcher errors", func() {
43 a := New(AsyncAssertionTypeEventually, func() interface{} {
46 return "not-a-number" //this should cause the matcher to error
49 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
51 a.Should(BeNumerically("==", 5), "My description %d", 2)
53 Ω(failureMessage).Should(ContainSubstring("Timed out after"))
54 Ω(failureMessage).Should(ContainSubstring("My description 2"))
55 Ω(callerSkip).Should(Equal(4))
58 It("should be able to timeout", func() {
60 a := New(AsyncAssertionTypeEventually, func() int {
63 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
65 a.Should(BeNumerically(">", 100), "My description %d", 2)
67 Ω(counter).Should(BeNumerically(">", 8))
68 Ω(counter).Should(BeNumerically("<=", 10))
69 Ω(failureMessage).Should(ContainSubstring("Timed out after"))
70 Ω(failureMessage).Should(MatchRegexp(`\<int\>: \d`), "Should pass the correct value to the matcher message formatter.")
71 Ω(failureMessage).Should(ContainSubstring("My description 2"))
72 Ω(callerSkip).Should(Equal(4))
76 Context("the negative case", func() {
77 It("should poll the function and matcher", func() {
79 a := New(AsyncAssertionTypeEventually, func() int {
82 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
84 a.ShouldNot(BeNumerically("<", 3))
86 Ω(counter).Should(Equal(3))
87 Ω(failureMessage).Should(BeZero())
90 It("should timeout when the matcher errors", func() {
91 a := New(AsyncAssertionTypeEventually, func() interface{} {
92 return 0 //this should cause the matcher to error
93 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
95 a.ShouldNot(HaveLen(0), "My description %d", 2)
97 Ω(failureMessage).Should(ContainSubstring("Timed out after"))
98 Ω(failureMessage).Should(ContainSubstring("Error:"))
99 Ω(failureMessage).Should(ContainSubstring("My description 2"))
100 Ω(callerSkip).Should(Equal(4))
103 It("should be able to timeout", func() {
104 a := New(AsyncAssertionTypeEventually, func() int {
106 }, fakeFailHandler, time.Duration(0.1*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
108 a.ShouldNot(Equal(0), "My description %d", 2)
110 Ω(failureMessage).Should(ContainSubstring("Timed out after"))
111 Ω(failureMessage).Should(ContainSubstring("<int>: 0"), "Should pass the correct value to the matcher message formatter.")
112 Ω(failureMessage).Should(ContainSubstring("My description 2"))
113 Ω(callerSkip).Should(Equal(4))
117 Context("with a function that returns multiple values", func() {
118 It("should eventually succeed if the additional arguments are nil", func() {
120 Eventually(func() (int, error) {
126 It("should eventually timeout if the additional arguments are not nil", func() {
128 a := New(AsyncAssertionTypeEventually, func() (int, error) {
130 return i, errors.New("bam")
131 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
134 Ω(failureMessage).Should(ContainSubstring("Timed out after"))
135 Ω(failureMessage).Should(ContainSubstring("Error:"))
136 Ω(failureMessage).Should(ContainSubstring("bam"))
137 Ω(callerSkip).Should(Equal(4))
141 Context("Making an assertion without a registered fail handler", func() {
142 It("should panic", func() {
145 RegisterFailHandler(Fail)
147 Fail("expected a panic to have occurred")
151 RegisterFailHandler(nil)
152 c := make(chan bool, 1)
154 Eventually(c).Should(Receive())
159 Describe("Consistently", func() {
160 Describe("The positive case", func() {
161 Context("when the matcher consistently passes for the duration", func() {
162 It("should pass", func() {
164 a := New(AsyncAssertionTypeConsistently, func() string {
167 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
169 a.Should(Equal("foo"))
170 Ω(calls).Should(BeNumerically(">", 8))
171 Ω(calls).Should(BeNumerically("<=", 10))
172 Ω(failureMessage).Should(BeZero())
176 Context("when the matcher fails at some point", func() {
177 It("should fail", func() {
179 a := New(AsyncAssertionTypeConsistently, func() interface{} {
185 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
187 a.Should(Equal("foo"))
188 Ω(failureMessage).Should(ContainSubstring("to equal"))
189 Ω(callerSkip).Should(Equal(4))
193 Context("when the matcher errors at some point", func() {
194 It("should fail", func() {
196 a := New(AsyncAssertionTypeConsistently, func() interface{} {
201 return []int{1, 2, 3}
202 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
205 Ω(failureMessage).Should(ContainSubstring("HaveLen matcher expects"))
206 Ω(callerSkip).Should(Equal(4))
211 Describe("The negative case", func() {
212 Context("when the matcher consistently passes for the duration", func() {
213 It("should pass", func() {
215 a := New(AsyncAssertionTypeConsistently, c, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
217 a.ShouldNot(Receive())
218 Ω(failureMessage).Should(BeZero())
222 Context("when the matcher fails at some point", func() {
223 It("should fail", func() {
226 time.Sleep(time.Duration(100 * time.Millisecond))
230 a := New(AsyncAssertionTypeConsistently, c, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
232 a.ShouldNot(Receive())
233 Ω(failureMessage).Should(ContainSubstring("not to receive anything"))
237 Context("when the matcher errors at some point", func() {
238 It("should fail", func() {
240 a := New(AsyncAssertionTypeConsistently, func() interface{} {
243 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
245 a.ShouldNot(BeNumerically(">", 5))
246 Ω(failureMessage).Should(ContainSubstring("not to be >"))
247 Ω(callerSkip).Should(Equal(4))
252 Context("with a function that returns multiple values", func() {
253 It("should consistently succeed if the additional arguments are nil", func() {
255 Consistently(func() (int, error) {
258 }).Should(BeNumerically(">=", 2))
261 It("should eventually timeout if the additional arguments are not nil", func() {
263 a := New(AsyncAssertionTypeEventually, func() (int, error) {
265 return i, errors.New("bam")
266 }, fakeFailHandler, time.Duration(0.2*float64(time.Second)), time.Duration(0.02*float64(time.Second)), 1)
267 a.Should(BeNumerically(">=", 2))
269 Ω(failureMessage).Should(ContainSubstring("Error:"))
270 Ω(failureMessage).Should(ContainSubstring("bam"))
271 Ω(callerSkip).Should(Equal(4))
275 Context("Making an assertion without a registered fail handler", func() {
276 It("should panic", func() {
279 RegisterFailHandler(Fail)
281 Fail("expected a panic to have occurred")
285 RegisterFailHandler(nil)
287 Consistently(c).ShouldNot(Receive())
292 Context("when passed a function with the wrong # or arguments & returns", func() {
293 It("should panic", func() {
295 New(AsyncAssertionTypeEventually, func() {}, fakeFailHandler, 0, 0, 1)
299 New(AsyncAssertionTypeEventually, func(a string) int { return 0 }, fakeFailHandler, 0, 0, 1)
303 New(AsyncAssertionTypeEventually, func() int { return 0 }, fakeFailHandler, 0, 0, 1)
304 }).ShouldNot(Panic())
307 New(AsyncAssertionTypeEventually, func() (int, error) { return 0, nil }, fakeFailHandler, 0, 0, 1)
308 }).ShouldNot(Panic())
312 Describe("bailing early", func() {
313 Context("when actual is a value", func() {
314 It("Eventually should bail out and fail early if the matcher says to", func() {
319 failures := InterceptGomegaFailures(func() {
320 Eventually(c, 0.1).Should(Receive())
322 Ω(time.Since(t)).Should(BeNumerically("<", 90*time.Millisecond))
324 Ω(failures).Should(HaveLen(1))
328 Context("when actual is a function", func() {
329 It("should never bail early", func() {
334 failures := InterceptGomegaFailures(func() {
335 Eventually(func() chan bool {
337 }, 0.1).Should(Receive())
339 Ω(time.Since(t)).Should(BeNumerically(">=", 90*time.Millisecond))
341 Ω(failures).Should(HaveLen(1))