aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-25 19:40:52 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-25 19:40:52 +0200
commitfc88c6de225592d8700fe1eb40d870ec8863b57d (patch)
tree32e7f842c6ca12b2b5ad1382d15c7acef72665de /test
parent4f3af5d6fdc3f5aafe955f88ee9a7788e420b62e (diff)
downloadcolitur-fc88c6de225592d8700fe1eb40d870ec8863b57d.tar.gz
colitur-fc88c6de225592d8700fe1eb40d870ec8863b57d.zip
test(of): prove the Tabula is total over 1583-9999
A hand-transcribed 13-entry table is only trustworthy if nothing the engine constructs falls through it. Sampled property plus an exhaustive sweep behind COLITUR_EXHAUSTIVE_SWEEP, matching the claim Precedence_ef.band already carries for RG 91's 28 entries. Mutation-proved rather than assumed: deleting the entry-13 branch reddens it on a named date.
Diffstat (limited to 'test')
-rw-r--r--test/test_precedence_of.ml41
1 files changed, 40 insertions, 1 deletions
diff --git a/test/test_precedence_of.ml b/test/test_precedence_of.ml
index 8817fa8..64b182c 100644
--- a/test/test_precedence_of.ml
+++ b/test/test_precedence_of.ml
@@ -225,8 +225,47 @@ let test_part3 () =
Alcotest.(check int) label expected (Rite_of.Precedence_of.band c cand))
part3_cases
+(* The temporal candidate Temporal_of produces for [d], as Precedence.resolve
+ would build it. *)
+let temporal_candidate d =
+ let t = Rite_of.Temporal_of.temporal d in
+ { Precedence.cel = t.Temporal.office; origin = Precedence.Temporal }
+
+let ctx_of_date d =
+ let t = Rite_of.Temporal_of.temporal d in
+ { Precedence.date = d; season = t.Temporal.season; weekday = Date.weekday d }
+
+let band_of_date d = Rite_of.Precedence_of.band (ctx_of_date d) (temporal_candidate d)
+
+(* Every day of a year: the temporal candidate must land on a real table
+ entry, never [unclassified]. *)
+let check_year y =
+ let mk_date y m dd =
+ Date.make ~year:y ~month:m ~day:dd |> Result.get_ok in
+ let d = ref (mk_date y 1 1) in
+ let last = mk_date y 12 31 in
+ while Date.compare !d last <= 0 do
+ let b = band_of_date !d in
+ if b = Rite_of.Precedence_of.unclassified then
+ Alcotest.failf "%s: temporal candidate is unclassified"
+ (Date.to_iso8601 !d);
+ d := Date.add_days !d 1
+ done
+
+let prop_band_total =
+ QCheck.Test.make ~count:200 ~name:"band classifies every temporal candidate"
+ (QCheck.int_range 1583 9999)
+ (fun y -> check_year y; true)
+
+let test_exhaustive_band_total () =
+ if Sys.getenv_opt "COLITUR_EXHAUSTIVE_SWEEP" = None then
+ Alcotest.skip ()
+ else for y = 1583 to 9999 do check_year y done
+
let suite =
( "precedence-of",
[ Alcotest.test_case "Tabula part I (entries 1-4)" `Quick test_part1;
Alcotest.test_case "Tabula part II (entries 5-9)" `Quick test_part2;
- Alcotest.test_case "Tabula part III (entries 10-13)" `Quick test_part3 ] )
+ Alcotest.test_case "Tabula part III (entries 10-13)" `Quick test_part3;
+ Alcotest.test_case "band is total over the domain" `Slow test_exhaustive_band_total ]
+ @ List.map QCheck_alcotest.to_alcotest [ prop_band_total ] )