# package clock - github.com/tilinna/clock - godocs.io ``` import "github.com/tilinna/clock" ``` Package clock implements a library for mocking time. ### Usage Include a Clock variable on your application and initialize it with a Realtime() by default. Then use the Clock for all time-related API calls. So instead of time.NewTimer(), say myClock.NewTimer(). On a test setup, override or inject the variable with a Mock instance and use it to control how the time behaves during each test phase. To mock context.WithTimeout and context.WithDeadline, use the included Context, TimeoutContext and DeadlineContext methods. The Context method is also useful in cases where you need to pass a Clock via an 'func(ctx Context, ..)' API you can't change yourself. The FromContext method will then return the associated Clock instance. Alternatively, use the context'ed methods like Sleep(ctx) directly. All methods are safe for concurrent use. ## Functions ### func After ``` func After(ctx context.Context, d time.Duration) <-chan time.Time ``` After is a convenience wrapper for FromContext(ctx).After. ### func Context ``` func Context(parent context.Context, c Clock) context.Context ``` Context returns a copy of parent in which the Clock is associated with. ### func DeadlineContext ``` func DeadlineContext(ctx context.Context, d time.Time) (context.Context, context.CancelFunc) ``` DeadlineContext is a convenience wrapper for FromContext(ctx).DeadlineContext. ### func Now ``` func Now(ctx context.Context) time.Time ``` Now is a convenience wrapper for FromContext(ctx).Now. ### func Since ``` func Since(ctx context.Context, t time.Time) time.Duration ``` Since is a convenience wrapper for FromContext(ctx).Since. ### func Sleep ``` func Sleep(ctx context.Context, d time.Duration) ``` Sleep is a convenience wrapper for FromContext(ctx).Sleep. ### func Tick ``` func Tick(ctx context.Context, d time.Duration) <-chan time.Time ``` Tick is a convenience wrapper for FromContext(ctx).Tick. ### func TimeoutContext ``` func TimeoutContext(ctx context.Context, timeout time.Duration) (context.Context, context.CancelFunc) ``` TimeoutContext is a convenience wrapper for FromContext(ctx).TimeoutContext. ### func Until ``` func Until(ctx context.Context, t time.Time) time.Duration ``` Until is a convenience wrapper for FromContext(ctx).Until. ## Types ### type Clock ``` type Clock interface { After(d time.Duration) <-chan time.Time AfterFunc(d time.Duration, f func()) *Timer NewTicker(d time.Duration) *Ticker NewTimer(d time.Duration) *Timer Now() time.Time Since(t time.Time) time.Duration Sleep(d time.Duration) Tick(d time.Duration) <-chan time.Time Until(t time.Time) time.Duration // DeadlineContext returns a copy of the parent context with the associated // Clock deadline adjusted to be no later than d. DeadlineContext(parent context.Context, d time.Time) (context.Context, context.CancelFunc) // TimeoutContext returns DeadlineContext(parent, Now(parent).Add(timeout)). TimeoutContext(parent context.Context, timeout time.Duration) (context.Context, context.CancelFunc) } ``` Clock represents an interface to the functions in the standard time and context packages. ### func FromContext ``` func FromContext(ctx context.Context) Clock ``` FromContext returns the Clock associated with the context, or Realtime(). ### func Realtime ``` func Realtime() Clock ``` Realtime returns the standard real-time Clock. ### type Mock ``` type Mock struct { sync.Mutex // contains filtered or unexported fields } ``` Mock implements a Clock that only moves with Add, AddNext and Set. The clock can be suspended with Lock and resumed with Unlock. While suspended, all attempts to use the API will block. To increase predictability, all Mock methods acquire and release the Mutex only once during their execution. ### func NewMock ``` func NewMock(now time.Time) *Mock ``` NewMock returns a new Mock with current time set to now. Use Realtime to get the real-time Clock. ### Example Code: ``` package main import ( "fmt" "time" "github.com/tilinna/clock" ) func main() { // Use clock.Realtime() in production mock := clock.NewMock(time.Date(2018, 1, 1, 10, 0, 0, 0, time.UTC)) fmt.Println("Time is now", mock.Now()) timer := mock.NewTimer(15 * time.Second) mock.Add(25 * time.Second) fmt.Println("Time is now", mock.Now()) fmt.Println("Timeout was", <-timer.C) } ``` Output: ``` Time is now 2018-01-01 10:00:00 +0000 UTC Time is now 2018-01-01 10:00:25 +0000 UTC Timeout was 2018-01-01 10:00:15 +0000 UTC ``` ### func (*Mock) Add ``` func (m *Mock) Add(d time.Duration) time.Time ``` Add advances the current time by duration d and fires all expired timers. Returns the new current time. To increase predictability and speed, Tickers are ticked only once per call. ### func (*Mock) AddNext ``` func (m *Mock) AddNext() (time.Time, time.Duration) ``` AddNext advances the current time to the next available timer deadline and fires all expired timers. Returns the new current time and the advanced duration. ### Example Code: ``` package main import ( "fmt" "strconv" "strings" "time" "github.com/tilinna/clock" ) func main() { start := time.Now() mock := clock.NewMock(start) mock.Tick(1 * time.Second) fizz := mock.Tick(3 * time.Second) buzz := mock.Tick(5 * time.Second) var items []string for i := 0; i < 20; i++ { mock.AddNext() var item string select { case <-fizz: select { case <-buzz: item = "FizzBuzz" default: item = "Fizz" } default: select { case <-buzz: item = "Buzz" default: item = strconv.Itoa(int(mock.Since(start) / time.Second)) } } items = append(items, item) } fmt.Println(strings.Join(items, " ")) } ``` Output: ``` 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz ``` ### func (*Mock) After ``` func (m *Mock) After(d time.Duration) <-chan time.Time ``` After waits for the duration to elapse and then sends the current time on the returned channel. A negative or zero duration fires the underlying timer immediately. ### func (*Mock) AfterFunc ``` func (m *Mock) AfterFunc(d time.Duration, f func()) *Timer ``` AfterFunc waits for the duration to elapse and then calls f in its own goroutine. It returns a Timer that can be used to cancel the call using its Stop method. A negative or zero duration fires the timer immediately. ### func (*Mock) DeadlineContext ``` func (m *Mock) DeadlineContext(parent context.Context, d time.Time) (context.Context, context.CancelFunc) ``` DeadlineContext implements Clock. ### Example Code: ``` package main import ( "context" "fmt" "time" "github.com/tilinna/clock" ) func main() { start := time.Date(2018, 1, 1, 10, 0, 0, 0, time.UTC) mock := clock.NewMock(start) fmt.Println("now:", mock.Now()) ctx, cfn := mock.DeadlineContext(context.Background(), start.Add(time.Hour)) defer cfn() fmt.Println("err:", ctx.Err()) dl, _ := ctx.Deadline() mock.Set(dl) fmt.Println("now:", clock.Now(ctx)) <-ctx.Done() fmt.Println("err:", ctx.Err()) } ``` Output: ``` now: 2018-01-01 10:00:00 +0000 UTC err: now: 2018-01-01 11:00:00 +0000 UTC err: context deadline exceeded ``` ### func (*Mock) Len ``` func (m *Mock) Len() int ``` Len returns the number of active timers. ### func (*Mock) NewTicker ``` func (m *Mock) NewTicker(d time.Duration) *Ticker ``` NewTicker returns a new Ticker containing a channel that will send the current time with a period specified by the duration d. ### func (*Mock) NewTimer ``` func (m *Mock) NewTimer(d time.Duration) *Timer ``` NewTimer creates a new Timer that will send the current time on its channel after at least duration d. A negative or zero duration fires the timer immediately. ### func (*Mock) Now ``` func (m *Mock) Now() time.Time ``` Now returns the current mocked time. ### func (*Mock) Set ``` func (m *Mock) Set(t time.Time) time.Duration ``` Set advances the current time to t and fires all expired timers. Returns the advanced duration. To increase predictability and speed, Tickers are ticked only once per call. ### func (*Mock) Since ``` func (m *Mock) Since(t time.Time) time.Duration ``` Since returns the time elapsed since t. ### func (*Mock) Sleep ``` func (m *Mock) Sleep(d time.Duration) ``` Sleep pauses the current goroutine for at least the duration d. A negative or zero duration causes Sleep to return immediately. ### func (*Mock) Tick ``` func (m *Mock) Tick(d time.Duration) <-chan time.Time ``` Tick is a convenience wrapper for NewTicker providing access to the ticking channel only. ### func (*Mock) TimeoutContext ``` func (m *Mock) TimeoutContext(parent context.Context, timeout time.Duration) (context.Context, context.CancelFunc) ``` TimeoutContext implements Clock. ### func (*Mock) Until ``` func (m *Mock) Until(t time.Time) time.Duration ``` Until returns the duration until t. ### type Ticker ``` type Ticker struct { C <-chan time.Time // contains filtered or unexported fields } ``` Ticker represents a time.Ticker. ### func NewTicker ``` func NewTicker(ctx context.Context, d time.Duration) *Ticker ``` NewTicker is a convenience wrapper for FromContext(ctx).NewTicker. ### func (*Ticker) Stop ``` func (t *Ticker) Stop() ``` Stop turns off a ticker. After Stop, no more ticks will be sent. ### type Timer ``` type Timer struct { C <-chan time.Time // contains filtered or unexported fields } ``` Timer represents a time.Timer. ### func AfterFunc ``` func AfterFunc(ctx context.Context, d time.Duration, f func()) *Timer ``` AfterFunc is a convenience wrapper for FromContext(ctx).AfterFunc. ### func NewTimer ``` func NewTimer(ctx context.Context, d time.Duration) *Timer ``` NewTimer is a convenience wrapper for FromContext(ctx).NewTimer. ### func (*Timer) Reset ``` func (t *Timer) Reset(d time.Duration) bool ``` Reset changes the timer to expire after duration d. It returns true if the timer had been active, false if the timer had expired or been stopped. A negative or zero duration fires the timer immediately. ### func (*Timer) Stop ``` func (t *Timer) Stop() bool ``` Stop prevents the Timer from firing. It returns true if the call stops the timer, false if the timer has already expired or been stopped. ## Details => ?view=versions Version: v1.1.0 (latest) * Published: Feb 18, 2021 => ?view=platforms Platform: linux/amd64 => ?view=imports Imports: 5 packages * Last checked: 2 weeks ago => /-/refresh?import_path=github.com/tilinna/clock&platform=linux/amd64 Refresh now => / Back to home => /-/search Search