diff --git a/time2/const.go b/time2/const.go new file mode 100644 index 0000000..b02c4e4 --- /dev/null +++ b/time2/const.go @@ -0,0 +1,16 @@ +package time2 + +import ( + "time" +) + +const ( + // Day is a 24 hour long duration. + Day = 24 * time.Hour + // Week is a 7 days long duration. + Week = 7 * Day + // Month is a 30 days long duration. + Month = 30 * Day + // Year is a 365 days long duration. + Year = 365 * Day +) diff --git a/time2/stop.go b/time2/stop.go new file mode 100644 index 0000000..a1731f6 --- /dev/null +++ b/time2/stop.go @@ -0,0 +1,71 @@ +package time2 + +import ( + "sync" + "time" +) + +var ( + stopMux sync.RWMutex + stoppedFor time.Duration + stoppedAt *time.Time + + // Now returns current time. For testing aid it could be replaced with a + // stoppable implementation. + Now = time.Now +) + +// InstrumentNow extends the package with a testing suitable implementation of +// the Now function. This function is supposed to be called at the beginning of +// a test suite. +func InstrumentNow() { + Now = stoppableNow +} + +// RestoreNow resets Now implementaion to the one from standard library. I have +// no clue if it's going to be useful or not. +func RestoreNow() { + Now = time.Now +} + +// stoppableNow returns current time taking time manipulation into account. +func stoppableNow() time.Time { + stopMux.RLock() + defer stopMux.RUnlock() + + if stoppedAt != nil { + return *stoppedAt + } + return time.Now().Add(-stoppedFor) +} + +// Stop makes the time stop. +func Stop() { + stopMux.Lock() + if stoppedAt != nil { + panic("Time was already stopped") + } + now := Now() + stoppedAt = &now + stopMux.Unlock() +} + +// Resume makes the time go again. +func Resume() { + stopMux.Lock() + if stoppedAt == nil { + panic("Time was not stopped") + } + stoppedFor += time.Since(*stoppedAt) + stoppedAt = nil + stopMux.Unlock() +} + +// Reset makes it appear like time was never been frozen. Call this function +// at the beginning of every test case. +func Reset() { + stopMux.Lock() + stoppedAt = nil + stoppedFor = 0 + stopMux.Unlock() +}