Skip to content

Commit

Permalink
Add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
rentziass committed Mar 22, 2023
1 parent 0b20ff8 commit 455793b
Showing 1 changed file with 80 additions and 34 deletions.
114 changes: 80 additions & 34 deletions eventually.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ type Eventually struct {
maxAttempts int
}

// New creates a new Eventually with the given options. This can be useful if you want to reuse the same
// configuration for multiple functions. For example:
//
// e := eventually.New(eventually.WithMaxAttempts(10))
//
// The returned Eventually has the following defaults unless otherwise specified:
//
// Timeout: 10 seconds
// Interval: 100 milliseconds
// MaxAttempts: 0 (unlimited)
//
// If you don't need to reuse the same configuration, you can use the [Must] and [Should] functions directly.
func New(options ...Option) *Eventually {
e := &Eventually{
timeout: 10 * time.Second,
Expand All @@ -25,13 +37,27 @@ func New(options ...Option) *Eventually {
return e
}

// Must will keep retrying the given function f until the testing.TB passed to
// it does not fail or one of the following conditions is met:
//
// - the timeout is reached
// - the maximum number of attempts is reached
//
// If f does not succed, Must will halt the test calling t.Fatalf.
func (e *Eventually) Must(t testing.TB, f func(t testing.TB)) {
t.Helper()

r := e.retryableT(t)
keepTrying(t, r, f, t.Fatalf)
}

// Should will keep retrying the given function f until the testing.TB passed to
// it does not fail or one of the following conditions is met:
//
// - the timeout is reached
// - the maximum number of attempts is reached
//
// If f does not succed, Should will fail the test calling t.Errorf.
func (e *Eventually) Should(t testing.TB, f func(t testing.TB)) {
t.Helper()

Expand All @@ -48,6 +74,60 @@ func (e *Eventually) retryableT(t testing.TB) *retryableT {
}
}

// Option is a function that can be used to configure an Eventually.
type Option func(*Eventually)

// WithTimeout sets the timeout for an Eventually.
func WithTimeout(timeout time.Duration) Option {
return func(e *Eventually) {
e.timeout = timeout
}
}

// WithInterval sets the interval Eventually will wait between attempts.
func WithInterval(interval time.Duration) Option {
return func(e *Eventually) {
e.interval = interval
}
}

// WithMaxAttempts sets the maximum number of attempts an Eventually will make.
func WithMaxAttempts(attempts int) Option {
return func(e *Eventually) {
e.maxAttempts = attempts
}
}

// Must will keep retrying the given function f until the testing.TB passed to
// it does not fail or one of the following conditions is met:
//
// - the timeout is reached
// - the maximum number of attempts is reached
//
// If f does not succed, Must will halt the test calling t.Fatalf.
// Must behaviour can be changed by passing options to it.
func Must(t testing.TB, f func(t testing.TB), options ...Option) {
t.Helper()

e := New(options...)
e.Must(t, f)
}

// Should will keep retrying the given function f until the testing.TB passed to
// it does not fail or one of the following conditions is met:
//
// - the timeout is reached
// - the maximum number of attempts is reached
//
// If f does not succed, Should will fail the test calling t.Errorf.
// Should behaviour can be changed by passing options to it.
func Should(t testing.TB, f func(t testing.TB), options ...Option) {
t.Helper()

e := New(options...)
e.Should(t, f)
}

type failNowPanic struct{}

type retryableT struct {
Expand Down Expand Up @@ -99,40 +179,6 @@ func (r *retryableT) Fatalf(format string, args ...any) {
r.FailNow()
}

type Option func(*Eventually)

func WithTimeout(timeout time.Duration) Option {
return func(e *Eventually) {
e.timeout = timeout
}
}

func WithInterval(interval time.Duration) Option {
return func(e *Eventually) {
e.interval = interval
}
}

func WithMaxAttempts(attempts int) Option {
return func(e *Eventually) {
e.maxAttempts = attempts
}
}

func Must(t testing.TB, f func(t testing.TB), options ...Option) {
t.Helper()

e := New(options...)
e.Must(t, f)
}

func Should(t testing.TB, f func(t testing.TB), options ...Option) {
t.Helper()

e := New(options...)
e.Should(t, f)
}

func keepTrying(t testing.TB, retryable *retryableT, f func(t testing.TB), failf func(format string, args ...any)) {
t.Helper()

Expand Down

0 comments on commit 455793b

Please sign in to comment.