From 18a4723c499b94a58224e9a93d79d935dc1359d1 Mon Sep 17 00:00:00 2001 From: TheDiveO Date: Tue, 2 Nov 2021 19:27:08 +0100 Subject: [PATCH] separate out offsets and timeouts (#478) --- gomega_dsl.go | 15 +++++- internal/assertion.go | 5 ++ internal/async_assertion.go | 15 ++++++ internal/async_assertion_test.go | 90 ++++++++++++++++---------------- internal/dsl_test.go | 4 +- internal/gomega_test.go | 4 +- matchers/satisfy_matcher_test.go | 2 +- matchers/with_transform_test.go | 2 +- types/types.go | 6 +++ 9 files changed, 91 insertions(+), 52 deletions(-) diff --git a/gomega_dsl.go b/gomega_dsl.go index 84775142c..492090b6e 100644 --- a/gomega_dsl.go +++ b/gomega_dsl.go @@ -204,7 +204,8 @@ func Expect(actual interface{}, extra ...interface{}) Assertion { // ExpectWithOffset(1, "foo").To(Equal("foo")) // // Unlike `Expect` and `Ω`, `ExpectWithOffset` takes an additional integer argument -// that is used to modify the call-stack offset when computing line numbers. +// that is used to modify the call-stack offset when computing line numbers. It is +// the same as `Expect(...).WithOffset`. // // This is most useful in helper functions that make assertions. If you want Gomega's // error message to refer to the calling line in the test (as opposed to the line in the helper function) @@ -300,6 +301,9 @@ For example: }).Should(Succeed()) will rerun the function until all assertions pass. + +`Eventually` specifying a timeout interval (and an optional polling interval) are +the same as `Eventually(...).WithTimeout` or `Eventually(...).WithTimeout(...).WithPolling`. */ func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() @@ -309,6 +313,12 @@ func Eventually(actual interface{}, intervals ...interface{}) AsyncAssertion { // EventuallyWithOffset operates like Eventually but takes an additional // initial argument to indicate an offset in the call stack. This is useful when building helper // functions that contain matchers. To learn more, read about `ExpectWithOffset`. +// +// `EventuallyWithOffset` is the same as `Eventually(...).WithOffset`. +// +// `EventuallyWithOffset` specifying a timeout interval (and an optional polling interval) are +// the same as `Eventually(...).WithOffset(...).WithTimeout` or +// `Eventually(...).WithOffset(...).WithTimeout(...).WithPolling`. func EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() return Default.EventuallyWithOffset(offset, actual, intervals...) @@ -337,6 +347,9 @@ func Consistently(actual interface{}, intervals ...interface{}) AsyncAssertion { // ConsistentlyWithOffset operates like Consistently but takes an additional // initial argument to indicate an offset in the call stack. This is useful when building helper // functions that contain matchers. To learn more, read about `ExpectWithOffset`. +// +// `ConsistentlyWithOffset` is the same as `Consistently(...).WithOffset` and +// optional `WithTimeout` and `WithPolling`. func ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) AsyncAssertion { ensureDefaultGomegaIsConfigured() return Default.ConsistentlyWithOffset(offset, actual, intervals...) diff --git a/internal/assertion.go b/internal/assertion.go index 36b0e8345..b7573330d 100644 --- a/internal/assertion.go +++ b/internal/assertion.go @@ -23,6 +23,11 @@ func NewAssertion(actualInput interface{}, g *Gomega, offset int, extra ...inter } } +func (assertion *Assertion) WithOffset(offset int) types.Assertion { + assertion.offset = offset + return assertion +} + func (assertion *Assertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...) diff --git a/internal/async_assertion.go b/internal/async_assertion.go index ae20c14b8..3e52992cf 100644 --- a/internal/async_assertion.go +++ b/internal/async_assertion.go @@ -87,6 +87,21 @@ func NewAsyncAssertion(asyncType AsyncAssertionType, actualInput interface{}, g return out } +func (assertion *AsyncAssertion) WithOffset(offset int) types.AsyncAssertion { + assertion.offset = offset + return assertion +} + +func (assertion *AsyncAssertion) WithTimeout(interval time.Duration) types.AsyncAssertion { + assertion.timeoutInterval = interval + return assertion +} + +func (assertion *AsyncAssertion) WithPolling(interval time.Duration) types.AsyncAssertion { + assertion.pollingInterval = interval + return assertion +} + func (assertion *AsyncAssertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool { assertion.g.THelper() return assertion.match(matcher, true, optionalDescription...) diff --git a/internal/async_assertion_test.go b/internal/async_assertion_test.go index 8bfc1ff52..6e0284dc6 100644 --- a/internal/async_assertion_test.go +++ b/internal/async_assertion_test.go @@ -51,7 +51,7 @@ var _ = Describe("Asynchronous Assertions", func() { return MATCH } return NO_MATCH - }, "200ms", "20ms").Should(SpecMatch()) + }).WithTimeout(200 * time.Millisecond).WithPolling(20 * time.Millisecond).Should(SpecMatch()) Ω(counter).Should(BeNumerically(">", 2)) Ω(counter).Should(BeNumerically("<", 20)) Ω(ig.FailureMessage).Should(ContainSubstring("Timed out after")) @@ -95,7 +95,7 @@ var _ = Describe("Asynchronous Assertions", func() { return NO_MATCH } return MATCH - }, "200ms", "20ms").ShouldNot(SpecMatch()) + }).WithTimeout(200 * time.Millisecond).WithPolling(20 * time.Millisecond).ShouldNot(SpecMatch()) Ω(counter).Should(BeNumerically(">", 2)) Ω(counter).Should(BeNumerically("<", 20)) Ω(ig.FailureMessage).Should(ContainSubstring("Timed out after")) @@ -106,7 +106,7 @@ var _ = Describe("Asynchronous Assertions", func() { Context("when a failure occurs", func() { It("registers the appropriate helper functions", func() { - ig.G.Eventually(NO_MATCH, "50ms", "10ms").Should(SpecMatch()) + ig.G.Eventually(NO_MATCH).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(SpecMatch()) Ω(ig.FailureMessage).Should(ContainSubstring("Timed out after")) Ω(ig.FailureMessage).Should(ContainSubstring("positive: no match")) Ω(ig.FailureSkip).Should(Equal([]int{3})) @@ -115,23 +115,23 @@ var _ = Describe("Asynchronous Assertions", func() { }) It("renders the matcher's error if an error occured", func() { - ig.G.Eventually(ERR_MATCH, "50ms", "10ms").Should(SpecMatch()) + ig.G.Eventually(ERR_MATCH).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(SpecMatch()) Ω(ig.FailureMessage).Should(ContainSubstring("Timed out after")) Ω(ig.FailureMessage).Should(ContainSubstring("Error: spec matcher error")) }) It("renders the optional description", func() { - ig.G.Eventually(NO_MATCH, "50ms", "10ms").Should(SpecMatch(), "boop") + ig.G.Eventually(NO_MATCH).WithTimeout(50*time.Millisecond).WithPolling(10*time.Millisecond).Should(SpecMatch(), "boop") Ω(ig.FailureMessage).Should(ContainSubstring("boop")) }) It("formats and renders the optional description when there are multiple arguments", func() { - ig.G.Eventually(NO_MATCH, "50ms", "10ms").Should(SpecMatch(), "boop %d", 17) + ig.G.Eventually(NO_MATCH).WithTimeout(50*time.Millisecond).WithPolling(10*time.Millisecond).Should(SpecMatch(), "boop %d", 17) Ω(ig.FailureMessage).Should(ContainSubstring("boop 17")) }) It("calls the optional description if it is a function", func() { - ig.G.Eventually(NO_MATCH, "50ms", "10ms").Should(SpecMatch(), func() string { return "boop" }) + ig.G.Eventually(NO_MATCH).WithTimeout(50*time.Millisecond).WithPolling(10*time.Millisecond).Should(SpecMatch(), func() string { return "boop" }) Ω(ig.FailureMessage).Should(ContainSubstring("boop")) }) }) @@ -144,7 +144,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Consistently(func() string { counter++ return MATCH - }, "50ms", "10ms").Should(SpecMatch()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(SpecMatch()) Ω(counter).Should(BeNumerically(">", 1)) Ω(counter).Should(BeNumerically("<", 7)) Ω(ig.FailureMessage).Should(BeZero()) @@ -158,7 +158,7 @@ var _ = Describe("Asynchronous Assertions", func() { return ERR_MATCH } return MATCH - }, "50ms", "10ms").Should(SpecMatch()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(SpecMatch()) Ω(counter).Should(Equal(3)) Ω(ig.FailureMessage).Should(ContainSubstring("Failed after")) Ω(ig.FailureMessage).Should(ContainSubstring("Error: spec matcher error")) @@ -172,7 +172,7 @@ var _ = Describe("Asynchronous Assertions", func() { return NO_MATCH } return MATCH - }, "50ms", "10ms").Should(SpecMatch()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(SpecMatch()) Ω(counter).Should(Equal(3)) Ω(ig.FailureMessage).Should(ContainSubstring("Failed after")) Ω(ig.FailureMessage).Should(ContainSubstring("positive: no match")) @@ -185,7 +185,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Consistently(func() string { counter++ return NO_MATCH - }, "50ms", "10ms").ShouldNot(SpecMatch()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(SpecMatch()) Ω(counter).Should(BeNumerically(">", 1)) Ω(counter).Should(BeNumerically("<", 7)) Ω(ig.FailureMessage).Should(BeZero()) @@ -199,7 +199,7 @@ var _ = Describe("Asynchronous Assertions", func() { return ERR_MATCH } return NO_MATCH - }, "50ms", "10ms").ShouldNot(SpecMatch()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(SpecMatch()) Ω(counter).Should(Equal(3)) Ω(ig.FailureMessage).Should(ContainSubstring("Failed after")) Ω(ig.FailureMessage).Should(ContainSubstring("Error: spec matcher error")) @@ -213,7 +213,7 @@ var _ = Describe("Asynchronous Assertions", func() { return MATCH } return NO_MATCH - }, "50ms", "10ms").ShouldNot(SpecMatch()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(SpecMatch()) Ω(counter).Should(Equal(3)) Ω(ig.FailureMessage).Should(ContainSubstring("Failed after")) Ω(ig.FailureMessage).Should(ContainSubstring("negative: match")) @@ -263,14 +263,14 @@ var _ = Describe("Asynchronous Assertions", func() { time.Sleep(100 * time.Millisecond) close(c) }() - ig.G.Eventually(c, "1s", "10ms").Should(BeClosed()) + ig.G.Eventually(c).WithTimeout(1 * time.Second).WithPolling(10 * time.Millisecond).Should(BeClosed()) Ω(ig.FailureMessage).Should(BeZero()) }) It("(consistently) continuously checks on the value ensuring a match always occurs", func() { c := make(chan bool) close(c) - ig.G.Consistently(c, "50ms", "10ms").Should(BeClosed()) + ig.G.Consistently(c).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(BeClosed()) Ω(ig.FailureMessage).Should(BeZero()) }) }) @@ -281,7 +281,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Eventually(func() int { counter += 1 return counter - }, "1s", "10ms").Should(BeNumerically(">", 5)) + }).WithTimeout(1 * time.Second).WithPolling(10 * time.Millisecond).Should(BeNumerically(">", 5)) Ω(ig.FailureMessage).Should(BeZero()) }) @@ -290,7 +290,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Consistently(func() int { counter += 1 return counter - }, "50ms", "10ms").Should(BeNumerically("<", 20)) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(BeNumerically("<", 20)) Ω(counter).Should(BeNumerically(">", 2)) Ω(ig.FailureMessage).Should(BeZero()) }) @@ -303,7 +303,7 @@ var _ = Describe("Asynchronous Assertions", func() { return nil } return errors.New("oops") - }, "1s", "10ms").Should(BeNil()) + }).WithTimeout(1 * time.Second).WithPolling(10 * time.Millisecond).Should(BeNil()) Ω(ig.FailureMessage).Should(BeZero()) }) }) @@ -322,7 +322,7 @@ var _ = Describe("Asynchronous Assertions", func() { err = nil } return counter, s, f, err - }, "1s", "10ms").Should(BeNumerically("<", 100)) + }).WithTimeout(1 * time.Second).WithPolling(10 * time.Millisecond).Should(BeNumerically("<", 100)) Ω(ig.FailureMessage).Should(BeZero()) Ω(counter).Should(Equal(4)) }) @@ -330,7 +330,7 @@ var _ = Describe("Asynchronous Assertions", func() { It("reports on the non-zero value if it times out", func() { ig.G.Eventually(func() (int, string, Foo, error) { return 1, "", Foo{Bar: "hi"}, nil - }, "30ms", "10ms").Should(BeNumerically("<", 100)) + }).WithTimeout(30 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(BeNumerically("<", 100)) Ω(ig.FailureMessage).Should(ContainSubstring("Error: Unexpected non-nil/non-zero extra argument at index 2:")) Ω(ig.FailureMessage).Should(ContainSubstring(`Foo{Bar:"hi"}`)) }) @@ -348,7 +348,7 @@ var _ = Describe("Asynchronous Assertions", func() { err = nil } return counter, s, f, err - }, "1s", "10ms").ShouldNot(BeNumerically("<", 0)) + }).WithTimeout(1 * time.Second).WithPolling(10 * time.Millisecond).ShouldNot(BeNumerically("<", 0)) Ω(ig.FailureMessage).Should(BeZero()) Ω(counter).Should(Equal(4)) }) @@ -362,7 +362,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Consistently(func() (int, string, Foo, error) { counter += 1 return counter, s, f, err - }, "50ms", "10ms").Should(BeNumerically("<", 100)) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(BeNumerically("<", 100)) Ω(ig.FailureMessage).Should(BeZero()) Ω(counter).Should(BeNumerically(">", 2)) }) @@ -376,7 +376,7 @@ var _ = Describe("Asynchronous Assertions", func() { f = Foo{Bar: "welp"} } return counter, s, f, err - }, "50ms", "10ms").Should(BeNumerically("<", 100)) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(BeNumerically("<", 100)) Ω(ig.FailureMessage).Should(ContainSubstring("Error: Unexpected non-nil/non-zero extra argument at index 2:")) Ω(ig.FailureMessage).Should(ContainSubstring(`Foo{Bar:"welp"}`)) Ω(counter).Should(Equal(3)) @@ -389,7 +389,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Consistently(func() (int, string, Foo, error) { counter += 1 return counter, s, f, err - }, "50ms", "10ms").ShouldNot(BeNumerically(">", 100)) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(BeNumerically(">", 100)) Ω(ig.FailureMessage).Should(BeZero()) Ω(counter).Should(BeNumerically(">", 2)) }) @@ -403,7 +403,7 @@ var _ = Describe("Asynchronous Assertions", func() { s = "welp" } return counter, s, f, err - }, "50ms", "10ms").ShouldNot(BeNumerically(">", 100)) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(BeNumerically(">", 100)) Ω(ig.FailureMessage).Should(ContainSubstring("Error: Unexpected non-nil/non-zero extra argument at index 1:")) Ω(ig.FailureMessage).Should(ContainSubstring(`: "welp"`)) Ω(counter).Should(Equal(3)) @@ -432,7 +432,7 @@ var _ = Describe("Asynchronous Assertions", func() { panic("boom") //never see since the expectation stops execution } return counter, s, f, err - }, "1s", "10ms").Should(BeNumerically("<", 100)) + }).WithTimeout(1 * time.Second).WithPolling(10 * time.Millisecond).Should(BeNumerically("<", 100)) Ω(ig.FailureMessage).Should(BeZero()) Ω(counter).Should(Equal(5)) }) @@ -442,7 +442,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Eventually(func(g Gomega) int { g.Expect(false).To(BeTrue()) return 10 - }, "30ms", "10ms").Should(Equal(10)) + }).WithTimeout(30 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(Equal(10)) Ω(ig.FailureMessage).Should(ContainSubstring("Error: Assertion in callback at %s:%d failed:", file, line+2)) Ω(ig.FailureMessage).Should(ContainSubstring("Expected\n : false\nto be true")) }) @@ -452,7 +452,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Eventually(func(g Gomega) int { g.Expect(true).To(BeTrue()) panic("boom") - }, "30ms", "10ms").Should(Equal(10)) + }).WithTimeout(30 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(Equal(10)) }).Should(PanicWith("boom")) Ω(ig.FailureMessage).Should(BeEmpty()) }) @@ -476,7 +476,7 @@ var _ = Describe("Asynchronous Assertions", func() { panic("boom") //never see since the expectation stops execution } return counter, s, f, err - }, "1s", "10ms").ShouldNot(BeNumerically("<", 0)) + }).WithTimeout(1 * time.Second).WithPolling(10 * time.Millisecond).ShouldNot(BeNumerically("<", 0)) Ω(ig.FailureMessage).Should(BeZero()) Ω(counter).Should(Equal(5)) }) @@ -487,7 +487,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Eventually(func(g Gomega) int { g.Expect(false).To(BeTrue()) return 9 - }, "30ms", "10ms").ShouldNot(Equal(10)) + }).WithTimeout(30 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(Equal(10)) Ω(ig.FailureMessage).Should(ContainSubstring("Error: Assertion in callback at %s:%d failed:", file, line+2)) Ω(ig.FailureMessage).Should(ContainSubstring("Expected\n : false\nto be true")) }) @@ -501,7 +501,7 @@ var _ = Describe("Asynchronous Assertions", func() { counter += 1 g.Expect(true).To(BeTrue()) return counter, s, f, err - }, "50ms", "10ms").Should(BeNumerically("<", 100)) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(BeNumerically("<", 100)) Ω(ig.FailureMessage).Should(BeZero()) Ω(counter).Should(BeNumerically(">", 2)) }) @@ -518,7 +518,7 @@ var _ = Describe("Asynchronous Assertions", func() { panic("boom") //never see this } return counter, s, f, err - }, "50ms", "10ms").Should(BeNumerically("<", 100)) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(BeNumerically("<", 100)) Ω(ig.FailureMessage).Should(ContainSubstring("Error: Assertion in callback at %s:%d failed:", file, line+5)) Ω(ig.FailureMessage).Should(ContainSubstring("Expected\n : false\nto be true")) Ω(counter).Should(Equal(3)) @@ -529,7 +529,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Consistently(func(g Gomega) int { g.Expect(true).To(BeTrue()) panic("boom") - }, "50ms", "10ms").Should(Equal(10)) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(Equal(10)) }).Should(PanicWith("boom")) Ω(ig.FailureMessage).Should(BeEmpty()) }) @@ -539,7 +539,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Consistently(func(g Gomega) int { g.Expect(true).To(BeTrue()) return 9 - }, "50ms", "10ms").ShouldNot(Equal(10)) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(Equal(10)) Ω(ig.FailureMessage).Should(BeEmpty()) }) @@ -554,7 +554,7 @@ var _ = Describe("Asynchronous Assertions", func() { panic("boom") //never see this } return 9 - }, "50ms", "10ms").ShouldNot(Equal(10)) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(Equal(10)) Ω(ig.FailureMessage).Should(ContainSubstring("Error: Assertion in callback at %s:%d failed:", file, line+5)) Ω(ig.FailureMessage).Should(ContainSubstring("Expected\n : false\nto be true")) }) @@ -572,7 +572,7 @@ var _ = Describe("Asynchronous Assertions", func() { g.Expect(false).To(BeTrue()) g.Expect("bloop").To(Equal("blarp")) } - }, "1s", "10ms").Should(Succeed()) + }).WithTimeout(1 * time.Second).WithPolling(10 * time.Millisecond).Should(Succeed()) Ω(counter).Should(Equal(5)) Ω(ig.FailureMessage).Should(BeZero()) }) @@ -585,7 +585,7 @@ var _ = Describe("Asynchronous Assertions", func() { g.Expect(false).To(BeTrue()) g.Expect("bloop").To(Equal("blarp")) } - }, "100ms", "10ms").Should(Succeed()) + }).WithTimeout(100 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(Succeed()) Ω(counter).Should(BeNumerically(">", 1)) Ω(ig.FailureMessage).Should(ContainSubstring("Expected success, but got an error")) Ω(ig.FailureMessage).Should(ContainSubstring(": false")) @@ -601,7 +601,7 @@ var _ = Describe("Asynchronous Assertions", func() { g.Expect(false).To(BeTrue()) g.Expect("bloop").To(Equal("blarp")) } - }, "100ms", "10ms").ShouldNot(Succeed()) + }).WithTimeout(100 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(Succeed()) Ω(counter).Should(Equal(6)) Ω(ig.FailureMessage).Should(BeZero()) }) @@ -609,7 +609,7 @@ var _ = Describe("Asynchronous Assertions", func() { It("should fail to ShouldNot(Succeed) eventually if an error never occurs", func() { ig.G.Eventually(func(g Gomega) { g.Expect(true).To(BeTrue()) - }, "50ms", "10ms").ShouldNot(Succeed()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(Succeed()) Ω(ig.FailureMessage).Should(ContainSubstring("Timed out after")) Ω(ig.FailureMessage).Should(ContainSubstring("Expected failure, but got no error.")) }) @@ -621,7 +621,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Consistently(func(g Gomega) { counter += 1 g.Expect(true).To(BeTrue()) - }, "50ms", "10ms").Should(Succeed()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(Succeed()) Ω(counter).Should(BeNumerically(">", 2)) Ω(ig.FailureMessage).Should(BeZero()) }) @@ -635,7 +635,7 @@ var _ = Describe("Asynchronous Assertions", func() { g.Expect(false).To(BeTrue()) g.Expect("bloop").To(Equal("blarp")) } - }, "50ms", "10ms").Should(Succeed()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).Should(Succeed()) Ω(ig.FailureMessage).Should(ContainSubstring("Expected success, but got an error")) Ω(ig.FailureMessage).Should(ContainSubstring(": false")) Ω(ig.FailureMessage).Should(ContainSubstring("to be true")) @@ -648,7 +648,7 @@ var _ = Describe("Asynchronous Assertions", func() { ig.G.Consistently(func(g Gomega) { counter += 1 g.Expect(true).To(BeFalse()) - }, "50ms", "10ms").ShouldNot(Succeed()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(Succeed()) Ω(counter).Should(BeNumerically(">", 2)) Ω(ig.FailureMessage).Should(BeZero()) }) @@ -662,7 +662,7 @@ var _ = Describe("Asynchronous Assertions", func() { } else { g.Expect(false).To(BeTrue()) } - }, "50ms", "10ms").ShouldNot(Succeed()) + }).WithTimeout(50 * time.Millisecond).WithPolling(10 * time.Millisecond).ShouldNot(Succeed()) Ω(ig.FailureMessage).Should(ContainSubstring("Failed after")) Ω(ig.FailureMessage).Should(ContainSubstring("Expected failure, but got no error.")) Ω(counter).Should(Equal(3)) @@ -695,7 +695,7 @@ var _ = Describe("Asynchronous Assertions", func() { close(c) t := time.Now() - ig.G.Eventually(c, "100ms", "10ms").Should(Receive(), "Receive is an OracleMatcher that gives up if the channel is closed") + ig.G.Eventually(c).WithTimeout(100*time.Millisecond).WithPolling(10*time.Millisecond).Should(Receive(), "Receive is an OracleMatcher that gives up if the channel is closed") Ω(time.Since(t)).Should(BeNumerically("<", 90*time.Millisecond)) Ω(ig.FailureMessage).Should(ContainSubstring("No future change is possible.")) Ω(ig.FailureMessage).Should(ContainSubstring("The channel is closed.")) @@ -706,7 +706,7 @@ var _ = Describe("Asynchronous Assertions", func() { close(c) t := time.Now() - ig.G.Eventually(func() chan bool { return c }, "100ms", "10ms").Should(Receive(), "Receive is an OracleMatcher that gives up if the channel is closed") + ig.G.Eventually(func() chan bool { return c }).WithTimeout(100*time.Millisecond).WithPolling(10*time.Millisecond).Should(Receive(), "Receive is an OracleMatcher that gives up if the channel is closed") Ω(time.Since(t)).Should(BeNumerically(">=", 90*time.Millisecond)) Ω(ig.FailureMessage).ShouldNot(ContainSubstring("No future change is possible.")) Ω(ig.FailureMessage).Should(ContainSubstring("Timed out after")) diff --git a/internal/dsl_test.go b/internal/dsl_test.go index 33b7069f4..be0122d34 100644 --- a/internal/dsl_test.go +++ b/internal/dsl_test.go @@ -215,9 +215,9 @@ var _ = Describe("Gomega DSL", func() { doubleNested := func(eventually bool) { func() { if eventually { - EventuallyWithOffset(2, true, "10ms", "5ms").Should(BeFalse()) + Eventually(true, "10ms", "5ms").WithOffset(2).Should(BeFalse()) } else { - ExpectWithOffset(2, true).To(BeFalse()) + Expect(true).WithOffset(2).To(BeFalse()) } }() } diff --git a/internal/gomega_test.go b/internal/gomega_test.go index a9fcb1cd3..ac15ec72e 100644 --- a/internal/gomega_test.go +++ b/internal/gomega_test.go @@ -61,9 +61,9 @@ var _ = Describe("Gomega", func() { doubleNested := func(g Gomega, eventually bool) { func() { if eventually { - g.EventuallyWithOffset(2, true, "10ms", "5ms").Should(BeFalse()) + g.Eventually(true, "10ms", "5ms").WithOffset(2).Should(BeFalse()) } else { - g.ExpectWithOffset(2, true).To(BeFalse()) + g.Expect(true).WithOffset(2).To(BeFalse()) } }() } diff --git a/matchers/satisfy_matcher_test.go b/matchers/satisfy_matcher_test.go index b91e8060f..0a76beeb3 100644 --- a/matchers/satisfy_matcher_test.go +++ b/matchers/satisfy_matcher_test.go @@ -13,7 +13,7 @@ var _ = Describe("SatisfyMatcher", func() { Context("Panic if predicate is invalid", func() { panicsWithPredicate := func(predicate interface{}) { - ExpectWithOffset(1, func() { Satisfy(predicate) }).To(Panic()) + Expect(func() { Satisfy(predicate) }).WithOffset(1).To(Panic()) } It("nil", func() { panicsWithPredicate(nil) diff --git a/matchers/with_transform_test.go b/matchers/with_transform_test.go index 480d72974..46b1e090c 100644 --- a/matchers/with_transform_test.go +++ b/matchers/with_transform_test.go @@ -14,7 +14,7 @@ var _ = Describe("WithTransformMatcher", func() { Context("Panic if transform function invalid", func() { panicsWithTransformer := func(transform interface{}) { - ExpectWithOffset(1, func() { WithTransform(transform, nil) }).To(Panic()) + Expect(func() { WithTransform(transform, nil) }).WithOffset(1).To(Panic()) } It("nil", func() { panicsWithTransformer(nil) diff --git a/types/types.go b/types/types.go index c75fcb3cc..a0ae6cbc9 100644 --- a/types/types.go +++ b/types/types.go @@ -66,6 +66,10 @@ func MatchMayChangeInTheFuture(matcher GomegaMatcher, value interface{}) bool { type AsyncAssertion interface { Should(matcher GomegaMatcher, optionalDescription ...interface{}) bool ShouldNot(matcher GomegaMatcher, optionalDescription ...interface{}) bool + + WithOffset(offset int) AsyncAssertion + WithTimeout(interval time.Duration) AsyncAssertion + WithPolling(interval time.Duration) AsyncAssertion } // Assertions are returned by Ω and Expect and enable assertions against Gomega matchers @@ -76,4 +80,6 @@ type Assertion interface { To(matcher GomegaMatcher, optionalDescription ...interface{}) bool ToNot(matcher GomegaMatcher, optionalDescription ...interface{}) bool NotTo(matcher GomegaMatcher, optionalDescription ...interface{}) bool + + WithOffset(offset int) Assertion }