Skip to content

Commit

Permalink
make assert Within and AnyOf fail early if FailNow based failure is e…
Browse files Browse the repository at this point in the history
…xpected from it
  • Loading branch information
adamluzsi committed Jan 25, 2023
1 parent 00fcb88 commit 2e5db10
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
18 changes: 13 additions & 5 deletions assert/Asserter.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ func (a Asserter) containExactlySlice(exp reflect.Value, act reflect.Value, msg

func (a Asserter) AnyOf(blk func(a *AnyOf), msg ...any) {
a.TB.Helper()
anyOf := &AnyOf{TB: a.TB, Fail: a.TB.Fail}
anyOf := &AnyOf{TB: a.TB, Fail: a.Fail}
defer anyOf.Finish(msg...)
blk(anyOf)
}
Expand Down Expand Up @@ -972,13 +972,18 @@ func (a Asserter) Within(timeout time.Duration, blk func(context.Context), msg .
a.TB.Helper()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
var done uint32
var done, isFailNow uint32
go func() {
blk(ctx)
atomic.AddUint32(&done, 1)
ro := sandbox.Run(func() {
blk(ctx)
atomic.AddUint32(&done, 1)
})
if !ro.OK {
atomic.AddUint32(&isFailNow, 1)
}
}()
Waiter{Timeout: timeout}.While(func() bool {
return atomic.LoadUint32(&done) == 0
return atomic.LoadUint32(&done) == 0 && atomic.LoadUint32(&isFailNow) == 0
})
if atomic.LoadUint32(&done) == 0 {
a.fn(fmterror.Message{
Expand All @@ -993,4 +998,7 @@ func (a Asserter) Within(timeout time.Duration, blk func(context.Context), msg .
},
}.String())
}
if atomic.LoadUint32(&isFailNow) != 0 {
a.TB.FailNow()
}
}
27 changes: 27 additions & 0 deletions assert/Asserter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,19 @@ func TestAsserter_Within(t *testing.T) {
it.Must.True(atomic.LoadInt32(&isCancelled) == 1)
})
})
t.Run("when FailNow based failing as part of the Within block, it is propagated to the outside as well", func(t *testing.T) {
dtb := &doubles.TB{}
a := asserter(dtb)

ro := sandbox.Run(func() {
a.Within(time.Second, func(ctx context.Context) {
dtb.FailNow()
})
})

assert.Must(t).True(dtb.IsFailed)
assert.Must(t).True(ro.Goexit)
})
}

func TestAsserter_ContainExactly_map(t *testing.T) {
Expand Down Expand Up @@ -1212,6 +1225,20 @@ func TestAsserter_AnyOf(t *testing.T) {
})
h.Equal(true, stub.IsFailed, `testing.TB should failure`)
})

t.Run("on rainy path - when test fails during AnyOf.Finish, then outer layer also fails", func(t *testing.T) {
ro := sandbox.Run(func() {
stub := &doubles.TB{}
a := assert.Asserter{TB: stub, Fail: stub.FailNow}
a.AnyOf(func(a *assert.AnyOf) {
a.Test(func(it assert.It) { it.FailNow() })
})
})
t.Log(`Asserter was used with FailNow, so the sandbox should not be OK`)
assert.False(t, ro.OK)
assert.True(t, ro.Goexit)
assert.Nil(t, ro.PanicValue)
})
}

func TestAsserter_Empty(t *testing.T) {
Expand Down

0 comments on commit 2e5db10

Please sign in to comment.