TrayTempo v0.2.0 : minuteur Pomodoro Windows en Nim avec interface intuitive
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
## test_timer.nim
|
||||
## ==============
|
||||
## Tests unitaires de la machine à états du minuteur (module pur, sans Win32).
|
||||
|
||||
import std/unittest
|
||||
import ../src/timer
|
||||
import ../src/config
|
||||
|
||||
proc testProfile(): Profile =
|
||||
Profile(name: "Test", workMin: 25, shortBreakMin: 5, longBreakMin: 15, cycles: 4)
|
||||
|
||||
suite "timer":
|
||||
test "initial state is idle":
|
||||
let t = initTimer()
|
||||
check t.phase == phIdle
|
||||
check t.remainingSecs == 0
|
||||
check t.cycleCount == 0
|
||||
|
||||
test "startWork sets working phase and duration":
|
||||
var t = initTimer()
|
||||
t.startWork(testProfile())
|
||||
check t.phase == phWorking
|
||||
check t.remainingSecs == 25 * 60
|
||||
|
||||
test "tick decrements remaining by one second":
|
||||
var t = initTimer()
|
||||
t.startWork(testProfile())
|
||||
let ev = t.tick(testProfile())
|
||||
check ev == evNone
|
||||
check t.remainingSecs == 25 * 60 - 1
|
||||
|
||||
test "tick does nothing when idle":
|
||||
var t = initTimer()
|
||||
check t.tick(testProfile()) == evNone
|
||||
check t.phase == phIdle
|
||||
|
||||
test "work completion transitions to short break (1 cycle)":
|
||||
var t = initTimer()
|
||||
let p = Profile(name: "T", workMin: 1, shortBreakMin: 5, longBreakMin: 15, cycles: 4)
|
||||
t.startWork(p)
|
||||
var ev = evNone
|
||||
for i in 0 ..< 60:
|
||||
ev = t.tick(p)
|
||||
check ev == evWorkCompleted
|
||||
check t.phase == phShortBreak
|
||||
check t.remainingSecs == 5 * 60
|
||||
check t.cycleCount == 1
|
||||
|
||||
test "break completion transitions back to work":
|
||||
var t = initTimer()
|
||||
let p = Profile(name: "T", workMin: 25, shortBreakMin: 1, longBreakMin: 15, cycles: 4)
|
||||
t.startBreak(p, longBreak = false)
|
||||
var ev = evNone
|
||||
for i in 0 ..< 60:
|
||||
ev = t.tick(p)
|
||||
check ev == evBreakCompleted
|
||||
check t.phase == phWorking
|
||||
check t.remainingSecs == 25 * 60
|
||||
|
||||
test "cyclesBeforeLongBreak triggers a long break":
|
||||
var t = initTimer()
|
||||
let p = Profile(name: "T", workMin: 1, shortBreakMin: 5, longBreakMin: 15, cycles: 4)
|
||||
t.cycleCount = 3 # la 4e période de travail doit déclencher la pause longue
|
||||
t.startWork(p)
|
||||
var ev = evNone
|
||||
for i in 0 ..< 60:
|
||||
ev = t.tick(p)
|
||||
check ev == evWorkCompleted
|
||||
check t.phase == phLongBreak
|
||||
check t.remainingSecs == 15 * 60
|
||||
|
||||
test "pause preserves the remaining time and resume restores phase":
|
||||
var t = initTimer()
|
||||
t.startWork(testProfile())
|
||||
let before = t.remainingSecs
|
||||
t.pause()
|
||||
check t.phase == phPaused
|
||||
check t.remainingSecs == before
|
||||
t.resume()
|
||||
check t.phase == phWorking
|
||||
|
||||
test "pause on idle does nothing":
|
||||
var t = initTimer()
|
||||
t.pause()
|
||||
check t.phase == phIdle
|
||||
|
||||
test "stop returns to idle":
|
||||
var t = initTimer()
|
||||
t.startWork(testProfile())
|
||||
t.stop()
|
||||
check t.phase == phIdle
|
||||
check t.remainingSecs == 0
|
||||
|
||||
test "stop resets cycleCount so long break timing stays correct":
|
||||
var t = initTimer()
|
||||
let p = Profile(name: "T", workMin: 1, shortBreakMin: 1, longBreakMin: 1, cycles: 4)
|
||||
t.cycleCount = 3
|
||||
t.stop()
|
||||
check t.cycleCount == 0
|
||||
# Après redémarrage, il faut 4 cycles (pas 1) avant la pause longue.
|
||||
t.startWork(p)
|
||||
check t.cycleCount == 0
|
||||
|
||||
test "isBreak is true only during breaks":
|
||||
var t = initTimer()
|
||||
check not t.isBreak()
|
||||
t.startWork(testProfile())
|
||||
check not t.isBreak()
|
||||
t.startBreak(testProfile(), longBreak = false)
|
||||
check t.isBreak()
|
||||
t.startBreak(testProfile(), longBreak = true)
|
||||
check t.isBreak()
|
||||
|
||||
test "skipBreak jumps from break to work":
|
||||
var t = initTimer()
|
||||
let p = testProfile()
|
||||
t.startBreak(p, longBreak = false)
|
||||
t.skipBreak(p)
|
||||
check t.phase == phWorking
|
||||
check t.remainingSecs == p.workMin * 60
|
||||
|
||||
test "skipBreak does nothing while working":
|
||||
var t = initTimer()
|
||||
t.startWork(testProfile())
|
||||
t.skipBreak(testProfile())
|
||||
check t.phase == phWorking
|
||||
|
||||
test "extendBreak adds minutes to a break":
|
||||
var t = initTimer()
|
||||
t.startBreak(testProfile(), longBreak = false)
|
||||
let before = t.remainingSecs
|
||||
t.extendBreak(5)
|
||||
check t.remainingSecs == before + 5 * 60
|
||||
|
||||
test "extendBreak does nothing while working":
|
||||
var t = initTimer()
|
||||
t.startWork(testProfile())
|
||||
t.extendBreak(5)
|
||||
check t.phase == phWorking
|
||||
|
||||
test "formatTime formats minutes and seconds":
|
||||
check formatTime(0) == "0:00"
|
||||
check formatTime(65) == "1:05"
|
||||
check formatTime(3661) == "1:01:01"
|
||||
Reference in New Issue
Block a user