107 lines
3.2 KiB
Nim
107 lines
3.2 KiB
Nim
## test_stats.nim
|
|
## ==============
|
|
## Tests unitaires des statistiques (compteurs jour/semaine et streak).
|
|
## Aucune écriture disque : on manipule directement la table `daily`.
|
|
|
|
import std/unittest
|
|
import std/times
|
|
import std/tables
|
|
import std/os
|
|
import std/strutils
|
|
import ../src/stats
|
|
|
|
suite "stats":
|
|
test "initStats starts empty":
|
|
let st = initStats()
|
|
check st.completedToday() == 0
|
|
check st.completedThisWeek() == 0
|
|
check st.streak() == 0
|
|
|
|
test "completedToday counts today's pomodoros":
|
|
var st = initStats()
|
|
st.daily[todayStr()] = 5
|
|
check st.completedToday() == 5
|
|
|
|
test "streak counts consecutive days ending today":
|
|
var st = initStats()
|
|
let today = now()
|
|
for i in 0 ..< 3:
|
|
st.daily[(today - i.days).format("yyyy-MM-dd")] = 1
|
|
check st.streak() == 3
|
|
|
|
test "streak starts from yesterday when today has no entry":
|
|
var st = initStats()
|
|
let today = now()
|
|
st.daily[(today - 1.days).format("yyyy-MM-dd")] = 1
|
|
st.daily[(today - 2.days).format("yyyy-MM-dd")] = 1
|
|
check st.streak() == 2
|
|
|
|
test "streak stops at the first gap":
|
|
var st = initStats()
|
|
let today = now()
|
|
st.daily[today.format("yyyy-MM-dd")] = 1
|
|
st.daily[(today - 1.days).format("yyyy-MM-dd")] = 1
|
|
# jour -2 manquant (gap)
|
|
st.daily[(today - 3.days).format("yyyy-MM-dd")] = 1
|
|
check st.streak() == 2
|
|
|
|
test "completedThisWeek sums the last 7 days":
|
|
var st = initStats()
|
|
let today = now()
|
|
for i in 0 ..< 7:
|
|
st.daily[(today - i.days).format("yyyy-MM-dd")] = 1
|
|
check st.completedThisWeek() == 7
|
|
|
|
test "totalPomodoros sums the whole history":
|
|
var st = initStats()
|
|
st.daily["2026-01-01"] = 2
|
|
st.daily["2026-01-02"] = 3
|
|
st.daily["2026-01-03"] = 5
|
|
check st.totalPomodoros() == 10
|
|
|
|
test "goalReached is true only when the goal is exactly met":
|
|
var st = initStats()
|
|
st.daily[todayStr()] = 8
|
|
check st.goalReached(8)
|
|
check not st.goalReached(4)
|
|
check not st.goalReached(0) # objectif 0 = désactivé
|
|
|
|
test "lastNDays returns n entries including empty days":
|
|
var st = initStats()
|
|
let today = now()
|
|
st.daily[today.format("yyyy-MM-dd")] = 4
|
|
let rows = st.lastNDays(7)
|
|
check rows.len == 7
|
|
# Le dernier élément correspond à aujourd'hui.
|
|
check rows[^1][0] == today.format("yyyy-MM-dd")
|
|
check rows[^1][1] == 4
|
|
|
|
test "exportCsv writes date,count lines":
|
|
var st = initStats()
|
|
st.daily["2026-08-13"] = 3
|
|
st.daily["2026-08-14"] = 5
|
|
let path = getTempDir() / "traytempo_test_export.csv"
|
|
check st.exportCsv(path)
|
|
let content = readFile(path)
|
|
check content.contains("date,count")
|
|
check content.contains("2026-08-13,3")
|
|
check content.contains("2026-08-14,5")
|
|
removeFile(path)
|
|
|
|
suite "stats persistence":
|
|
test "saveStats then loadStats round-trips":
|
|
# Isole l'écriture disque dans un APPDATA temporaire.
|
|
let tmpApd = getTempDir() / "traytempo_test_stats"
|
|
if dirExists(tmpApd):
|
|
removeDir(tmpApd)
|
|
putEnv("APPDATA", tmpApd)
|
|
|
|
var st = initStats()
|
|
st.daily["2026-08-13"] = 3
|
|
st.daily["2026-08-14"] = 5
|
|
saveStats(st)
|
|
|
|
let loaded = loadStats()
|
|
check loaded.daily["2026-08-13"] == 3
|
|
check loaded.daily["2026-08-14"] == 5
|