diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 3fe076cfe..0b946da2d 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -159,30 +159,21 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // periodically checking target function each tick. In contrast to Eventually, // it supplies a CollectT to the condition function, so that the condition // function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. // The supplied CollectT collects all errors from one tick (if there are any). // If the condition is not met before waitFor, the collected errors of // the last tick are copied to t. // -// falseThenTrue := func(falses int) func() bool { -// count := 0 -// return func() bool { -// if count < falses { -// count++ -// return false -// } -// return true -// } -// } -// f := falseThenTrue(5) -// assert.EventuallyWithTf(t, func(mockT *assert.CollectT) (success bool, "error message %s", "formatted") { -// defer func() { -// r := recover() -// success = (r == nil) -// }() -// assert.True(mockT, f()) -// return -// }, 50*time.Millisecond, 10*time.Millisecond) -func EventuallyWithTf(t TestingT, condition func(collect *CollectT) bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// assert.EventuallyWithTf(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still: %v", externalState) +func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 7ab795746..661ab07a3 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -292,30 +292,21 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti // periodically checking target function each tick. In contrast to Eventually, // it supplies a CollectT to the condition function, so that the condition // function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. // The supplied CollectT collects all errors from one tick (if there are any). // If the condition is not met before waitFor, the collected errors of // the last tick are copied to t. // -// falseThenTrue := func(falses int) func() bool { -// count := 0 -// return func() bool { -// if count < falses { -// count++ -// return false -// } -// return true -// } -// } -// f := falseThenTrue(5) -// a.EventuallyWithT(func(mockT *assert.CollectT) (success bool) { -// defer func() { -// r := recover() -// success = (r == nil) -// }() -// assert.True(mockT, f()) -// return -// }, 50*time.Millisecond, 10*time.Millisecond) -func (a *Assertions) EventuallyWithT(condition func(collect *CollectT) bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// a.EventuallyWithT(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() } @@ -326,30 +317,21 @@ func (a *Assertions) EventuallyWithT(condition func(collect *CollectT) bool, wai // periodically checking target function each tick. In contrast to Eventually, // it supplies a CollectT to the condition function, so that the condition // function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. // The supplied CollectT collects all errors from one tick (if there are any). // If the condition is not met before waitFor, the collected errors of // the last tick are copied to t. // -// falseThenTrue := func(falses int) func() bool { -// count := 0 -// return func() bool { -// if count < falses { -// count++ -// return false -// } -// return true -// } -// } -// f := falseThenTrue(5) -// a.EventuallyWithTf(func(mockT *assert.CollectT) (success bool, "error message %s", "formatted") { -// defer func() { -// r := recover() -// success = (r == nil) -// }() -// assert.True(mockT, f()) -// return -// }, 50*time.Millisecond, 10*time.Millisecond) -func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT) bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// a.EventuallyWithTf(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still: %v", externalState) +func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() } diff --git a/assert/assertions.go b/assert/assertions.go index 71c5c5a4d..ed9d677f9 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1778,6 +1778,9 @@ func (c *CollectT) Reset() { // Copy copies the collected errors to the supplied t. func (c *CollectT) Copy(t TestingT) { + if tt, ok := t.(tHelper); ok { + tt.Helper() + } for _, err := range c.errors { t.Errorf("%v", err) } @@ -1787,30 +1790,21 @@ func (c *CollectT) Copy(t TestingT) { // periodically checking target function each tick. In contrast to Eventually, // it supplies a CollectT to the condition function, so that the condition // function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. // The supplied CollectT collects all errors from one tick (if there are any). // If the condition is not met before waitFor, the collected errors of // the last tick are copied to t. // -// falseThenTrue := func(falses int) func() bool { -// count := 0 -// return func() bool { -// if count < falses { -// count++ -// return false -// } -// return true -// } -// } -// f := falseThenTrue(5) -// assert.EventuallyWithT(t, func(mockT *assert.CollectT) (success bool) { -// defer func() { -// r := recover() -// success = (r == nil) -// }() -// assert.True(mockT, f()) -// return -// }, 50*time.Millisecond, 10*time.Millisecond) -func EventuallyWithT(t TestingT, condition func(collect *CollectT) bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// assert.EventuallyWithT(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } @@ -1832,7 +1826,10 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT) bool, waitFor case <-tick: tick = nil collect.Reset() - go func() { ch <- condition(collect) }() + go func() { + condition(collect) + ch <- len(collect.errors) == 0 + }() case v := <-ch: if v { return true diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 9c324f1c0..14b657bd9 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2431,8 +2431,8 @@ func TestEventuallyTrue(t *testing.T) { func TestEventuallyWithTFalse(t *testing.T) { mockT := new(CollectT) - condition := func(collect *CollectT) bool { - return True(collect, false) + condition := func(collect *CollectT) { + True(collect, false) } False(t, EventuallyWithT(mockT, condition, 100*time.Millisecond, 20*time.Millisecond)) @@ -2443,17 +2443,11 @@ func TestEventuallyWithTTrue(t *testing.T) { mockT := new(CollectT) state := 0 - condition := func(collect *CollectT) bool { + condition := func(collect *CollectT) { defer func() { state += 1 }() - - if state == 2 { - True(collect, true) - return true - } - - return True(collect, false) + True(collect, state == 2) } True(t, EventuallyWithT(mockT, condition, 100*time.Millisecond, 20*time.Millisecond)) diff --git a/require/require.go b/require/require.go index 79052243f..e59c4f4e0 100644 --- a/require/require.go +++ b/require/require.go @@ -368,30 +368,21 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t // periodically checking target function each tick. In contrast to Eventually, // it supplies a CollectT to the condition function, so that the condition // function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. // The supplied CollectT collects all errors from one tick (if there are any). // If the condition is not met before waitFor, the collected errors of // the last tick are copied to t. // -// falseThenTrue := func(falses int) func() bool { -// count := 0 -// return func() bool { -// if count < falses { -// count++ -// return false -// } -// return true -// } -// } -// f := falseThenTrue(5) -// assert.EventuallyWithT(t, func(mockT *assert.CollectT) (success bool) { -// defer func() { -// r := recover() -// success = (r == nil) -// }() -// assert.True(mockT, f()) -// return -// }, 50*time.Millisecond, 10*time.Millisecond) -func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT) bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// require.EventuallyWithT(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() } @@ -405,30 +396,21 @@ func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT) bool, // periodically checking target function each tick. In contrast to Eventually, // it supplies a CollectT to the condition function, so that the condition // function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. // The supplied CollectT collects all errors from one tick (if there are any). // If the condition is not met before waitFor, the collected errors of // the last tick are copied to t. // -// falseThenTrue := func(falses int) func() bool { -// count := 0 -// return func() bool { -// if count < falses { -// count++ -// return false -// } -// return true -// } -// } -// f := falseThenTrue(5) -// assert.EventuallyWithTf(t, func(mockT *assert.CollectT) (success bool, "error message %s", "formatted") { -// defer func() { -// r := recover() -// success = (r == nil) -// }() -// assert.True(mockT, f()) -// return -// }, 50*time.Millisecond, 10*time.Millisecond) -func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT) bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// require.EventuallyWithTf(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still: %v", externalState) +func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() } diff --git a/require/require_forward.go b/require/require_forward.go index 75cbd4bde..ab0231574 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -293,30 +293,21 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti // periodically checking target function each tick. In contrast to Eventually, // it supplies a CollectT to the condition function, so that the condition // function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. // The supplied CollectT collects all errors from one tick (if there are any). // If the condition is not met before waitFor, the collected errors of // the last tick are copied to t. // -// falseThenTrue := func(falses int) func() bool { -// count := 0 -// return func() bool { -// if count < falses { -// count++ -// return false -// } -// return true -// } -// } -// f := falseThenTrue(5) -// a.EventuallyWithT(func(mockT *assert.CollectT) (success bool) { -// defer func() { -// r := recover() -// success = (r == nil) -// }() -// assert.True(mockT, f()) -// return -// }, 50*time.Millisecond, 10*time.Millisecond) -func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT) bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// require.EventuallyWithT(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() } @@ -327,30 +318,21 @@ func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT) bo // periodically checking target function each tick. In contrast to Eventually, // it supplies a CollectT to the condition function, so that the condition // function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. // The supplied CollectT collects all errors from one tick (if there are any). // If the condition is not met before waitFor, the collected errors of // the last tick are copied to t. // -// falseThenTrue := func(falses int) func() bool { -// count := 0 -// return func() bool { -// if count < falses { -// count++ -// return false -// } -// return true -// } -// } -// f := falseThenTrue(5) -// a.EventuallyWithTf(func(mockT *assert.CollectT) (success bool, "error message %s", "formatted") { -// defer func() { -// r := recover() -// success = (r == nil) -// }() -// assert.True(mockT, f()) -// return -// }, 50*time.Millisecond, 10*time.Millisecond) -func (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT) bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// require.EventuallyWithTf(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still: %v", externalState) +func (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() }