From 1351f31e796af99e580ba8cc8e2cb870825eeecc Mon Sep 17 00:00:00 2001 From: Vladimir Kochnev Date: Sun, 8 Oct 2023 21:08:46 +0300 Subject: [PATCH] assert: collect.FailNow() should not panic Fixes https://github.com/stretchr/testify/issues/1396 Fixes https://github.com/stretchr/testify/issues/1457 --- assert/assertions.go | 9 +++++---- assert/assertions_test.go | 11 +++++++++++ require/requirements_test.go | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index c276316b4..38c7bd8e1 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1872,9 +1872,10 @@ func (c *CollectT) Errorf(format string, args ...interface{}) { c.errors = append(c.errors, fmt.Errorf(format, args...)) } -// FailNow panics. -func (*CollectT) FailNow() { - panic("Assertion failed") +// FailNow stops the execution by calling runtime.Goexit. +func (c *CollectT) FailNow() { + c.errors = []error{} // Make it non-nil to mark a failure. + runtime.Goexit() } // Deprecated: That was a method for internal usage that should not have been published. Now just panics. @@ -1936,7 +1937,7 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time condition(collect) }() case errs := <-ch: - if len(errs) == 0 { + if errs == nil { return true } // Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached. diff --git a/assert/assertions_test.go b/assert/assertions_test.go index e1245b421..47c34a444 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2838,6 +2838,17 @@ func TestEventuallyWithT_ReturnsTheLatestFinishedConditionErrors(t *testing.T) { Len(t, mockT.errors, 2) } +func TestEventuallyWithTFailNow(t *testing.T) { + mockT := new(CollectT) + + condition := func(collect *CollectT) { + collect.FailNow() + } + + False(t, EventuallyWithT(mockT, condition, 100*time.Millisecond, 20*time.Millisecond)) + Len(t, mockT.errors, 1) +} + func TestNeverFalse(t *testing.T) { condition := func() bool { return false diff --git a/require/requirements_test.go b/require/requirements_test.go index febf0c187..c1636ca2e 100644 --- a/require/requirements_test.go +++ b/require/requirements_test.go @@ -5,6 +5,8 @@ import ( "errors" "testing" "time" + + "github.com/stretchr/testify/assert" ) // AssertionTesterInterface defines an interface to be used for testing assertion methods @@ -681,3 +683,33 @@ func TestErrorAssertionFunc(t *testing.T) { }) } } + +func TestEventuallyWithTFalse(t *testing.T) { + mockT := new(MockT) + + condition := func(collect *assert.CollectT) { + True(collect, false) + } + + EventuallyWithT(mockT, condition, 100*time.Millisecond, 20*time.Millisecond) + if !mockT.Failed { + t.Error("Check should fail") + } +} + +func TestEventuallyWithTTrue(t *testing.T) { + mockT := new(MockT) + + state := 0 + condition := func(collect *assert.CollectT) { + defer func() { + state += 1 + }() + True(collect, state == 2) + } + + EventuallyWithT(mockT, condition, 100*time.Millisecond, 20*time.Millisecond) + if mockT.Failed { + t.Error("Check should pass") + } +}