mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-02 03:28:28 -04:00
68d5d7c5ed
fixes #1010
180 lines
4.7 KiB
Go
180 lines
4.7 KiB
Go
package wallpaper
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestParseHHMM(t *testing.T) {
|
|
cases := []struct {
|
|
in string
|
|
hour int
|
|
minute int
|
|
ok bool
|
|
}{
|
|
{"06:00", 6, 0, true},
|
|
{"23:59", 23, 59, true},
|
|
{"00:00", 0, 0, true},
|
|
{"24:00", 0, 0, false},
|
|
{"6:5", 6, 5, true},
|
|
{"bad", 0, 0, false},
|
|
{"12", 0, 0, false},
|
|
{"12:60", 0, 0, false},
|
|
}
|
|
for _, c := range cases {
|
|
hour, minute, ok := parseHHMM(c.in)
|
|
if ok != c.ok || (ok && (hour != c.hour || minute != c.minute)) {
|
|
t.Errorf("parseHHMM(%q) = (%d, %d, %v), want (%d, %d, %v)", c.in, hour, minute, ok, c.hour, c.minute, c.ok)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestComputeNextInterval(t *testing.T) {
|
|
now := time.Date(2026, 6, 30, 12, 0, 0, 0, time.UTC)
|
|
got := computeNext(now, ScheduleConfig{Mode: "interval", IntervalSec: 300})
|
|
if want := now.Add(300 * time.Second); !got.Equal(want) {
|
|
t.Errorf("interval next = %v, want %v", got, want)
|
|
}
|
|
|
|
clamped := computeNext(now, ScheduleConfig{Mode: "interval", IntervalSec: 0})
|
|
if want := now.Add(time.Second); !clamped.Equal(want) {
|
|
t.Errorf("interval clamp = %v, want %v", clamped, want)
|
|
}
|
|
}
|
|
|
|
func TestComputeNextTime(t *testing.T) {
|
|
now := time.Date(2026, 6, 30, 12, 0, 0, 0, time.UTC)
|
|
|
|
later := computeNext(now, ScheduleConfig{Mode: "time", Time: "18:00"})
|
|
if want := time.Date(2026, 6, 30, 18, 0, 0, 0, time.UTC); !later.Equal(want) {
|
|
t.Errorf("time next (today) = %v, want %v", later, want)
|
|
}
|
|
|
|
tomorrow := computeNext(now, ScheduleConfig{Mode: "time", Time: "06:00"})
|
|
if want := time.Date(2026, 7, 1, 6, 0, 0, 0, time.UTC); !tomorrow.Equal(want) {
|
|
t.Errorf("time next (tomorrow) = %v, want %v", tomorrow, want)
|
|
}
|
|
}
|
|
|
|
func TestActiveSchedules(t *testing.T) {
|
|
global := activeSchedules(Config{
|
|
Global: ScheduleConfig{Enabled: true, Mode: "interval", IntervalSec: 60},
|
|
})
|
|
if len(global) != 1 {
|
|
t.Fatalf("global active = %d, want 1", len(global))
|
|
}
|
|
if _, ok := global[""]; !ok {
|
|
t.Errorf("global active missing global key")
|
|
}
|
|
|
|
perMonitor := activeSchedules(Config{
|
|
PerMonitor: true,
|
|
Global: ScheduleConfig{Enabled: true},
|
|
Monitors: map[string]ScheduleConfig{
|
|
"DP-1": {Enabled: true, Mode: "interval", IntervalSec: 60},
|
|
"DP-2": {Enabled: false},
|
|
},
|
|
})
|
|
if len(perMonitor) != 1 {
|
|
t.Fatalf("per-monitor active = %d, want 1", len(perMonitor))
|
|
}
|
|
if _, ok := perMonitor["DP-1"]; !ok {
|
|
t.Errorf("per-monitor active missing DP-1")
|
|
}
|
|
}
|
|
|
|
func TestPrevDailyTime(t *testing.T) {
|
|
now := time.Date(2026, 6, 30, 12, 0, 0, 0, time.UTC)
|
|
|
|
earlier, ok := prevDailyTime(now, "06:00")
|
|
if !ok || !earlier.Equal(time.Date(2026, 6, 30, 6, 0, 0, 0, time.UTC)) {
|
|
t.Errorf("prev (today) = %v, %v", earlier, ok)
|
|
}
|
|
|
|
later, ok := prevDailyTime(now, "18:00")
|
|
if !ok || !later.Equal(time.Date(2026, 6, 29, 18, 0, 0, 0, time.UTC)) {
|
|
t.Errorf("prev (yesterday) = %v, %v", later, ok)
|
|
}
|
|
|
|
if _, ok := prevDailyTime(now, "bad"); ok {
|
|
t.Error("prev (invalid) should not be ok")
|
|
}
|
|
}
|
|
|
|
func TestTimeScheduleCatchUpAfterRestart(t *testing.T) {
|
|
origDelay := catchUpDelay
|
|
catchUpDelay = 100 * time.Millisecond
|
|
defer func() { catchUpDelay = origDelay }()
|
|
|
|
now := time.Now()
|
|
hhmm := now.Add(-2 * time.Hour).Format("15:04")
|
|
seed := map[string]time.Time{"": now.Add(-26 * time.Hour)}
|
|
|
|
m := newManager(seed, func(map[string]time.Time) {})
|
|
defer m.Close()
|
|
|
|
sub := m.Subscribe("test")
|
|
defer m.Unsubscribe("test")
|
|
|
|
m.SetConfig(Config{Global: ScheduleConfig{Enabled: true, Mode: "time", Time: hhmm}})
|
|
|
|
deadline := time.After(3 * time.Second)
|
|
for {
|
|
select {
|
|
case state := <-sub:
|
|
if state.CycleSeq > 0 && state.Target == "" {
|
|
return
|
|
}
|
|
case <-deadline:
|
|
t.Fatal("missed time schedule did not catch up within 3s")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTimeScheduleNoFireOnFirstEnable(t *testing.T) {
|
|
now := time.Now()
|
|
hhmm := now.Add(-2 * time.Hour).Format("15:04")
|
|
|
|
m := newManager(map[string]time.Time{}, func(map[string]time.Time) {})
|
|
defer m.Close()
|
|
|
|
sub := m.Subscribe("test")
|
|
defer m.Unsubscribe("test")
|
|
|
|
m.SetConfig(Config{Global: ScheduleConfig{Enabled: true, Mode: "time", Time: hhmm}})
|
|
|
|
deadline := time.After(1500 * time.Millisecond)
|
|
for {
|
|
select {
|
|
case state := <-sub:
|
|
if state.CycleSeq > 0 {
|
|
t.Fatal("first enable must not fire immediately")
|
|
}
|
|
case <-deadline:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSchedulerEmitsCycle(t *testing.T) {
|
|
m := newManager(map[string]time.Time{}, func(map[string]time.Time) {})
|
|
defer m.Close()
|
|
|
|
sub := m.Subscribe("test")
|
|
defer m.Unsubscribe("test")
|
|
|
|
m.SetConfig(Config{Global: ScheduleConfig{Enabled: true, Mode: "interval", IntervalSec: 1}})
|
|
|
|
deadline := time.After(3 * time.Second)
|
|
for {
|
|
select {
|
|
case state := <-sub:
|
|
if state.CycleSeq > 0 && state.Target == "" {
|
|
return
|
|
}
|
|
case <-deadline:
|
|
t.Fatal("scheduler did not emit a cycle event within 3s")
|
|
}
|
|
}
|
|
}
|