Documentation
¶
Index ¶
- func Mocked(now time.Time, f func(mocked *TestImplementation))
- type AfterCall
- type AfterFuncCall
- type MockedTicker
- type MockedTimer
- type NewTickerCall
- type NewTimerCall
- type SleepCall
- type TestImplementation
- func (ti *TestImplementation) After(d time.Duration) <-chan time.Time
- func (ti *TestImplementation) AfterFunc(d time.Duration, f func()) timex.Timer
- func (ti *TestImplementation) NewTicker(d time.Duration) timex.Ticker
- func (ti *TestImplementation) NewTimer(d time.Duration) timex.Timer
- func (ti *TestImplementation) Now() time.Time
- func (ti *TestImplementation) RestoreDefaultImplementation()
- func (ti *TestImplementation) SetNow(now time.Time)
- func (ti *TestImplementation) Since(t time.Time) time.Duration
- func (ti *TestImplementation) Sleep(d time.Duration)
- func (ti *TestImplementation) TearDown()
- func (ti *TestImplementation) Until(t time.Time) time.Duration
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Mocked ¶
func Mocked(now time.Time, f func(mocked *TestImplementation))
Mocked mocks the current time and passes it to the provided function Afterwards, it restores the default implementation
Types ¶
type AfterCall ¶
type AfterCall struct { Mock *MockedTimer Duration time.Duration }
AfterCall is a call to a mocked After It relies on a MockedTimer which will never be stopped
type AfterFuncCall ¶
type AfterFuncCall struct { // Mock provides the underlying timer. Calling Trigger() on it will execute the function provided // in the calling goroutine Mock *MockedTimer Duration time.Duration // Function is the function provided, probably useless Function func() }
AfterFuncCall represents a call made to timex.AfterFunc
type MockedTicker ¶
type MockedTicker struct {
// contains filtered or unexported fields
}
MockedTicker implements a timex.Ticker and provides functions to control its behavior
func (*MockedTicker) Stop ¶
func (mt *MockedTicker) Stop()
Stop implements timex.Ticker, and it will close the channel provided by StoppedChan
func (*MockedTicker) StoppedChan ¶
func (mt *MockedTicker) StoppedChan() chan struct{}
StoppedChan will be closed once Stop is called
func (*MockedTicker) Tick ¶
func (mt *MockedTicker) Tick(t time.Time)
Tick will send the provided time through ticker.C()
type MockedTimer ¶
type MockedTimer struct {
// contains filtered or unexported fields
}
MockedTimer implements a timex.Timer and provides functions to control its behavior
func (*MockedTimer) Stop ¶
func (mt *MockedTimer) Stop() bool
Stop implements the timex.Timer, stop will not return until the value is set by StopValue()
func (*MockedTimer) StopValue ¶
func (mt *MockedTimer) StopValue(v bool)
StopValue sets the value to be returned by Stop(), it has to be called to allow that method to return It can be only called once
func (*MockedTimer) StoppedChan ¶
func (mt *MockedTimer) StoppedChan() chan struct{}
StoppedChan provides the channel that is closed when Stop() is called
func (*MockedTimer) Trigger ¶
func (mt *MockedTimer) Trigger(t time.Time)
Trigger for a usual Timer will send the provided time through timer.C(), If this was a AfterFunc call, then trigger will ignore the time provided and will call the scheduled function in the caller's goroutine
type NewTickerCall ¶
type NewTickerCall struct { Mock *MockedTicker Duration time.Duration }
NewTickerCall is a call to a mocked NewTicker
type NewTimerCall ¶
type NewTimerCall struct { Mock *MockedTimer Duration time.Duration }
NewTimerCall is a call to a mocked NewTimer
type SleepCall ¶
type SleepCall struct { // WakeUp allows calling goroutine to continue execution WakeUp func() Duration time.Duration }
SleepCall represents a call made to timex.Sleep
type TestImplementation ¶
type TestImplementation struct { SleepCalls chan SleepCall AfterCalls chan AfterCall AfterFuncCalls chan AfterFuncCall NewTickerCalls chan NewTickerCall NewTimerCalls chan NewTimerCall sync.RWMutex // contains filtered or unexported fields }
TestImplementation implements timex.Implementation for tests
func Mock ¶
func Mock(now time.Time) *TestImplementation
Mock mocks/stubs the timex functions so they return constant known values Also mocks the timex.AfterFunc, returning the calls made to it through a channel. It mocks Sleep too: the delayed function will just unlock the caller of Sleep.
func (*TestImplementation) After ¶
func (ti *TestImplementation) After(d time.Duration) <-chan time.Time
After returns a mocked timer
Example ¶
package main import ( "fmt" "sync" "time" "github.com/cabify/timex" "github.com/cabify/timex/timextest" ) var now = time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC) func main() { timextest.Mocked(now, func(mockedtimex *timextest.TestImplementation) { var value bool wg := sync.WaitGroup{} wg.Add(1) go func() { defer wg.Done() <-timex.After(time.Minute) value = false }() // Note that the race detector would usually complain about this read because it would be // racy with the test value = true (<-mockedtimex.AfterCalls).Mock.Trigger(time.Time{}) wg.Wait() fmt.Println(value) }) }
Output: false
func (*TestImplementation) AfterFunc ¶
func (ti *TestImplementation) AfterFunc(d time.Duration, f func()) timex.Timer
AfterFunc allows the AfterFunc mocking by pushing calls into ti.AfterFuncCalls
Example ¶
package main import ( "fmt" "time" "github.com/cabify/timex" "github.com/cabify/timex/timextest" ) var now = time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC) func main() { timextest.Mocked(now, func(mockedtimex *timextest.TestImplementation) { go func() { timex.AfterFunc(time.Second, func() { fmt.Println("This happens a second later") }) timex.AfterFunc(time.Hour, func() { fmt.Println("This happens an hour later") }) }() firstCall := <-mockedtimex.AfterFuncCalls fmt.Printf("First function is scheduled for %s\n", firstCall.Duration) secondCall := <-mockedtimex.AfterFuncCalls fmt.Printf("Second function is scheduled for %s\n", secondCall.Duration) firstCall.Mock.Trigger(now) secondCall.Mock.Trigger(now) }) }
Output: First function is scheduled for 1s Second function is scheduled for 1h0m0s This happens a second later This happens an hour later
func (*TestImplementation) NewTicker ¶
func (ti *TestImplementation) NewTicker(d time.Duration) timex.Ticker
NewTicker returns a mocked ticker
Example ¶
package main import ( "fmt" "time" "github.com/cabify/timex" "github.com/cabify/timex/timextest" ) var now = time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC) func main() { timextest.Mocked(now, func(mockedtimex *timextest.TestImplementation) { go func() { ticker := timex.NewTicker(time.Hour) for t := range ticker.C() { fmt.Printf("%s\n", t) } }() tickerCall := <-mockedtimex.NewTickerCalls tickerCall.Mock.Tick(now.Add(time.Second)) tickerCall.Mock.Tick(now.Add(2 * time.Second)) }) }
Output: 2009-11-10 23:00:01 +0000 UTC 2009-11-10 23:00:02 +0000 UTC
func (*TestImplementation) NewTimer ¶
func (ti *TestImplementation) NewTimer(d time.Duration) timex.Timer
NewTimer returns a mocked timer
Example ¶
package main import ( "fmt" "sync" "time" "github.com/cabify/timex" "github.com/cabify/timex/timextest" ) var now = time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC) func main() { timextest.Mocked(now, func(mockedtimex *timextest.TestImplementation) { wg := sync.WaitGroup{} wg.Add(1) go func(d time.Duration) { defer wg.Done() ticker := timex.NewTimer(d) t := <-ticker.C() fmt.Println(t) }(time.Minute) timer := <-mockedtimex.NewTimerCalls timer.Mock.Trigger(now.Add(timer.Duration)) wg.Wait() }) }
Output: 2009-11-10 23:01:00 +0000 UTC
func (*TestImplementation) Now ¶
func (ti *TestImplementation) Now() time.Time
Now returns always the same now
Example ¶
package main import ( "fmt" "time" "github.com/cabify/timex" "github.com/cabify/timex/timextest" ) var now = time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC) func main() { timextest.Mocked(now, func(mockedtimex *timextest.TestImplementation) { fmt.Println(timex.Now()) }) }
Output: 2009-11-10 23:00:00 +0000 UTC
func (*TestImplementation) RestoreDefaultImplementation ¶
func (ti *TestImplementation) RestoreDefaultImplementation()
RestoreDefaultImplementation restores timex default implementation
func (*TestImplementation) SetNow ¶
func (ti *TestImplementation) SetNow(now time.Time)
SetNow updates Now() value to a newer one
Example ¶
package main import ( "fmt" "time" "github.com/cabify/timex" "github.com/cabify/timex/timextest" ) var now = time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC) func main() { timextest.Mocked(now, func(mockedtimex *timextest.TestImplementation) { mockedtimex.SetNow(time.Unix(1, 0).UTC()) fmt.Println(timex.Now()) }) }
Output: 1970-01-01 00:00:01 +0000 UTC
func (*TestImplementation) Since ¶
func (ti *TestImplementation) Since(t time.Time) time.Duration
Since returns the duration elapsed since mocked `now`
Example ¶
package main import ( "fmt" "time" "github.com/cabify/timex" "github.com/cabify/timex/timextest" ) var now = time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC) func main() { timextest.Mocked(now, func(mockedtimex *timextest.TestImplementation) { fmt.Println(timex.Since(now.Add(-time.Hour))) }) }
Output: 1h0m0s
func (*TestImplementation) Sleep ¶
func (ti *TestImplementation) Sleep(d time.Duration)
Sleep sleeps until WakeUp is called
Example ¶
ExampleTestImplementation_Sleep observes the execution of a tempSwitch that uses timex.Sleep To change the state of the program just temporarily This way the assertions are deterministic and we don't have to wait the real amount of time
package main import ( "fmt" "sync/atomic" "time" "github.com/cabify/timex" "github.com/cabify/timex/timextest" ) var now = time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC) func main() { timextest.Mocked(now, func(mockedtimex *timextest.TestImplementation) { sw := tempSwitch{new(int64)} done := make(chan struct{}) // Check it's turned off fmt.Printf("First state of switch is %t\n", sw.IsTurnedOn()) go func() { sw.TurnOn() close(done) }() // Wait until the program is sleeping sleepCall := <-mockedtimex.SleepCalls // Check it's turned on fmt.Printf("Then it's temporarily %t\n", sw.IsTurnedOn()) // Let it wake up and wait until TurnOn call finishes execution sleepCall.WakeUp() <-done // Check it's turned off again fmt.Printf("And then it's %t again\n", sw.IsTurnedOn()) }) } type tempSwitch struct{ val *int64 } func (ts tempSwitch) TurnOn() { atomic.AddInt64(ts.val, 1) timex.Sleep(time.Hour) atomic.AddInt64(ts.val, -1) } func (ts tempSwitch) IsTurnedOn() bool { return atomic.LoadInt64(ts.val) == 1 }
Output: First state of switch is false Then it's temporarily true And then it's false again
func (*TestImplementation) TearDown ¶
func (ti *TestImplementation) TearDown()
TearDown closes all the channels on the test implementation. Useful to terminate goroutines watching those channels.
func (*TestImplementation) Until ¶
func (ti *TestImplementation) Until(t time.Time) time.Duration
Until returns the duration until mocked `now`
Example ¶
package main import ( "fmt" "time" "github.com/cabify/timex" "github.com/cabify/timex/timextest" ) var now = time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC) func main() { timextest.Mocked(now, func(mockedtimex *timextest.TestImplementation) { fmt.Println(timex.Until(now.Add(time.Minute))) }) }
Output: 1m0s