1
0
times/test.go

103 lines
1.5 KiB
Go
Raw Normal View History

2026-03-04 21:11:49 +01:00
package times
import (
"time"
"sort"
)
type clockState struct {
current time.Time
chans map[time.Time][]chan<- time.Time
chantlist []time.Time
}
type test struct {
state chan clockState
}
func makeTestClock(initial time.Time) test {
s := make(chan clockState, 1)
s <- clockState{
current: initial,
chans: make(map[time.Time][]chan<- time.Time),
}
return test{state: s}
}
func triggerChans(s clockState) clockState {
for len(s.chantlist) > 0 && !s.chantlist[0].After(s.current) {
var ct time.Time
ct, s.chantlist = s.chantlist[0], s.chantlist[1:]
for _, c := range s.chans[ct] {
c <- s.current
}
delete(s.chans, ct)
}
return s
}
func (t test) now() time.Time {
s := <-t.state
defer func() {
t.state <- s
}()
return s.current
}
func (t test) after(d time.Duration) <-chan time.Time {
s := <-t.state
defer func() {
t.state <- s
}()
c := make(chan time.Time, 1)
ct := s.current.Add(d)
if !ct.After(s.current) {
c <- s.current
return c
}
_, ctset := s.chans[ct]
s.chans[ct] = append(s.chans[ct], c)
if !ctset {
s.chantlist = append(s.chantlist, ct)
sort.Slice(s.chantlist, func(i, j int) bool {
return s.chantlist[i].Before(s.chantlist[j])
})
}
return c
}
func (t test) pass(d time.Duration) {
s := <-t.state
defer func() {
t.state <- s
}()
if d < 0 {
d = 0
}
s.current = s.current.Add(d)
s = triggerChans(s)
}
func (t test) jump(to time.Time) {
s := <-t.state
defer func() {
t.state <- s
}()
if to.Before(s.current) {
return
}
s.current = to
s = triggerChans(s)
}