aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-26 13:57:14 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-26 13:57:14 +0200
commit03d3c00ccdde318207c8b4fdc456e5e64d6b4abf (patch)
treeeaa8b77b549f6751594b2868798c7ca2d1b3ca70 /test
parent9b8821f7b914c94f5b2c8eeda05407ee921b3d5a (diff)
downloadcolitur-03d3c00ccdde318207c8b4fdc456e5e64d6b4abf.tar.gz
colitur-03d3c00ccdde318207c8b4fdc456e5e64d6b4abf.zip
feat(of-lectionary): hand-author the Christmas Day Mass, close the gap
colitur readings --rite of printed "- | -" on 25 December every year -- lectio's own 988 keys never included the Christmas DAY Mass at all, only the Vigil (already correctly noted, but left unfilled, in tools/bootstrap_lectionary_of.ml's own named_overrides comment). Sourced, not guessed: docs/research/of/olm-1981-ocr.txt:4513-4520, "16 Ad Missam in die", the same primary authority this module already cites for the cycle rules. First reading and Gospel only, matching this file's own scope everywhere else (First/Gospel is the kernel's own boundary, I7, a separate deferred task) -- Isaiah 52:7-10 / John 1:1-18 (OLM's own LONGER form; the file's LINEAGE section already discloses that short/long-form choices are not modelled anywhere in this data, so this is an application of an existing limitation, not a new one). Injected via a new hand_authored table in the generator, merged into entries before assert_reachable/Lectionary.of_entries -- there is no ini section to derive this from. One new lookup_any call (readings' own existing temporal-slug fallback, unmodified) now resolves BOTH the formulary and the citations for 25 December from the same entry, so both halves of the "citations-unresolved"/"formulary" gap close together, not just the citation half. Verified across the WHOLE domain, not assumed: test_validate_of.ml's exhaustive sweep (COLITUR_EXHAUSTIVE_SWEEP=1, all 8 416 years) now asserts the Nativity gap fires on NONE of them, down from all 8 416 before this fix -- and is kept as a live, dedicated "must never recur" counter rather than deleted. test_rite_of.ml's landmark-year check and test_lectionary_of.ml's 2026 coverage pins are updated the same way (the unresolved-day set that used to be pinned as {25 December} is now pinned as empty, not merely a count going to zero). A concrete golden pin (test_golden_of.ml) locks the exact citations through the full resolved pipeline. data/of/lectionary.sexp regenerated (771 entries, was 770); its own SHA-256 re-pinned. make check (COLITUR_EXHAUSTIVE_SWEEP=1 dune test --force, unpiped, foreground): exit 0, 895 tests, ~536s.
Diffstat (limited to 'test')
-rw-r--r--test/test_citation_coverage_of.ml6
-rw-r--r--test/test_golden_of.ml31
-rw-r--r--test/test_lectionary_of.ml50
-rw-r--r--test/test_rite_of.ml45
-rw-r--r--test/test_validate_of.ml81
5 files changed, 140 insertions, 73 deletions
diff --git a/test/test_citation_coverage_of.ml b/test/test_citation_coverage_of.ml
index 3444706..70e63ad 100644
--- a/test/test_citation_coverage_of.ml
+++ b/test/test_citation_coverage_of.ml
@@ -19,7 +19,7 @@
the FULL data/of/lectionary.sexp (not merely what one civil year happens
to observe -- a stricter check than EF's own year-walk, and the same one
tools/bootstrap_lectionary_of.ml's own generated header now runs and
- discloses): 41 distinct references, out of 1540 total, EVERY ONE a
+ discloses): 41 distinct references, out of 1542 total, EVERY ONE a
hyphenated range crossing a chapter boundary ("2:29-3:6", "1 John") --
a {!Colitur_citation.Parse.t} shape [part]/[verse_range] do not
represent (a [part] is one chapter and a list of within-chapter ranges;
@@ -91,9 +91,9 @@ let test_of_citations_convert_or_are_the_known_cross_chapter_residual () =
cits)
(Colitur_kernel.Lectionary.entries (lectionary ()));
let bad = List.sort compare !bad in
- Alcotest.(check int) "1540 citation fields in data/of/lectionary.sexp today -- if this changes, the \
+ Alcotest.(check int) "1542 citation fields in data/of/lectionary.sexp today -- if this changes, the \
pinned residual below may need updating too, not just this count"
- 1540 !total;
+ 1542 !total;
Alcotest.(check (list string)) "the unconverted set is EXACTLY the known cross-chapter residual, no \
more and no fewer"
(List.sort compare known_cross_chapter_residual) bad;
diff --git a/test/test_golden_of.ml b/test/test_golden_of.ml
index f40b62a..fd4f781 100644
--- a/test/test_golden_of.ml
+++ b/test/test_golden_of.ml
@@ -34,7 +34,10 @@
5. All Souls (2 November).
6. The Sacred Heart (Easter+68).
Plus 17 December's own date-keyed reading (Gen 49:2,8-10 / Mt 1:1-17,
- fixed earlier on this branch, commit b6d0eba0). *)
+ fixed earlier on this branch, commit b6d0eba0), and, added by the
+ fix-wave-2 review (I8), 25 December's own reading (Isa 52:7-10 /
+ Jn 1:1-18, hand-authored from OLM 1981 -- see [test_christmas_day_
+ reading]'s own header). *)
module Cal = Colitur_kernel.Calendar
module Layer = Colitur_kernel.Layer
@@ -317,6 +320,29 @@ let test_december_17_reading () =
letter"
2027 12 17 "2027-12-17 slug=of-advent-3-friday first=Genesis 49:2,8-10 gospel=Matthew 1:1-17"
+(* ------------------------------------------------------------------ *)
+(* 8. Christmas Day itself: fix wave I8 (final-review.md, 2026-08-25- *)
+(* colitur-of-phases-3-5). lectio's own 988 keys never covered the *)
+(* Christmas DAY Mass at all (only the Vigil) -- `colitur readings *)
+(* --rite of` used to print "- | -" on 25 December, every year (pinned, *)
+(* before this fix, by test_validate_of.ml's own exhaustive-sweep *)
+(* counter: fired on all 8 416 swept years). tools/ *)
+(* bootstrap_lectionary_of.ml's own [hand_authored] table now injects it *)
+(* directly from OLM 1981's own "16 Ad Missam in die" *)
+(* (docs/research/of/olm-1981-ocr.txt:4513-4520): First = Isaiah *)
+(* 52:7-10, Gospel = John 1:1-18 (OLM's own LONGER form -- the file's own*)
+(* LINEAGE section already discloses that short/long-form choices are *)
+(* not modelled anywhere in this data, so this is an application of an *)
+(* existing, stated limitation, not a new one). Fixed civil-date entry, *)
+(* not cycle-lettered (the Christmas Day Mass does not vary by A/B/C or *)
+(* I/II), so a single year is sufficient -- unlike item 7 above, there is*)
+(* no cycle-letter axis to re-confirm in a second year. ------------------ *)
+
+let test_christmas_day_reading () =
+ check_readings ~msg:"2026-12-25: the Christmas Day Mass, hand-authored from OLM 1981 (Isa 52:7-10/John \
+ 1:1-18) -- was \"- | -\" before fix wave I8"
+ 2026 12 25 "2026-12-25 slug=of-nativity first=Isaiah 52:7-10 gospel=John 1:1-18"
+
let suite =
( "golden-of",
[ Alcotest.test_case "Ordinary Time skips a week (2026); Mary, Mother of the Church" `Quick
@@ -328,5 +354,6 @@ let suite =
test_annunciation_holy_week_2027;
Alcotest.test_case "All Souls (2026)" `Quick test_all_souls_2026;
Alcotest.test_case "the Sacred Heart, Easter+68 (2026)" `Quick test_sacred_heart_2026;
- Alcotest.test_case "17 December's own date-keyed reading, two civil years" `Quick test_december_17_reading
+ Alcotest.test_case "17 December's own date-keyed reading, two civil years" `Quick test_december_17_reading;
+ Alcotest.test_case "Christmas Day's own reading (fix wave I8)" `Quick test_christmas_day_reading
] )
diff --git a/test/test_lectionary_of.ml b/test/test_lectionary_of.ml
index a9fcdb1..03aaea5 100644
--- a/test/test_lectionary_of.ml
+++ b/test/test_lectionary_of.ml
@@ -178,15 +178,14 @@ let sha256_of_file path =
don't transcribe it from generator stdout" discipline
test_calendar_of_data.ml's own [test_sha256] already follows. *)
let test_sha256_pinned () =
- (* Fix wave I2 (final-review.md, 2026-08-25-colitur-of-phases-3-5): the
- hash changed because the header grew a new "Citation-siglum
- conversion" census -- the payload (parse this test's siblings assert
- against) is byte-identical; only the disclosure comment above it is
- new. Re-derived with `sha256sum data/of/lectionary.sexp`, not
- transcribed from generator stdout, the same discipline this test's own
- header states. *)
+ (* Fix wave I8 (final-review.md, 2026-08-25-colitur-of-phases-3-5): the
+ hash changed again -- ONE genuine new entry this time ("of-nativity",
+ the Christmas Day Mass hand-authored from OLM 1981; see
+ test_coverage_2026's own citation), not header-only as the I2 change
+ just above was. Re-derived with `sha256sum data/of/lectionary.sexp`,
+ same discipline. *)
Alcotest.(check string) "data/of/lectionary.sexp SHA-256"
- "aba7817ace8add740a5722f5fdb401a119869545eda9082e41e203df4ac27ee5" (sha256_of_file lectionary_path)
+ "e08207614472955974b504bfe6984ff44e882c4d8fadc778c4fa1ddce1adecf8" (sha256_of_file lectionary_path)
(* lectio's OWN of-lectionary.ini SHA-256, pinned inside data/of/
lectionary.sexp's own provenance header (tools/bootstrap_lectionary_of
@@ -252,7 +251,12 @@ let test_missing_source_fails_loudly () =
let test_load () =
let l = real_lectionary () in
- Alcotest.(check int) "770 entries" 770 (List.length (Lectionary.entries l))
+ (* 771, not 770: fix wave I8 (final-review.md) added ONE hand-authored
+ entry, "of-nativity" (the Christmas Day Mass, absent from lectio's own
+ source entirely -- see this file's own [test_coverage_2026] and
+ tools/bootstrap_lectionary_of.ml's own [hand_authored] table for the
+ citation and full argument). *)
+ Alcotest.(check int) "771 entries" 771 (List.length (Lectionary.entries l))
(* ---- coverage: a full sample civil year, both directions, PINNED ------ *)
@@ -285,14 +289,18 @@ let test_coverage_2026 () =
all_days_of_2026
in
Alcotest.(check int) "365 days in 2026" 365 (List.length all_days_of_2026);
- (* The ONE genuine gap this task's own bootstrap found and named: lectio's
- 988 keys never include a Christmas DAY Mass (only the Vigil) -- see
- data/of/lectionary.sexp's own provenance header and
- tools/bootstrap_lectionary_of.ml's own [named_overrides] comment on
- "christmas". Pinned as a NAMED set, not a bare count: a silent zero
- here is exactly the failure mode the task brief warns against. *)
- Alcotest.(check (list string)) "the unresolved-day set is exactly {25 December}" [ "2026-12-25" ] unresolved;
- Alcotest.(check int) "364 of 365 days resolve readings" 364 (365 - List.length unresolved)
+ (* CLOSED, fix wave I8 (final-review.md, 2026-08-25-colitur-of-phases-3-5):
+ lectio's 988 keys never included a Christmas DAY Mass (only the
+ Vigil) -- tools/bootstrap_lectionary_of.ml's own [hand_authored] table
+ now injects it directly (Isa 52:7-10/John 1:1-18, OLM 1981's own "16
+ Ad Missam in die", docs/research/of/olm-1981-ocr.txt:4513-4520), so
+ the set that used to be pinned as {25 December} is now pinned as
+ EMPTY -- still a NAMED set, not a bare count collapsing to zero by
+ coincidence: a future regression reopening this (or any other) gap
+ still fails loudly by naming the date, not merely by a count
+ mismatch. *)
+ Alcotest.(check (list string)) "the unresolved-day set is empty" [] unresolved;
+ Alcotest.(check int) "365 of 365 days resolve readings" 365 (365 - List.length unresolved)
(* Same measurement, restated as "how many days resolve" rather than "how
many don't" -- redundant with the count above by construction, kept
@@ -308,7 +316,7 @@ let test_pinned_resolved_count () =
(fun date -> match readings_on lectionary index date with Some _, _ :: _ -> true | _ -> false)
all_days_of_2026)
in
- Alcotest.(check int) "364 days resolve readings in 2026" 364 resolved
+ Alcotest.(check int) "365 days resolve readings in 2026 (fix wave I8: was 364)" 365 resolved
(* ---- resolution chain: unit-level spot checks -------------------------- *)
@@ -471,9 +479,9 @@ let suite =
Alcotest.test_case "data/of/lectionary.sexp SHA-256 pinned" `Quick test_sha256_pinned;
Alcotest.test_case "lectio source SHA-256 pinned in the header" `Quick test_source_sha256_pinned_in_header;
Alcotest.test_case "a missing lectio source fails loudly, not silently" `Quick test_missing_source_fails_loudly;
- Alcotest.test_case "loads, 770 entries" `Quick test_load;
- Alcotest.test_case "2026 coverage: exactly {25 December} unresolved" `Quick test_coverage_2026;
- Alcotest.test_case "2026 coverage: 364 days resolve" `Quick test_pinned_resolved_count;
+ Alcotest.test_case "loads, 771 entries" `Quick test_load;
+ Alcotest.test_case "2026 coverage: nothing unresolved (fix wave I8)" `Quick test_coverage_2026;
+ Alcotest.test_case "2026 coverage: 365 days resolve" `Quick test_pinned_resolved_count;
Alcotest.test_case "step 3: temporal ferial fallback" `Quick test_step3_temporal_ferial;
Alcotest.test_case "step 2: sanctoral proper wins over the ferial" `Quick test_step2_sanctoral_wins;
Alcotest.test_case "date_keyed_slug boundaries (OLM n. 69.3)" `Quick test_date_keyed_slug_boundaries;
diff --git a/test/test_rite_of.ml b/test/test_rite_of.ml
index a1892ae..5e369b8 100644
--- a/test/test_rite_of.ml
+++ b/test/test_rite_of.ml
@@ -77,21 +77,25 @@ let real_of_rite = Rite_of.context ~lectionary:real_of_lectionary
let run year = Val.run real_of_rite real_of_layer ~year
-(* data/of/lectionary.sexp's own provenance header names ONE informational
- temporal-slug gap: [of-nativity] (25 December -- Christmas Day itself)
- has no entry, because niedziela.pl's own source keys the Nativity's
- several Masses (Vigil/Night/Dawn/Day) differently than a single flat
- slug can address, and [Lectionary_of.readings] has no fallback beyond
- its own three-step chain (unlike EF's RG 299 preceding-Sunday rule,
- which OF's own OLM Praenotanda gives no equivalent for -- see
- lectionary_of.mli's own citation). This makes {!Colitur_kernel.Validate
- .run}'s ["citations-unresolved"] check fire exactly once a year, on 25
- December, on real shipped data -- a documented, measured gap in
- lectionary_of's own data file (out of this task's scope to touch or
- close: lectionary_of.* is excluded from this task's brief), not a defect
- this module's wiring introduced. Named and filtered explicitly, never
- silently dropped, so a future SECOND gap (a regression) still reddens
- this test. *)
+(* CLOSED, fix wave I8 (final-review.md, 2026-08-25-colitur-of-phases-3-5).
+ This paragraph used to describe a LIVE gap: data/of/lectionary.sexp's
+ own provenance header named ONE informational temporal-slug gap,
+ [of-nativity] (25 December -- Christmas Day itself), because
+ niedziela.pl's own source never covered the Christmas DAY Mass at all
+ (only the Vigil), which made {!Colitur_kernel.Validate.run}'s
+ ["citations-unresolved"]/["formulary"] checks fire every year, on 25
+ December, on real shipped data. tools/bootstrap_lectionary_of.ml's own
+ [hand_authored] table now injects that entry directly (Isaiah 52:7-10 /
+ John 1:1-18, OLM 1981's own "16 Ad Missam in die",
+ docs/research/of/olm-1981-ocr.txt:4513-4520) -- a primary-source
+ citation, not a guess, the same discipline every other hand-authored
+ entry in this project follows. [is_known_nativity_gap] is kept, not
+ deleted, but is no longer in [is_known]'s own filter below: it now
+ exists ONLY as an explicit, named "this must never fire again" check
+ ({!check_year_allowing_known_gaps}'s own dedicated assertion) -- a
+ regression here surfaces as an ordinary unexpected-failure test error,
+ not a silently-absorbed known gap, which is the whole point of moving a
+ predicate out of the filter once its own defect closes. *)
let ends_with ~suffix s =
let ls = String.length s and lx = String.length suffix in
ls >= lx && String.sub s (ls - lx) lx = suffix
@@ -141,18 +145,19 @@ let is_known_holy_family_fallback_gap (f : Val.failure) =
let check_year_allowing_known_gaps year =
let fs = run year in
- let is_known f = is_known_nativity_gap f || is_known_holy_family_fallback_gap f in
+ (* Fix wave I8: [is_known_nativity_gap] is deliberately NOT part of
+ [is_known] any more -- see that predicate's own header. Only the
+ Holy Family fallback gap is still filtered out here. *)
+ let is_known f = is_known_holy_family_fallback_gap f in
let unexpected = List.filter (fun f -> not (is_known f)) fs in
(match unexpected with
| [] -> ()
| fs ->
Alcotest.failf "%d: %s" year
(String.concat "; " (List.map Val.failure_to_string (List.filteri (fun i _ -> i < 5) fs))));
- let nativity_gaps = List.filter is_known_nativity_gap fs in
Alcotest.(check int)
- (Printf.sprintf "%d: exactly the two documented of-nativity checks (citations-unresolved + \
- formulary), no more" year)
- 2 (List.length nativity_gaps)
+ (Printf.sprintf "%d: no of-nativity citations-unresolved/formulary gap (fix wave I8 -- was 2)" year)
+ 0 (List.length (List.filter is_known_nativity_gap fs))
(* Landmark years, the same choice test_validate.ml's own
[test_landmark_years] makes for EF: both domain edges plus two ordinary
diff --git a/test/test_validate_of.ml b/test/test_validate_of.ml
index a8a6001..5c64710 100644
--- a/test/test_validate_of.ml
+++ b/test/test_validate_of.ml
@@ -14,20 +14,26 @@
down, not a replacement for Task 5's own tests (which stay as they are,
including their own three pinned defects -- see below).
- THE THREE KNOWN, PINNED-NOT-FIXED GAPS (Task 5's own report; do not
- relitigate here, only avoid papering over them):
+ THE KNOWN, PINNED-NOT-FIXED GAPS (Task 5's own report; do not relitigate
+ here, only avoid papering over them). Originally three; now two -- see
+ item 2's own CLOSED note:
1. Normae n. 35(a)'s Holy Family fallback is unreached whenever
Christmas Day is itself a Sunday (test_rite_of.ml's own
[is_known_holy_family_fallback_gap]/
[test_holy_family_fallback_1583_known_wrong_ferial]) -- fires on
roughly one year in seven, first hit at 1583.
- 2. The lectionary (data/of/lectionary.sexp) was audited against only one
- civil year (2026) -- surfaces here as [Validate]'s own
- ["citations-unresolved"]/["formulary"] gap on 25 December every year
- (test_rite_of.ml's own [is_known_nativity_gap]), and, more broadly,
- as a citation-chain gap this file's own comparators (which never
- touch citations/formulary at all -- see the "what this layer cannot
- see" note at the end) cannot see beyond that one symptom either way.
+ 2. CLOSED, fix wave I8 (final-review.md, 2026-08-25-colitur-of-phases-
+ 3-5). Used to read: "The lectionary (data/of/lectionary.sexp) was
+ audited against only one civil year (2026) -- surfaces here as
+ [Validate]'s own [\"citations-unresolved\"]/[\"formulary\"] gap on 25
+ December every year". tools/bootstrap_lectionary_of.ml's own
+ [hand_authored] table now injects the Christmas Day Mass directly
+ (Isa 52:7-10/John 1:1-18, OLM 1981's own "16 Ad Missam in die"), so
+ this fires on ZERO years now, verified across the whole domain by
+ [test_exhaustive_domain_sweep]'s own [nativity_gap_years] counter
+ below -- not merely assumed from the fix. [is_known_nativity_gap]
+ itself is kept, as a dedicated "this must never recur" check, not
+ deleted.
3. St Joseph / Palm Sunday (Normae n. 56(f)) -- invisible to
[Validate.run] entirely: the impeded solemnity is still transferred
exactly once, to SOME later date, so no structural check
@@ -98,6 +104,12 @@ let ends_with ~suffix s =
let ls = String.length s and lx = String.length suffix in
ls >= lx && String.sub s (ls - lx) lx = suffix
+(* CLOSED, fix wave I8 (final-review.md, 2026-08-25-colitur-of-phases-3-5):
+ see test_rite_of.ml's own [is_known_nativity_gap] header for the
+ citation and the full argument (this predicate is duplicated from that
+ file, this file's own header already states why -- not shared through a
+ .mli). Kept as an explicit "this must never fire again" check, no longer
+ part of [is_known_gap]'s own filter below. *)
let is_known_nativity_gap (f : Val.failure) =
(f.Val.check = "citations-unresolved" || f.Val.check = "formulary") && ends_with ~suffix:"12-25" f.Val.date
@@ -109,7 +121,10 @@ let contains ~substring s =
let is_known_holy_family_fallback_gap (f : Val.failure) =
f.Val.check = "anchor" && contains ~substring:"of-holy-family" f.Val.detail
-let is_known_gap f = is_known_nativity_gap f || is_known_holy_family_fallback_gap f
+(* Fix wave I8: [is_known_nativity_gap] deliberately excluded -- see its own
+ header just above. A recurrence now surfaces as an ordinary unexpected
+ failure everywhere this predicate is used to filter. *)
+let is_known_gap f = is_known_holy_family_fallback_gap f
let unexplained_failures year = List.filter (fun f -> not (is_known_gap f)) (run year)
@@ -268,6 +283,12 @@ let test_exhaustive_domain_sweep () =
for y = 1583 to 9998 do
let fs = run y in
let hf = List.exists is_known_holy_family_fallback_gap fs in
+ (* Fix wave I8: expected to be [false] every single year now -- kept
+ as a live measurement, not deleted, so a regression anywhere in
+ the domain increments this counter AND (via [is_known_gap] no
+ longer absorbing it) fails the loop below immediately, on the
+ first year it recurs, rather than only being caught by the
+ summary assertion after the full sweep completes. *)
let nat = List.exists is_known_nativity_gap fs in
if hf then incr holy_family_gap_years;
if nat then incr nativity_gap_years;
@@ -288,33 +309,39 @@ let test_exhaustive_domain_sweep () =
(not (List.exists (fun f -> f.Val.check = "coverage") fs_9999));
Alcotest.(check bool) "9999: seasons check flags the truncated final year as incomplete" true
(List.exists (fun f -> f.Val.check = "seasons") fs_9999);
- Alcotest.(check (list string)) "9999: nothing OTHER than the documented seasons truncation (and the three \
- known, pinned gaps) fired"
+ Alcotest.(check (list string)) "9999: nothing OTHER than the documented seasons truncation (and the two \
+ remaining known, pinned gaps) fired"
[ "seasons" ]
(List.sort_uniq compare
(List.map (fun f -> f.Val.check) (List.filter (fun f -> not (is_known_gap f)) fs_9999)));
- (* Both known gaps are real and not vacuous across the FULL domain, not
- merely on the handful of years the sampled property happens to draw
- -- the Nativity gap fires on literally EVERY year (25 December
- always exists); the Holy Family gap fires on roughly one year in
- seven (whenever 25 December is a Sunday). Pinned as a range, not an
- exact count, deliberately: the exact figure is a real, computable
- fact about the Gregorian calendar's own 400-year cycle, but pinning
- it to the digit would make this test fail the moment a future
- COLITUR_EXHAUSTIVE_SWEEP run's own domain bounds shift by even one
- year at either edge, for a reason having nothing to do with
- colitur's own correctness. *)
- Alcotest.(check int) "the Nativity citation/formulary gap fires on every one of the 8 416 swept years"
- 8416 !nativity_gap_years;
+ (* The Holy Family gap is real and not vacuous across the FULL domain,
+ not merely on the handful of years the sampled property happens to
+ draw -- it fires on roughly one year in seven (whenever 25 December
+ is a Sunday). Pinned as a range, not an exact count, deliberately:
+ the exact figure is a real, computable fact about the Gregorian
+ calendar's own 400-year cycle, but pinning it to the digit would
+ make this test fail the moment a future COLITUR_EXHAUSTIVE_SWEEP
+ run's own domain bounds shift by even one year at either edge, for a
+ reason having nothing to do with colitur's own correctness. *)
Alcotest.(check bool) "the Holy Family fallback gap fires on a real, non-trivial fraction of years \
(roughly one in seven)"
true
- (!holy_family_gap_years > 1000 && !holy_family_gap_years < 1400)
+ (!holy_family_gap_years > 1000 && !holy_family_gap_years < 1400);
+ (* CLOSED, fix wave I8: the Nativity gap used to fire on literally every
+ one of the 8 416 swept years (25 December always exists). Now
+ exactly zero -- across the WHOLE domain, not merely the 4 landmark
+ years test_rite_of.ml's own [test_landmark_years] already checks,
+ which is the entire reason this dedicated exhaustive counter is kept
+ rather than deleted alongside the rest of the old gap-tracking. *)
+ Alcotest.(check int) "the Nativity citation/formulary gap fires on NONE of the 8 416 swept years (fix \
+ wave I8 -- was 8 416)"
+ 0 !nativity_gap_years
end
let suite =
( "Validate (OF, real data: Rite_of.context)",
- [ Alcotest.test_case "landmark years validate cleanly (modulo the three known gaps)" `Quick test_landmark_years;
+ [ Alcotest.test_case "landmark years validate cleanly (modulo the two remaining known gaps)" `Quick
+ test_landmark_years;
Alcotest.test_case "year 9999 does not raise; seasons flags the clamp, nothing else (beyond the known \
gaps) fires" `Quick
test_year_9999_does_not_raise;