diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-13 15:57:14 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-13 15:57:14 +0200 |
| commit | c7f9b66ffe0c265ab049afc8948317e9daded9e7 (patch) | |
| tree | d86c083d1e10de3ac6ae9432395f3af9c5b85287 /test/test_precedence_ef.ml | |
| parent | 044aa0dccbfe76ac9afd299af6074296eeb2cca3 (diff) | |
| download | colitur-c7f9b66ffe0c265ab049afc8948317e9daded9e7.tar.gz colitur-c7f9b66ffe0c265ab049afc8948317e9daded9e7.zip | |
test(ef): reach RG 91 entry 27 through the real pipeline, end-to-end
Entry 27's band branch has been unreachable for the right reason since
it was written: precedence_ef.ml's own comment on it acknowledged the
row existed, but the one test exercising it built a hand-typed
candidate, never a real Temporal_ef.temporal output, and nothing built
the office itself. Closes that gap on both sides:
- The band-table row now sources its candidate from Temporal_ef.temporal
directly (of_temporal), the same review-finding-3 discipline the
Ember/vigil rows already use, so a future regression in the office's
own construction fails this row too, not only the unit-level test.
- Two new resolve-level end-to-end tests, using the real band/
disposition/admit triple (not stubs): the office winning a real
otherwise-unoccupied Saturday and admitting an ordinary commemoration
alongside it (1 August 2026, Holy Machabees -- the task brief's own
worked oracle example), and the office genuinely losing to a real
competing feast and being omitted under RG 26, with no confusion from
the one live data witness that also carries subject Bvm (12 September,
Most Holy Name of Mary) -- proving RG 26's rank-keyed omission fires
before any subject-keyed rule ever could.
- Two golden pins mirroring the same two dates, checked by hand against
`colitur day 2026` before being typed in, following this file's own
"a golden test blesses whatever it is given, verified independently"
discipline. The existing 2038-03-06 pin (RG 91 entry 24 outranking a
Class4 candidate) is corrected in passing: that date is itself a
Saturday, so the displaced candidate the pin's own omitted-list check
names is now precisely entry 27's own shape, not entry 28's bare
catch-all -- the win/lose outcome the pin proves is unchanged, only
its own more precise citation.
Mutation-tested (recorded in the task report): reverting
is_bvm_saturday to a constant false reddens the dedicated unit test, the
new end-to-end resolve test, and the 2026-08-01 golden pin, while
leaving the 2026-09-12 "loses to a real feast" pin untouched, exactly as
expected since that date's outcome never depended on the fix.
Diffstat (limited to 'test/test_precedence_ef.ml')
| -rw-r--r-- | test/test_precedence_ef.ml | 102 |
1 files changed, 98 insertions, 4 deletions
diff --git a/test/test_precedence_ef.ml b/test/test_precedence_ef.ml index ed9a933..475ae6e 100644 --- a/test/test_precedence_ef.ml +++ b/test/test_precedence_ef.ml @@ -291,10 +291,21 @@ let cases = cand ~origin:P.Sanctoral ~rank:V.Class3 ~layer:PE.universal_layer "vigil-of-st-lawrence", 260 ); (* Entry 27 -- RG 91 entry 27 (§4): an otherwise-unoccupied IV-class - Saturday. *) - ( "27 Office of the BVM on Saturday", off 62, - cand ~rank:V.Class4 "ef-time-after-pentecost-1-sat", - 270 ); + Saturday. ef-bvm-saturday task: sourced from [Temporal_ef.temporal]'s + own real output (see [of_temporal], the same review-finding-3 + discipline entry 18's/21's own rows above use), not a hand-typed + slug/rank pair -- this row used to be the one place in this whole + suite where [band]'s entry-27 branch was exercised by a value nothing + in [Temporal_ef.temporal] could actually produce (the office itself + was unbuilt): [band] read [rank = Class4 && weekday = Sat] + correctly, but nothing proved [temporal] ever handed it a candidate + shaped that way for the RIGHT reason. Now it does: [of_temporal (off + 62)] is 6 June 2026, a real otherwise-contested Time-after-Pentecost + Saturday (Norbert, Class3, wins the DAY outright in the real + pipeline -- irrelevant here, since this row tests [band] on the + TEMPORAL CANDIDATE alone, which [Temporal_ef.temporal] builds as the + BVM Saturday office regardless of what wins). *) + ( "27 Office of the BVM on Saturday (from Temporal_ef.temporal)", off 62, of_temporal (off 62), 270 ); (* Entry 28 -- RG 91 entry 28 (§4): the unqualified IV-class catch-all. *) ("28 IV-class feria", off 65, cand ~rank:V.Class4 "ef-time-after-pentecost-1-tue", 280); (* Not an RG 91 row at all: a I-class candidate marked as a vigil, which @@ -1421,6 +1432,81 @@ let test_ii_class_sunday_privileged_witness_admitted_end_to_end () = [ ("ef-some-saint", "omitted: admission limit reached") ] (List.map (fun (c, reason) -> (S.to_string c.P.cel.Cel.slug, reason)) resolution.P.omitted) +(* RG 91 entry 27 / RG 78-79 (Caput IX, "De sancta Maria in sabbato") reached + end-to-end through the REAL pipeline -- this is THE hazard this task's own + brief names explicitly: {!PE.band}'s entry-27 branch has been reachable + only in isolation (the table-driven row above) since it was written, never + through a real [Temporal_ef.temporal] candidate winning an actual day, so + this test is checked for whether it exercises entry 27 for the RIGHT + reason -- proved by the mutation test recorded in the task report + (reverting temporal_ef.ml's own [is_bvm_saturday] branches back to the + generic ferial fallback reddens THIS test, not merely the [band]-table + row, which would still pass unchanged since it is sourced from real + [T.temporal] output either way). + + 1 August 2026, matching the task brief's own worked example against the + oracle exactly: a Time-after-Pentecost Saturday, otherwise unoccupied but + for Holy Machabees (Commemoration_only, Class3, real data/ef/sanctoral.sexp + entry, 1 August) -- the office wins outright (band 270, ahead of Holy + Machabees's own [unclassified]) and the Commemoration_only loser still + rides along as an ordinary commemoration, the SAME shape the oracle's own + row for this date shows ("V Mass of the B. V. M. -- Salve, Sancta Parens", + commemorating Holy Machabees). *) +let test_bvm_saturday_wins_and_commemorates_end_to_end () = + let date = mk 2026 8 1 in + let day_ctx = ctx date in + let bvm_saturday = of_temporal date in + let holy_machabees = + cand ~origin:P.Sanctoral ~rank:V.Class3 ~status:Cel.Commemoration_only ~layer:PE.universal_layer + "holy-machabees" + in + let resolution = P.resolve real_rules day_ctx ~temporal:bvm_saturday ~sanctoral:[ holy_machabees ] in + Alcotest.(check string) "the BVM Saturday office is observed, not Holy Machabees" + "ef-time-after-pentecost-9-saturday" (S.to_string resolution.P.observed.P.cel.Cel.slug); + Alcotest.(check string) "observed rank is class-4, unconditional" "class-4" + (V.rank_to_string resolution.P.observed.P.cel.Cel.rank); + Alcotest.(check string) "observed colour is white, overriding the season's own green" "white" + (Col.to_string resolution.P.observed.P.cel.Cel.colour); + Alcotest.(check bool) "observed subject is Bvm" true (resolution.P.observed.P.cel.Cel.subject = Sub.Bvm); + Alcotest.(check (list (pair string string))) "Holy Machabees still rides along as an ordinary commemoration" + [ ("holy-machabees", "Ordinary") ] + (List.map + (fun (c, p) -> (S.to_string c.P.cel.Cel.slug, match p with P.Privileged -> "Privileged" | P.Ordinary -> "Ordinary")) + resolution.P.commemorations); + Alcotest.(check int) "nothing omitted" 0 (List.length resolution.P.omitted) + +(* The other half of the SAME hazard: a real Saturday where RG 78's own + protasis is FALSE (a genuine sanctoral feast wins the day outright), so + the BVM-Saturday-shaped temporal candidate must lose, and be OMITTED under + RG 26 (a temporal Class4 non-vigil loser is never commemorated) exactly + like the plain ferial candidate it replaces always was -- proving [band]/ + [disposition] need no special case for this office at all, the design + claim the task report makes explicitly. 12 September 2026 is a Saturday + where `most-holy-name-of-mary` (data/ef/adjustments.sexp's own [Set_subject + Bvm] entry, Class3 Feast) wins outright -- ALSO tagged [subject = Bvm], + the one live data witness that could in principle confuse a + subject-keyed disposition rule with RG 26's own rank-keyed one: this test + proves they do NOT collide (RG 26 fires first, unconditionally, on the + loser's own [rank = Class4], never reaching a subject comparison at all). *) +let test_bvm_saturday_loses_to_a_real_feast_end_to_end () = + let date = mk 2026 9 12 in + let day_ctx = ctx date in + let bvm_saturday = of_temporal date in + let name_of_mary = + cand ~origin:P.Sanctoral ~rank:V.Class3 ~subject:Sub.Bvm ~layer:PE.universal_layer + "most-holy-name-of-mary" + in + let resolution = P.resolve real_rules day_ctx ~temporal:bvm_saturday ~sanctoral:[ name_of_mary ] in + Alcotest.(check string) "Most Holy Name of Mary is observed, not the BVM Saturday office" + "most-holy-name-of-mary" (S.to_string resolution.P.observed.P.cel.Cel.slug); + Alcotest.(check (list string)) "nothing is commemorated" [] + (List.map (fun (c, _) -> S.to_string c.P.cel.Cel.slug) resolution.P.commemorations); + Alcotest.(check (list (pair string string))) + "the BVM-Saturday-shaped temporal candidate is omitted under RG26, not commemorated -- no Bvm-vs-Bvm \ + confusion with RG112(a)-style subject logic" + [ ("ef-time-after-pentecost-15-saturday", "omitted: yielded to a higher day") ] + (List.map (fun (c, reason) -> (S.to_string c.P.cel.Cel.slug, reason)) resolution.P.omitted) + (* RG 16(a) (register §6.0) reached end-to-end through the REAL pipeline ([PE.band], [PE.disposition] AND [PE.admit] together, not any one of them in isolation as this file's own hand-tagged rows test them @@ -1895,6 +1981,14 @@ let suite = "II-class Sunday override: RG109(b) witness admitted over an ordinary saint, end-to-end" `Quick test_ii_class_sunday_privileged_witness_admitted_end_to_end; Alcotest.test_case + "RG91 e27/RG78: the BVM Saturday office wins and commemorates Holy Machabees, end-to-end \ + (2026-08-01)" + `Quick test_bvm_saturday_wins_and_commemorates_end_to_end; + Alcotest.test_case + "RG91 e27/RG78/RG26: the BVM Saturday office loses to a real feast and is omitted, end-to-end \ + (2026-09-12)" + `Quick test_bvm_saturday_loses_to_a_real_feast_end_to_end; + Alcotest.test_case "RG16(a): a Feast of the Lord suppresses the Sunday's own commemoration entirely, \ end-to-end (2028-08-06)" `Quick test_rg16a_lord_feast_suppresses_sunday_end_to_end; |
