Skip to content

Commit f633800

Browse files
authored
introduces Eventually.Within.ProbeEvery with tests and documentation (#591)
1 parent fb586b3 commit f633800

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

docs/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,11 @@ The first optional argument is the timeout (which defaults to 1s), the second is
252252

253253
> As with synchronous assertions, you can annotate asynchronous assertions by passing either a format string and optional inputs or a function of type `func() string` after the `GomegaMatcher`.
254254
255-
Alternatively, the timeout and polling interval can also be specified by chaining `WithTimeout` and `WithPolling` to `Eventually`:
255+
Alternatively, the timeout and polling interval can also be specified by chaining `Within` and `ProbeEvery` or `WithTimeout` and `WithPolling` to `Eventually`:
256256

257257
```go
258258
Eventually(ACTUAL).WithTimeout(TIMEOUT).WithPolling(POLLING_INTERVAL).Should(MATCHER)
259+
Eventually(ACTUAL).Within(TIMEOUT).ProbeEvery(POLLING_INTERVAL).Should(MATCHER)
259260
```
260261

261262
Eventually works with any Gomega compatible matcher and supports making assertions against three categories of `ACTUAL` value:

internal/async_assertion.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ func (assertion *AsyncAssertion) WithPolling(interval time.Duration) types.Async
102102
return assertion
103103
}
104104

105+
func (assertion *AsyncAssertion) Within(timeout time.Duration) types.AsyncAssertion {
106+
assertion.timeoutInterval = timeout
107+
return assertion
108+
}
109+
110+
func (assertion *AsyncAssertion) ProbeEvery(interval time.Duration) types.AsyncAssertion {
111+
assertion.pollingInterval = interval
112+
return assertion
113+
}
114+
105115
func (assertion *AsyncAssertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
106116
assertion.g.THelper()
107117
vetOptionalDescription("Asynchronous assertion", optionalDescription...)

internal/async_assertion_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,26 @@ var _ = Describe("Asynchronous Assertions", func() {
5959
Ω(ig.FailureMessage).Should(ContainSubstring("positive: no match"))
6060
Ω(ig.FailureSkip).Should(Equal([]int{3}))
6161
})
62+
63+
It("maps Within() correctly to timeout and polling intervals", func() {
64+
counter := 0
65+
ig.G.Eventually(func() bool {
66+
counter++
67+
return false
68+
}).WithTimeout(0).WithPolling(20 * time.Millisecond).Within(200 * time.Millisecond).Should(BeTrue())
69+
Ω(counter).Should(BeNumerically(">", 2))
70+
Ω(counter).Should(BeNumerically("<", 20))
71+
72+
counter = 0
73+
ig.G.Eventually(func() bool {
74+
counter++
75+
return false
76+
}).WithTimeout(0).WithPolling(0). // first zero intervals, then set them
77+
Within(200 * time.Millisecond).ProbeEvery(20 * time.Millisecond).
78+
Should(BeTrue())
79+
Ω(counter).Should(BeNumerically(">", 2))
80+
Ω(counter).Should(BeNumerically("<", 20))
81+
})
6282
})
6383

6484
Context("the negative case", func() {
@@ -309,7 +329,7 @@ var _ = Describe("Asynchronous Assertions", func() {
309329
})
310330
})
311331

312-
Context("when passed a function that takes no arguments and returns mutliple values", func() {
332+
Context("when passed a function that takes no arguments and returns multiple values", func() {
313333
Context("with Eventually", func() {
314334
It("polls the function until the first returned value satisfies the matcher _and_ all additional values are zero", func() {
315335
counter, s, f, err := 0, "hi", Foo{Bar: "hi"}, errors.New("hi")

types/types.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66

77
type GomegaFailHandler func(message string, callerSkip ...int)
88

9-
//A simple *testing.T interface wrapper
9+
// A simple *testing.T interface wrapper
1010
type GomegaTestingT interface {
1111
Helper()
1212
Fatalf(format string, args ...interface{})
@@ -30,9 +30,9 @@ type Gomega interface {
3030
SetDefaultConsistentlyPollingInterval(time.Duration)
3131
}
3232

33-
//All Gomega matchers must implement the GomegaMatcher interface
33+
// All Gomega matchers must implement the GomegaMatcher interface
3434
//
35-
//For details on writing custom matchers, check out: http://onsi.github.io/gomega/#adding-your-own-matchers
35+
// For details on writing custom matchers, check out: http://onsi.github.io/gomega/#adding-your-own-matchers
3636
type GomegaMatcher interface {
3737
Match(actual interface{}) (success bool, err error)
3838
FailureMessage(actual interface{}) (message string)
@@ -70,6 +70,8 @@ type AsyncAssertion interface {
7070
WithOffset(offset int) AsyncAssertion
7171
WithTimeout(interval time.Duration) AsyncAssertion
7272
WithPolling(interval time.Duration) AsyncAssertion
73+
Within(timeout time.Duration) AsyncAssertion
74+
ProbeEvery(interval time.Duration) AsyncAssertion
7375
}
7476

7577
// Assertions are returned by Ω and Expect and enable assertions against Gomega matchers

0 commit comments

Comments
 (0)