diff options
Diffstat (limited to 'test/test_validate_of.ml')
| -rw-r--r-- | test/test_validate_of.ml | 111 |
1 files changed, 63 insertions, 48 deletions
diff --git a/test/test_validate_of.ml b/test/test_validate_of.ml index 5c64710..bcf61cc 100644 --- a/test/test_validate_of.ml +++ b/test/test_validate_of.ml @@ -15,13 +15,20 @@ including their own three pinned defects -- see below). 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. + here, only avoid papering over them). Originally three; now ONE -- items + 1 and 2 are both CLOSED (see each one's own CLOSED note): + 1. CLOSED, W2 fix (CLAUDE.md, temporal_of.ml). Used to read: "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." {!Rite_of.Temporal_of.temporal} now consults + {!Rite_of.Temporal_of.holy_family} directly, independent of weekday, + so this fires on ZERO years now, verified across the whole domain by + [test_exhaustive_domain_sweep]'s own [holy_family_gap_years] counter + below -- not merely assumed from the fix. [is_known_holy_family_ + fallback_gap] itself is kept, as a dedicated "this must never recur" + check, not deleted -- the same discipline item 2 already established. 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 @@ -118,13 +125,20 @@ let contains ~substring s = let rec go i = i + lx <= ls && (String.sub s i lx = substring || go (i + 1)) in lx = 0 || go 0 +(* CLOSED, W2 fix (CLAUDE.md, temporal_of.ml): see this file's own header, + item 1. Kept as an explicit "this must never fire again" check, no + longer part of [is_known_gap]'s own filter below -- the same discipline + [is_known_nativity_gap] just above already established. *) let is_known_holy_family_fallback_gap (f : Val.failure) = f.Val.check = "anchor" && contains ~substring:"of-holy-family" f.Val.detail -(* 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 +(* Fix wave I8 + W2: both [is_known_nativity_gap] and + [is_known_holy_family_fallback_gap] are deliberately excluded now -- see + each one's own header just above. A recurrence of either now surfaces as + an ordinary unexpected failure everywhere this predicate is used to + filter. Kept as a named hook (not inlined to [false] at each call site) + so a future gap has an obvious place to land. *) +let is_known_gap (_ : Val.failure) = false let unexplained_failures year = List.filter (fun f -> not (is_known_gap f)) (run year) @@ -152,13 +166,16 @@ let test_landmark_years () = List.iter check_year_allowing_known_gaps [ 1583; 20 Christmas-Day-is-Sunday shape can both still occur inside the truncated walk) -- only "seasons" is additionally allowed here, and only here. *) let test_year_9999_does_not_raise () = + (* [is_known_gap] now filters nothing (both gaps CLOSED) -- kept in the + pipeline anyway so a future gap has the same obvious place to land, but + [fs] here is really just [run 9999] unfiltered. *) let fs = List.filter (fun f -> not (is_known_gap f)) (run 9999) in Alcotest.(check bool) "no coverage failures (temporal stayed total through the clamp)" true (not (List.exists (fun f -> f.Val.check = "coverage") fs)); Alcotest.(check bool) "seasons check flags the truncated final year as incomplete" true (List.exists (fun f -> f.Val.check = "seasons") fs); - Alcotest.(check (list string)) "nothing OTHER than the documented seasons truncation (and the three known \ - gaps, already filtered) fired" + Alcotest.(check (list string)) "nothing OTHER than the documented seasons truncation fired (both known \ + gaps are CLOSED)" [ "seasons" ] (List.sort_uniq compare (List.map (fun f -> f.Val.check) fs)) @@ -166,18 +183,15 @@ let test_year_9999_does_not_raise () = (* THE CONFIDENCE-TO-9999 CORE: random years across the whole domain, *) (* mirroring test_validate.ml's own [prop_invariants] exactly, one rite *) (* down -- 200 samples by default; every EXHAUSTIVE year under *) -(* [COLITUR_EXHAUSTIVE_SWEEP=1] (below). Filtered of the three known gaps, *) -(* same discipline [check_year_allowing_known_gaps] already applies to the *) -(* landmark years -- a property that asserted [run y = []] UNFILTERED *) -(* would not test anything new (it would just fail on ~1/7 of its own *) -(* samples, the Holy Family gap's own real incidence), and one that *) -(* filtered EVERYTHING unconditionally would risk hiding a genuinely NEW *) -(* failure behind the same three names -- which is exactly why *) -(* [is_known_gap] is the narrow, field-checked pair of predicates above, *) -(* not a blanket "ignore anything on 25 December" rule. *) +(* [COLITUR_EXHAUSTIVE_SWEEP=1] (below). Both known gaps are now CLOSED *) +(* (this file's own header), so [is_known_gap] filters nothing any more -- *) +(* [unexplained_failures y = []] below is really [run y = []] UNFILTERED, *) +(* a strictly stronger assertion than this property used to make while *) +(* either gap was still open. [is_known_gap] is kept in the pipeline (not *) +(* inlined away) so a future gap has the same obvious, narrow, field- *) +(* checked place to land that the two closed ones already used. *) let prop_invariants = - QCheck.Test.make ~count:200 ~name:"OF temporal invariants hold across 1583..9998 (modulo the three known, \ - pinned gaps)" + QCheck.Test.make ~count:200 ~name:"OF temporal invariants hold across 1583..9998 (no known gaps remain)" (QCheck.int_range 1583 9998) (fun y -> unexplained_failures y = []) @@ -283,12 +297,13 @@ 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. *) + (* Fix wave I8 + W2: expected to be [false] every single year now for + BOTH counters -- kept as a live measurement, not deleted, so a + regression anywhere in the domain increments the relevant counter + AND (via [is_known_gap] no longer absorbing either shape) 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; @@ -309,24 +324,25 @@ 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 two \ - remaining known, pinned gaps) fired" + Alcotest.(check (list string)) "9999: nothing OTHER than the documented seasons truncation fired (both \ + known gaps are CLOSED)" [ "seasons" ] (List.sort_uniq compare (List.map (fun f -> f.Val.check) (List.filter (fun f -> not (is_known_gap f)) fs_9999))); - (* 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); + (* CLOSED, W2 fix: the Holy Family gap used to fire on roughly one year + in seven (whenever 25 December is a Sunday) -- real and not vacuous + across the FULL domain, not merely the handful of years the sampled + property happens to draw. {!Rite_of.Temporal_of.temporal} now + consults {!Rite_of.Temporal_of.holy_family} directly, independent of + weekday, so this now fires on ZERO years -- 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, mirroring the Nativity + counter's own already-established pattern just below. *) + Alcotest.(check int) "the Holy Family fallback gap fires on NONE of the 8 416 swept years (W2 fix -- was \ + roughly one in seven, ~1200)" + 0 !holy_family_gap_years; (* 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 @@ -340,10 +356,9 @@ let test_exhaustive_domain_sweep () = let suite = ( "Validate (OF, real data: Rite_of.context)", - [ Alcotest.test_case "landmark years validate cleanly (modulo the two remaining known gaps)" `Quick + [ Alcotest.test_case "landmark years validate cleanly (both known gaps are CLOSED)" `Quick test_landmark_years; - Alcotest.test_case "year 9999 does not raise; seasons flags the clamp, nothing else (beyond the known \ - gaps) fires" `Quick + Alcotest.test_case "year 9999 does not raise; seasons flags the clamp, nothing else fires" `Quick test_year_9999_does_not_raise; Alcotest.test_case "exhaustive domain sweep (1583..9999), committed not sampled" `Slow test_exhaustive_domain_sweep ] |
