flextime

package module
Version: v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2020 License: MIT Imports: 4 Imported by: 11

README

flextime

Test Status Coverage Status MIT License GoDoc

flextime improves time testability by replacing the backend clock flexibly.

Synopsis

import "github.com/Songmu/flextime"

now := flextime.Now() // returned normal current time by default
flextime.Sleep()
d := flextime.Until(date)
d := flextime.Since(date)
<-flextime.After(5*time.Second)
flextime.AfterFunc(5*time.Second, func() { fmt.Println("Done") })
timer := flextime.NewTimer(10*time.Second)
ticker := flextime.NewTicker(10*time.Second)
ch := flextime.Tick(3*time.Second)

func () { // Set time
    restore := flextime.Set(time.Date(2001, time.May, 1, 10, 10, 10, 0, time.UTC))
    defer restore()

    now = flextime.Now() // returned set time
}()

func () { // Fix time
    restore := flextime.Fix(time.Date(2001, time.May, 1, 10, 10, 10, 0, time.UTC))
    defer restore()

    now = flextime.Now() // returned fixed time
}()

Description

The flextime improves time testability by replacing the backend clock flexibly.

It has a set of functions similar to the standard time package, making it easy to migrate from standard time package.

By default, it behaves the same as the standard time package, but allows us to change or fix the current time by using Fix and Set function.

Also, we can replace the backend clock by implementing our own Clock interface and combining it with the Switch function.

Installation

% go get github.com/Songmu/flextime

Migration

You can almost migrate from standard time package to Songmu/flextime with the following command.

% go get github.com/Songmu/flextime
% find . -name '*.go' | xargs perl -i -pe 's/\btime\.((?:N(?:ewTi(?:ck|m)er|ow)|After(?:Func)?|Sleep|Until|Tick))/flextime.$1/g'
% goimport -w .

Author

Songmu

Documentation

Overview

Package flextime improves time testability by replacing the backend clock flexibly.

It has a set of following 9 functions similar to the standard time package, making it easy to migrate from standard time package.

now := flextime.Now()
flextime.Sleep()
d := flextime.Until(date)
d := flextime.Since(date)
<-flextime.After(5*time.Second)
flextime.AfterFunc(5*time.Second, func() { fmt.Println("Done") })
timer := flextime.NewTimer(10*time.Second)
ticker := flextime.NewTicker(10*time.Second)
ch := flextime.Tick(3*time.Second)

By default, it behaves the same as the standard time package, but allows us to change or fix the current time by using `Fix` and `Set` function.

func () { // Set time
	restore := flextime.Set(time.Date(2001, time.May, 1, 10, 10, 10, 0, time.UTC))
	defer restore()

	now = flextime.Now() // returned set time
}()

func () { // Fix time
	restore := flextime.Fix(time.Date(2001, time.May, 1, 10, 10, 10, 0, time.UTC))
	defer restore()

	now = flextime.Now() // returned fixed time
}()

Also, we can replace the backend clock by implementing our own `Clock` interface and combining it with the Switch function.

restore := flextime.Switch(clock)
defer restore()

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func After

func After(d time.Duration) <-chan time.Time

After waits for the duration to elapse and then sends the current time on the returned channel using backend Clock.

func Fix

func Fix(t time.Time) (restore func())

Fix switches backend Clock and fixes the current time to the specified time. This differs from `Set` in that the time does not change even if the time elapses during the test. However, when Sleep is called, the virtual time is passed without actually pausing. It returns a restore func and we can restore time behavior by calling it after the test.

func Now

func Now() time.Time

Now returns the current time from backend Clock.

func NowFunc added in v0.1.0

func NowFunc(now func() time.Time) (restore func())

NowFunc simply replace the function to get faked current time

func Restore

func Restore()

Restore the default real Clock

func Set

func Set(t time.Time) (restore func())

Set switches backend Clock and sets the current time to the specified time. It internally holds the offset and is affected by the passage of time during the test. When Sleep is called, the virtual time is passed without actually pausing. It returns a restore func and we can restore time behavior by calling it after the test.

func Since

func Since(t time.Time) time.Duration

Since returns the time elapsed since t using backend Clock.

func Sleep

func Sleep(d time.Duration)

Sleep pauses the current process for at least the duration d using backend Clock.

func Switch

func Switch(c Clock) (restore func())

Switch switches backend Clock. Is it useful for testing.

func Tick

func Tick(d time.Duration) <-chan time.Time

Tick is a convenience wrapper for NewTicker providing access to the ticking channel only using backend Clock.

func Until

func Until(t time.Time) time.Duration

Until returns the duration until t using backend Clock.

Types

type Clock

type Clock interface {
	Now() time.Time
	Sleep(d time.Duration)
	Since(t time.Time) time.Duration
	Until(t time.Time) time.Duration

	After(d time.Duration) <-chan time.Time
	AfterFunc(d time.Duration, f func()) *Timer
	NewTimer(d time.Duration) *Timer
	NewTicker(d time.Duration) *Ticker
	Tick(d time.Duration) <-chan time.Time
}

Clock is an interface that implements the functions of the standard time package

func NewFakeClock

func NewFakeClock(ns NowSleeper) Clock

NewFakeClock accepts a NowSleeper interface and returns an object with a Clock interface.

type NowSleeper

type NowSleeper interface {
	Now() time.Time
	Sleep(d time.Duration)
}

NowSleeper is, as the name implies, an interface with Now and Sleep methods. By simply implementing these two methods, we can create an object with a Clock interface by combining it with the NewFakeClock function.

type Ticker

type Ticker struct {
	C <-chan time.Time
	// contains filtered or unexported fields
}

A Ticker holds a channel that delivers `ticks' of a clock at intervals. It has same API with time.Ticker

func NewTicker

func NewTicker(d time.Duration) *Ticker

NewTicker returns a new Ticker containing a channel that will send the time with a period specified by the duration argument using backend Clock.

func (*Ticker) Reset added in v0.1.0

func (ti *Ticker) Reset(d time.Duration)

Reset stops a ticker and resets its period to the specified duration The next tick will arrive after the new period elapses.

func (*Ticker) Stop

func (ti *Ticker) Stop()

Stop turns off a ticker.

type Timer

type Timer struct {
	C <-chan time.Time
	// contains filtered or unexported fields
}

The Timer type represents a single event. It has same API with time.Timer

func AfterFunc

func AfterFunc(d time.Duration, f func()) *Timer

AfterFunc waits for the duration to elapse and then calls f in its own goroutine using backend Clock. It returns a Timer that can be used to cancel the call using its Stop method.

func NewTimer

func NewTimer(d time.Duration) *Timer

NewTimer creates a new Timer that will send the current time on its channel after at least duration d using backend Clock.

func (*Timer) Reset

func (ti *Timer) Reset(d time.Duration) bool

Reset changes the timer to expire after duration d.

func (*Timer) Stop

func (ti *Timer) Stop() bool

Stop prevents the Timer from firing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL