1
-
Removed:
(** Unit tests for {!Recovery}, authored against recovery.mli.
1
+
Added:
(** Unit tests for {!Recovery}. *)
2
2
3
-
Removed:
Recovery is now just time primitives plus a readiness judgment; sessions,
4
-
Removed:
overrides, and evidence-based prescription moved to {!Logbook}
5
-
Removed:
(informational gating) and were dropped from this module entirely. *)
3
+
Added:
let secs d = Recovery.duration_to_seconds d
4
+
Added:
let at s = Recovery.timestamp_of_unix_seconds s
6
5
7
-
Removed:
let ts = Recovery.timestamp_of_unix_seconds
8
-
Removed:
9
-
Removed:
let elapsed_tests =
6
+
Added:
let time_tests =
10
7
[
11
-
Removed:
( "elapsed is the gap between two timestamps",
8
+
Added:
( "hours and days convert to seconds",
12
9
`Quick,
13
10
fun () ->
14
-
Removed:
let e = Recovery.elapsed ~since:(ts 1000) ~now:(ts 1900) in
15
-
Removed:
Alcotest.(check int) "900s" 900 (Recovery.duration_to_seconds e) );
11
+
Added:
Alcotest.(check int) "48h" 172_800 (secs (Recovery.hours 48));
12
+
Added:
Alcotest.(check int) "2d" 172_800 (secs (Recovery.days 2)) );
13
+
Added:
( "timestamps round-trip",
14
+
Added:
`Quick,
15
+
Added:
fun () ->
16
+
Added:
Alcotest.(check int)
17
+
Added:
"unix seconds" 1_700_000_000
18
+
Added:
(Recovery.timestamp_to_unix_seconds (at 1_700_000_000)) );
19
+
Added:
( "elapsed measures the gap between workouts",
20
+
Added:
`Quick,
21
+
Added:
fun () ->
22
+
Added:
Alcotest.(check int)
23
+
Added:
"48h apart" 172_800
24
+
Added:
(secs (Recovery.elapsed ~since:(at 0) ~now:(at 172_800))) );
25
+
Added:
( "elapsed never goes negative",
26
+
Added:
`Quick,
27
+
Added:
fun () ->
28
+
Added:
Alcotest.(check int)
29
+
Added:
"clamped" 0
30
+
Added:
(secs (Recovery.elapsed ~since:(at 172_800) ~now:(at 0))) );
16
31
]
17
32
18
33
let readiness_tests =
19
34
[
20
-
Removed:
( "fully elapsed window is Ready",
35
+
Added:
( "the recommended window having passed means ready",
21
36
`Quick,
22
37
fun () ->
23
-
Removed:
let e = Recovery.elapsed ~since:(ts 0) ~now:(ts 1_000_000) in
24
38
let r =
25
-
Removed:
Recovery.evaluate_readiness ~elapsed:e ~recommended:(Recovery.days 4)
39
+
Added:
Recovery.evaluate_readiness ~elapsed:(Recovery.hours 48)
40
+
Added:
~recommended:(Recovery.hours 48)
26
41
in
27
42
Alcotest.(check bool) "ready" true (Recovery.is_ready r) );
28
-
Removed:
( "within the window is not Ready",
43
+
Added:
( "short of the window means still recovering",
29
44
`Quick,
30
45
fun () ->
31
-
Removed:
let e = Recovery.elapsed ~since:(ts 0) ~now:(ts 3600) in
32
-
Removed:
let r =
33
-
Removed:
Recovery.evaluate_readiness ~elapsed:e ~recommended:(Recovery.days 4)
46
+
Added:
match
47
+
Added:
Recovery.evaluate_readiness ~elapsed:(Recovery.hours 24)
48
+
Added:
~recommended:(Recovery.hours 48)
49
+
Added:
with
50
+
Added:
| Recovery.Ready -> Alcotest.fail "expected Recovering"
51
+
Added:
| Recovery.Recovering { rested; recommended } ->
52
+
Added:
Alcotest.(check int) "rested" 86_400 (secs rested);
53
+
Added:
Alcotest.(check int) "recommended" 172_800 (secs recommended) );
54
+
Added:
]
55
+
Added:
56
+
Added:
let clearance_tests =
57
+
Added:
[
58
+
Added:
( "recovery earns a clearance",
59
+
Added:
`Quick,
60
+
Added:
fun () ->
61
+
Added:
match Recovery.clear Recovery.Ready with
62
+
Added:
| Some c -> (
63
+
Added:
match Recovery.basis c with
64
+
Added:
| Recovery.Recovered -> ()
65
+
Added:
| Recovery.Overridden _ -> Alcotest.fail "expected Recovered")
66
+
Added:
| None -> Alcotest.fail "expected a clearance" );
67
+
Added:
( "an incomplete recovery earns none",
68
+
Added:
`Quick,
69
+
Added:
fun () ->
70
+
Added:
let recovering =
71
+
Added:
Recovery.evaluate_readiness ~elapsed:(Recovery.hours 12)
72
+
Added:
~recommended:(Recovery.hours 48)
34
73
in
35
-
Removed:
Alcotest.(check bool) "not ready" false (Recovery.is_ready r) );
74
+
Added:
Alcotest.(check bool)
75
+
Added:
"refused" true
76
+
Added:
(Option.is_none (Recovery.clear recovering)) );
77
+
Added:
( "an override is granted but leaves its reason on the record",
78
+
Added:
`Quick,
79
+
Added:
fun () ->
80
+
Added:
let recovering =
81
+
Added:
Recovery.evaluate_readiness ~elapsed:(Recovery.hours 12)
82
+
Added:
~recommended:(Recovery.hours 48)
83
+
Added:
in
84
+
Added:
let c = Recovery.override recovering ~reason:"travelling tomorrow" in
85
+
Added:
match Recovery.basis c with
86
+
Added:
| Recovery.Overridden { rested; recommended; reason } ->
87
+
Added:
Alcotest.(check int) "rested" 43_200 (secs rested);
88
+
Added:
Alcotest.(check int) "recommended" 172_800 (secs recommended);
89
+
Added:
Alcotest.(check string) "reason" "travelling tomorrow" reason
90
+
Added:
| Recovery.Recovered -> Alcotest.fail "expected Overridden" );
91
+
Added:
( "overriding when already recovered is simply recovered",
92
+
Added:
`Quick,
93
+
Added:
fun () ->
94
+
Added:
match
95
+
Added:
Recovery.basis (Recovery.override Recovery.Ready ~reason:"impatient")
96
+
Added:
with
97
+
Added:
| Recovery.Recovered -> ()
98
+
Added:
| Recovery.Overridden _ ->
99
+
Added:
Alcotest.fail "no recovery was outstanding to override" );
36
100
]
37
101
38
102
let suite =
39
103
[
40
-
Removed:
("recovery.elapsed", elapsed_tests); ("recovery.readiness", readiness_tests);
104
+
Added:
("recovery.time", time_tests);
105
+
Added:
("recovery.readiness", readiness_tests);
106
+
Added:
("recovery.clearance", clearance_tests);
41
107
]