Skip to content

Commit f422352

Browse files
committed
refactor assert.Eventually to be consistent with other assertion functions
1 parent eb4560a commit f422352

19 files changed

+201
-79
lines changed

Race_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
)
2020

2121
func TestRace(t *testing.T) {
22-
eventually := assert.Eventually{RetryStrategy: assert.Waiter{Timeout: time.Second}}
22+
eventually := assert.Retry{Strategy: assert.Waiter{Timeout: time.Second}}
2323

2424
t.Run(`functions run in race against each other`, func(t *testing.T) {
2525
eventually.Assert(t, func(it assert.It) {

Spec.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ type Spec struct {
9090
parallel bool
9191
sequential bool
9292
skipBenchmark bool
93-
flaky *assert.Eventually
94-
eventually *assert.Eventually
93+
flaky *assert.Retry
94+
eventually *assert.Retry
9595
group *struct{ name string }
9696
description string
9797
tags []string
@@ -290,24 +290,24 @@ func (spec *Spec) isBenchAllowedToRun() bool {
290290
return true
291291
}
292292

293-
func (spec *Spec) lookupRetryFlaky() (assert.Eventually, bool) {
293+
func (spec *Spec) lookupRetryFlaky() (assert.Retry, bool) {
294294
spec.testingTB.Helper()
295295
for _, context := range spec.specsFromParent() {
296296
if context.flaky != nil {
297297
return *context.flaky, true
298298
}
299299
}
300-
return assert.Eventually{}, false
300+
return assert.Retry{}, false
301301
}
302302

303-
func (spec *Spec) lookupRetryEventually() (assert.Eventually, bool) {
303+
func (spec *Spec) lookupRetryEventually() (assert.Retry, bool) {
304304
spec.testingTB.Helper()
305305
for _, context := range spec.specsFromParent() {
306306
if context.eventually != nil {
307307
return *context.eventually, true
308308
}
309309
}
310-
return assert.Eventually{}, false
310+
return assert.Retry{}, false
311311
}
312312

313313
func (spec *Spec) printDescription(tb testing.TB) {

Spec_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,8 +1047,8 @@ func TestSpec_Test_flakyByRetry_willRunAgainWithTheProvidedRetry(t *testing.T) {
10471047
s := testcase.NewSpec(t)
10481048

10491049
var retryUsed bool
1050-
retry := assert.Eventually{
1051-
RetryStrategy: assert.RetryStrategyFunc(func(condition func() bool) {
1050+
retry := assert.Retry{
1051+
Strategy: assert.RetryStrategyFunc(func(condition func() bool) {
10521052
retryUsed = true
10531053
for condition() {
10541054
}
@@ -1158,7 +1158,7 @@ func TestSpec_Parallel_testPrepareActionsExecutedInParallel(t *testing.T) {
11581158
}
11591159

11601160
func TestSpec_Context_nonParallelTestExecutionOrder_isRandom(t *testing.T) {
1161-
assert.Eventually{RetryStrategy: assert.Waiter{WaitDuration: time.Second}}.Assert(t, func(it assert.It) {
1161+
assert.Retry{Strategy: assert.Waiter{WaitDuration: time.Second}}.Assert(t, func(it assert.It) {
11621162
var m sync.Mutex
11631163
out := make([]int, 0)
11641164
testcase.NewSpec(it).Context("", func(s *testcase.Spec) {

T.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ func (t *T) hasOnLetHookApplied(name string) bool {
154154
return false
155155
}
156156

157-
var DefaultEventually = assert.Eventually{RetryStrategy: assert.Waiter{Timeout: 3 * time.Second}}
157+
var DefaultEventually = assert.Retry{Strategy: assert.Waiter{Timeout: 3 * time.Second}}
158158

159159
// Eventually helper allows you to write expectations to results that will only be eventually true.
160160
// A common scenario where using Eventually will benefit you is testing concurrent operations.

T_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ func TestT_HasTag(t *testing.T) {
343343

344344
func TestT_Random(t *testing.T) {
345345
randomGenerationWorks := func(t *testcase.T) {
346-
assert.Eventually{RetryStrategy: assert.Waiter{WaitDuration: time.Second}}.Assert(t, func(it assert.It) {
346+
assert.Retry{Strategy: assert.Waiter{WaitDuration: time.Second}}.Assert(t, func(it assert.It) {
347347
it.Must.True(0 < t.Random.Int())
348348
})
349349
}

assert/Asserter.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,3 +1049,17 @@ func (a Asserter) within(timeout time.Duration, blk func(context.Context)) bool
10491049
}
10501050
return atomic.LoadUint32(&done) == 1
10511051
}
1052+
1053+
func (a Asserter) Eventually(durationOrCount any, blk func(it It)) {
1054+
a.TB.Helper()
1055+
var retry Retry
1056+
switch v := durationOrCount.(type) {
1057+
case time.Duration:
1058+
retry = Retry{Strategy: Waiter{Timeout: v}}
1059+
case int:
1060+
retry = Retry{Strategy: RetryCount(v)}
1061+
default:
1062+
a.TB.Fatalf("%T is neither a duration or the number of times to retry", durationOrCount)
1063+
}
1064+
retry.Assert(a.TB, blk)
1065+
}

assert/Asserter_test.go

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,7 @@ func TestAsserter_Within(t *testing.T) {
12321232
})
12331233
assert.True(t, dtb.IsFailed)
12341234

1235-
assert.EventuallyWithin(3*time.Second).Assert(t, func(it assert.It) {
1235+
assert.MakeRetry(3*time.Second).Assert(t, func(it assert.It) {
12361236
it.Must.True(atomic.LoadInt32(&isCancelled) == 1)
12371237
})
12381238
})
@@ -1292,7 +1292,7 @@ func TestAsserter_NotWithin(t *testing.T) {
12921292
})
12931293
assert.False(t, dtb.IsFailed)
12941294

1295-
assert.EventuallyWithin(3*time.Second).Assert(t, func(it assert.It) {
1295+
assert.MakeRetry(3*time.Second).Assert(t, func(it assert.It) {
12961296
it.Must.True(atomic.LoadInt32(&isCancelled) == 1)
12971297
})
12981298
})
@@ -1965,3 +1965,68 @@ func TestRegisterEqual(t *testing.T) {
19651965
})
19661966
assert.False(t, dtb.IsFailed)
19671967
}
1968+
1969+
func TestAsserter_Eventually(t *testing.T) {
1970+
t.Run("happy - n times", func(t *testing.T) {
1971+
dtb := &doubles.TB{}
1972+
var ran int
1973+
sandbox.Run(func() {
1974+
subject := asserter(dtb)
1975+
var ok bool
1976+
subject.Eventually(2, func(it assert.It) {
1977+
ran++
1978+
if ok {
1979+
return // OK
1980+
}
1981+
ok = true
1982+
it.FailNow()
1983+
})
1984+
})
1985+
1986+
assert.False(t, dtb.IsFailed, "eventually pass")
1987+
})
1988+
t.Run("happy - n time duration", func(t *testing.T) {
1989+
dtb := &doubles.TB{}
1990+
sandbox.Run(func() {
1991+
subject := asserter(dtb)
1992+
tries := 128
1993+
subject.Eventually(time.Minute, func(it assert.It) {
1994+
tries--
1995+
if tries <= 0 {
1996+
return // OK
1997+
}
1998+
it.FailNow()
1999+
})
2000+
})
2001+
assert.False(t, dtb.IsFailed, "eventually pass")
2002+
})
2003+
t.Run("rainy - n times", func(t *testing.T) {
2004+
dtb := &doubles.TB{}
2005+
var tried int
2006+
sandbox.Run(func() {
2007+
subject := asserter(dtb)
2008+
subject.Eventually(2, func(it assert.It) {
2009+
tried++
2010+
it.FailNow()
2011+
})
2012+
})
2013+
assert.True(t, dtb.IsFailed, "eventually fail")
2014+
assert.NotEqual(t, tried, 0)
2015+
})
2016+
t.Run("rainy - n duration", func(t *testing.T) {
2017+
dtb := &doubles.TB{}
2018+
sandbox.Run(func() {
2019+
subject := asserter(dtb)
2020+
var ok bool
2021+
subject.Eventually(100*time.Millisecond, func(it assert.It) {
2022+
if ok {
2023+
return // OK which will never happen
2024+
}
2025+
ok = true
2026+
time.Sleep(150 * time.Millisecond)
2027+
it.FailNow()
2028+
})
2029+
})
2030+
assert.True(t, dtb.IsFailed, "eventually fail")
2031+
})
2032+
}

assert/Eventually.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,24 @@ import (
99
"go.llib.dev/testcase/internal/doubles"
1010
)
1111

12-
func EventuallyWithin[T time.Duration | int](durationOrCount T) Eventually {
12+
func MakeRetry[T time.Duration | int](durationOrCount T) Retry {
1313
switch v := any(durationOrCount).(type) {
1414
case time.Duration:
15-
return Eventually{RetryStrategy: Waiter{Timeout: v}}
15+
return Retry{Strategy: Waiter{Timeout: v}}
1616
case int:
17-
return Eventually{RetryStrategy: RetryCount(v)}
17+
return Retry{Strategy: RetryCount(v)}
1818
default:
19-
panic("invalid usage")
19+
panic("impossible usage")
2020
}
2121
}
2222

23-
// Eventually Automatically retries operations whose failure is expected under certain defined conditions.
23+
// Retry Automatically retries operations whose failure is expected under certain defined conditions.
2424
// This pattern enables fault-tolerance.
2525
//
26-
// A common scenario where using Eventually will benefit you is testing concurrent operations.
26+
// A common scenario where using Retry will benefit you is testing concurrent operations.
2727
// Due to the nature of async operations, one might need to wait
2828
// and observe the system with multiple tries before the outcome can be seen.
29-
type Eventually struct{ RetryStrategy RetryStrategy }
29+
type Retry struct{ Strategy RetryStrategy }
3030

3131
type RetryStrategy interface {
3232
// While implements the retry strategy looping part.
@@ -43,12 +43,12 @@ func (fn RetryStrategyFunc) While(condition func() bool) { fn(condition) }
4343
// In case expectations are failed, it will retry the assertion block using the RetryStrategy.
4444
// The last failed assertion results would be published to the received testing.TB.
4545
// Calling multiple times the assertion function block content should be a safe and repeatable operation.
46-
func (r Eventually) Assert(tb testing.TB, blk func(it It)) {
46+
func (r Retry) Assert(tb testing.TB, blk func(it It)) {
4747
tb.Helper()
4848
var lastRecorder *doubles.RecorderTB
4949

5050
isFailed := tb.Failed()
51-
r.RetryStrategy.While(func() bool {
51+
r.Strategy.While(func() bool {
5252
tb.Helper()
5353
lastRecorder = &doubles.RecorderTB{TB: tb}
5454
ro := sandbox.Run(func() {

assert/Eventually_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,25 @@ import (
1414
"go.llib.dev/testcase"
1515
)
1616

17-
func TestEventually(t *testing.T) {
18-
SpecEventually(t)
17+
func TestRetry(t *testing.T) {
18+
SpecRetry(t)
1919
}
2020

2121
func BenchmarkEventually(b *testing.B) {
22-
SpecEventually(b)
22+
SpecRetry(b)
2323
}
2424

25-
func SpecEventually(tb testing.TB) {
25+
func SpecRetry(tb testing.TB) {
2626
s := testcase.NewSpec(tb)
2727

2828
var (
2929
strategyWillRetry = testcase.Var[bool]{ID: `retry strategy will retry`}
3030
strategyStub = testcase.Let(s, func(t *testcase.T) *stubRetryStrategy {
3131
return &stubRetryStrategy{ShouldRetry: strategyWillRetry.Get(t)}
3232
})
33-
helper = testcase.Let(s, func(t *testcase.T) *assert.Eventually {
34-
return &assert.Eventually{
35-
RetryStrategy: strategyStub.Get(t),
33+
helper = testcase.Let(s, func(t *testcase.T) *assert.Retry {
34+
return &assert.Retry{
35+
Strategy: strategyStub.Get(t),
3636
}
3737
})
3838
)
@@ -353,8 +353,8 @@ func SpecEventually(tb testing.TB) {
353353
}
354354

355355
func TestRetry_Assert_failsOnceButThenPass(t *testing.T) {
356-
w := assert.Eventually{
357-
RetryStrategy: assert.Waiter{
356+
w := assert.Retry{
357+
Strategy: assert.Waiter{
358358
WaitDuration: 0,
359359
Timeout: 42 * time.Second,
360360
},
@@ -388,8 +388,8 @@ func TestRetry_Assert_failsOnceButThenPass(t *testing.T) {
388388

389389
func TestRetry_Assert_panic(t *testing.T) {
390390
rnd := random.New(random.CryptoSeed{})
391-
w := assert.Eventually{
392-
RetryStrategy: assert.RetryStrategyFunc(func(condition func() bool) {
391+
w := assert.Retry{
392+
Strategy: assert.RetryStrategyFunc(func(condition func() bool) {
393393
for condition() {
394394
}
395395
}),
@@ -488,11 +488,11 @@ func TestRetryCount_While(t *testing.T) {
488488
})
489489
}
490490

491-
func TestEventuallyWithin(t *testing.T) {
491+
func TestMakeRetry(t *testing.T) {
492492
t.Run("time.Duration", func(t *testing.T) {
493493
t.Run("on timeout", func(t *testing.T) {
494494
it := assert.MakeIt(t)
495-
e := assert.EventuallyWithin(time.Millisecond)
495+
e := assert.MakeRetry(time.Millisecond)
496496
dtb := &doubles.TB{}
497497

498498
t1 := time.Now()
@@ -506,7 +506,7 @@ func TestEventuallyWithin(t *testing.T) {
506506
})
507507
t.Run("within the time", func(t *testing.T) {
508508
it := assert.MakeIt(t)
509-
e := assert.EventuallyWithin(time.Millisecond)
509+
e := assert.MakeRetry(time.Millisecond)
510510
dtb := &doubles.TB{}
511511

512512
t1 := time.Now()
@@ -522,7 +522,7 @@ func TestEventuallyWithin(t *testing.T) {
522522
t.Run("retry count", func(t *testing.T) {
523523
t.Run("out of count", func(t *testing.T) {
524524
it := assert.MakeIt(t)
525-
e := assert.EventuallyWithin(3)
525+
e := assert.MakeRetry(3)
526526
dtb := &doubles.TB{}
527527

528528
e.Assert(dtb, func(it assert.It) {
@@ -534,7 +534,7 @@ func TestEventuallyWithin(t *testing.T) {
534534
t.Run("within the count", func(t *testing.T) {
535535
it := assert.MakeIt(t)
536536

537-
e := assert.EventuallyWithin(3)
537+
e := assert.MakeRetry(3)
538538
dtb := &doubles.TB{}
539539

540540
n := 3

0 commit comments

Comments
 (0)