-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclock.go
92 lines (73 loc) · 1.88 KB
/
clock.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// This is based on https://raw.githubusercontent.com/smartystreets/clock/master/clock.go
// but with some different implementation choices
package clock
import "time"
type NowCallbackFn func(int) time.Time
type SleepCallbackFn func(time.Duration)
type Clock struct {
index int
nowCallback NowCallbackFn
sleepCallback SleepCallbackFn
napDurations []time.Duration
}
func NewClock() *Clock {
return NewClockAt(time.Now())
}
func NewClockAt(instant time.Time) *Clock {
return NewClockFromCallbacks(NewDefaultSleeperCallbacks(instant))
}
func NewClockFromSlice(instants ...time.Time) *Clock {
return NewClockFromCallbacks(slicesNowFn(instants...), nil)
}
func slicesNowFn(instants ...time.Time) NowCallbackFn {
return func(i int) time.Time {
if i >= len(instants) {
panic("ran out of moments frozen in time")
} else {
return instants[i]
}
}
}
func NewClockFromCallbacks(nowFn NowCallbackFn, sleepFn SleepCallbackFn) *Clock {
return &Clock{
nowCallback: nowFn,
sleepCallback: sleepFn,
napDurations: []time.Duration{},
}
}
func NewDefaultSleeperCallbacks(start time.Time) (NowCallbackFn, SleepCallbackFn) {
sleeperNow := start
nowFn := func(i int) time.Time {
return sleeperNow
}
sleepFn := func(d time.Duration) {
sleeperNow = sleeperNow.Add(d)
}
return nowFn, sleepFn
}
func (c *Clock) Now() time.Time {
if c == nil {
return time.Now()
}
defer func() {
c.index++
}()
return c.nowCallback(c.index)
}
func (c *Clock) Sleep(duration time.Duration) {
if c == nil {
time.Sleep(duration)
} else if c.sleepCallback != nil {
c.sleepCallback(duration)
c.napDurations = append(c.napDurations, duration)
}
}
func (c *Clock) TimeSince(before time.Time) time.Duration {
return c.Now().Sub(before)
}
func (c *Clock) NapDurations() []time.Duration {
return c.napDurations
}
func (c *Clock) ClearNapDurations() {
c.napDurations = []time.Duration{}
}