1
-
Removed:
(** Unit tests for {!Routine}, authored against routine.mli.
1
+
Added:
(** Unit tests for {!Routine}. *)
2
2
3
-
Removed:
A routine is a sequence of prescribed workouts rotated through, not a flat
4
-
Removed:
list of exercises. *)
3
+
Added:
let ok = function Ok v -> v | Error _ -> Alcotest.fail "expected Ok"
4
+
Added:
let secs = Recovery.duration_to_seconds
5
+
Added:
let ideal = Routine.ideal_routine
6
+
Added:
let days = Routine.workouts ideal
5
7
6
-
Removed:
let preset_tests =
8
+
Added:
let nth n =
9
+
Added:
match List.nth_opt days n with
10
+
Added:
| Some w -> w
11
+
Added:
| None -> Alcotest.failf "Ideal Routine has no workout %d" n
12
+
Added:
13
+
Added:
let construction_tests =
7
14
[
8
-
Removed:
( "ideal routine cycles several workouts",
15
+
Added:
( "an empty routine is refused",
9
16
`Quick,
10
17
fun () ->
11
-
Removed:
Alcotest.(check bool)
12
-
Removed:
"more than one workout" true
13
-
Removed:
(List.length (Routine.workouts Routine.ideal_routine) > 1) );
14
-
Removed:
( "consolidation routine has workouts",
18
+
Added:
match Routine.make ~name:"Nothing" ~workouts:[] with
19
+
Added:
| Error Routine.Empty_routine -> ()
20
+
Added:
| Ok _ -> Alcotest.fail "expected Empty_routine" );
21
+
Added:
( "the Ideal Routine is HD1's three days",
15
22
`Quick,
16
23
fun () ->
17
-
Removed:
Alcotest.(check bool)
18
-
Removed:
"non-empty" true
19
-
Removed:
(List.length (Routine.workouts Routine.consolidation_routine) > 0) );
20
-
Removed:
( "every workout prescribes at least one set group",
24
+
Added:
Alcotest.(check string) "name" "Ideal Routine" (Routine.name ideal);
25
+
Added:
Alcotest.(check int) "three workouts" 3 (List.length days);
26
+
Added:
Alcotest.(check (list string))
27
+
Added:
"in order"
28
+
Added:
[ "Day 1"; "Day 2"; "Day 3" ]
29
+
Added:
(List.map Workout_prescription.name days) );
30
+
Added:
( "each day prescribes the movements HD1 lists",
21
31
`Quick,
22
32
fun () ->
23
-
Removed:
List.iter
24
-
Removed:
(fun w ->
25
-
Removed:
Alcotest.(check bool)
26
-
Removed:
"workout non-empty" true
27
-
Removed:
(List.length (Workout_prescription.set_groups w) > 0))
28
-
Removed:
(Routine.workouts Routine.ideal_routine) );
29
-
Removed:
( "rotation advances then wraps around the cycle",
33
+
Added:
Alcotest.(check (list int))
34
+
Added:
"stimuli per day" [ 4; 5; 4 ]
35
+
Added:
(List.map
36
+
Added:
(fun w -> List.length (Workout_prescription.prescriptions w))
37
+
Added:
days) );
38
+
Added:
( "Day 1 opens with the pec pre-exhaust and closes with the triceps one",
30
39
`Quick,
31
40
fun () ->
32
-
Removed:
let r = Routine.ideal_routine in
33
-
Removed:
let workouts = Routine.workouts r in
34
-
Removed:
let first = List.hd workouts in
35
-
Removed:
let second = Routine.workout_after r first in
36
-
Removed:
Alcotest.(check bool)
37
-
Removed:
"advances" false
38
-
Removed:
(Workout_prescription.equal first second);
39
-
Removed:
(* Stepping through the whole cycle returns to the first. *)
40
-
Removed:
let n = List.length workouts in
41
-
Removed:
let rec step w i =
42
-
Removed:
if i = 0 then w else step (Routine.workout_after r w) (i - 1)
41
+
Added:
let ps = Workout_prescription.prescriptions (nth 0) in
42
+
Added:
let names p = List.map Exercise.name (Prescription.exercises p) in
43
+
Added:
Alcotest.(check (list string))
44
+
Added:
"flyes into incline press"
45
+
Added:
[ "Dumbbell Flyes"; "Incline Presses" ]
46
+
Added:
(names (List.hd ps));
47
+
Added:
Alcotest.(check (list string))
48
+
Added:
"french press into dips"
49
+
Added:
[ "Lying French Presses"; "Dips" ]
50
+
Added:
(names (List.nth ps 3)) );
51
+
Added:
( "Day 2's superset is the lat pre-exhaust, not an antagonist pairing",
52
+
Added:
`Quick,
53
+
Added:
fun () ->
54
+
Added:
let ps = Workout_prescription.prescriptions (nth 1) in
55
+
Added:
match Prescription.delivery (List.hd ps) with
56
+
Added:
| Prescription.Pre_exhaust { isolation; compound } ->
57
+
Added:
Alcotest.(check string)
58
+
Added:
"isolation" "Pullovers" (Exercise.name isolation);
59
+
Added:
Alcotest.(check string)
60
+
Added:
"compound" "Close-grip, palms-up Pulldowns"
61
+
Added:
(Exercise.name compound)
62
+
Added:
| Prescription.Single _ -> Alcotest.fail "expected a pre-exhaust" );
63
+
Added:
( "HD1's alternatives are permitted where it offers them",
64
+
Added:
`Quick,
65
+
Added:
fun () ->
66
+
Added:
let get id =
67
+
Added:
match Exercise.find id with
68
+
Added:
| Some e -> e
69
+
Added:
| None -> Alcotest.failf "no exercise %S" id
43
70
in
71
+
Added:
let legs = List.hd (Workout_prescription.prescriptions (nth 2)) in
44
72
Alcotest.(check bool)
45
-
Removed:
"wraps after a full cycle" true
46
-
Removed:
(Workout_prescription.equal first (step first n)) );
73
+
Added:
"squats may replace the leg press" true
74
+
Added:
(Prescription.permits legs (get "squats"));
75
+
Added:
let pecs = List.hd (Workout_prescription.prescriptions (nth 0)) in
76
+
Added:
Alcotest.(check bool)
77
+
Added:
"pec deck may replace flyes" true
78
+
Added:
(Prescription.permits pecs (get "pec-deck")) );
47
79
]
48
80
49
-
Removed:
let make_tests =
81
+
Added:
let rotation_tests =
50
82
[
51
-
Removed:
( "empty routine rejected",
83
+
Added:
( "the cycle advances and wraps",
52
84
`Quick,
53
85
fun () ->
54
-
Removed:
Alcotest.(check bool)
55
-
Removed:
"empty rejected" true
56
-
Removed:
(Result.is_error (Routine.make ~name:"Empty" ~workouts:[])) );
86
+
Added:
let name w = Workout_prescription.name w in
87
+
Added:
Alcotest.(check string)
88
+
Added:
"1 -> 2" "Day 2"
89
+
Added:
(name (Routine.workout_after ideal (nth 0)));
90
+
Added:
Alcotest.(check string)
91
+
Added:
"2 -> 3" "Day 3"
92
+
Added:
(name (Routine.workout_after ideal (nth 1)));
93
+
Added:
Alcotest.(check string)
94
+
Added:
"3 wraps to 1" "Day 1"
95
+
Added:
(name (Routine.workout_after ideal (nth 2))) );
96
+
Added:
( "an unknown workout falls back to the start of the cycle",
97
+
Added:
`Quick,
98
+
Added:
fun () ->
99
+
Added:
let stranger =
100
+
Added:
ok
101
+
Added:
(Workout_prescription.make ~id:"elsewhere" ~name:"Elsewhere"
102
+
Added:
~prescriptions:(Workout_prescription.prescriptions (nth 0)))
103
+
Added:
in
104
+
Added:
Alcotest.(check string)
105
+
Added:
"falls back" "Day 1"
106
+
Added:
(Workout_prescription.name (Routine.workout_after ideal stranger)) );
57
107
]
58
108
59
-
Removed:
let suite = [ ("routine.presets", preset_tests); ("routine.make", make_tests) ]
109
+
Added:
let rest_tests =
110
+
Added:
[
111
+
Added:
( "HD1's intervals are every other day, then two days off",
112
+
Added:
`Quick,
113
+
Added:
fun () ->
114
+
Added:
Alcotest.(check int) "48h" 172_800 (secs Routine.training_interval);
115
+
Added:
Alcotest.(check int) "72h" 259_200 (secs Routine.cycle_rest) );
116
+
Added:
( "rest within the cycle is 48h, and 72h once it completes",
117
+
Added:
`Quick,
118
+
Added:
fun () ->
119
+
Added:
Alcotest.(check int)
120
+
Added:
"after Day 1" 172_800
121
+
Added:
(secs (Routine.recovery_after ideal (nth 0)));
122
+
Added:
Alcotest.(check int)
123
+
Added:
"after Day 2" 172_800
124
+
Added:
(secs (Routine.recovery_after ideal (nth 1)));
125
+
Added:
Alcotest.(check int)
126
+
Added:
"after Day 3" 259_200
127
+
Added:
(secs (Routine.recovery_after ideal (nth 2))) );
128
+
Added:
]
129
+
Added:
130
+
Added:
let suite =
131
+
Added:
[
132
+
Added:
("routine.construction", construction_tests);
133
+
Added:
("routine.rotation", rotation_tests);
134
+
Added:
("routine.rest", rest_tests);
135
+
Added:
]