diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-11 14:22:04 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-11 14:22:04 +0200 |
| commit | 93efd2d5149e351687488935f04c37abc589729b (patch) | |
| tree | 0d3c5f5875e5ed12a8cf7a18b9011f718c9e6e55 /test/test_temporal_ef.ml | |
| parent | 53e0639612a348ddc66e33952d913c5257fe2ba8 (diff) | |
| download | colitur-93efd2d5149e351687488935f04c37abc589729b.tar.gz colitur-93efd2d5149e351687488935f04c37abc589729b.zip | |
rite(ef): ferias, Ember days, Rogations and the temporal entry point
Ferial ranks per RG 91: I class in Holy Week and the privileged octaves
(entries 7, 10), II class for Advent 17-23 and the Ember days (entry 18), III
class for Advent to 16 December and Lent/Passiontide (entries 22, 25), IV class
per annum (entry 28). Two further divergences from lectio, both from the table:
Advent 17-23 are II class, and the Lenten Ember days are II class rather than
ordinary Lenten ferias. Rogations (RG 80/87) exist at all, which lectio does
not compute. Gaudete and Laetare are rose.
Two corrections against the primary source beyond the task brief's draft.
Entry 7 (verified against the Latin: "feria IV cinerum et II, III et IV
Hebdomadae sanctae") covers only Ash Wednesday and Monday-Wednesday of Holy
Week; Thursday-Saturday are the Sacred Triduum, entry 2, cited separately.
Rogation Monday and Tuesday keep the ordinary ferial rank of their season
(RG 88: "de Litaniis minoribus nihil fit in Officio") rather than a fixed
class, since no RG 91 entry ranks them specially.
A module-type constraint proves Temporal_ef satisfies the kernel RITE contract.
Diffstat (limited to 'test/test_temporal_ef.ml')
| -rw-r--r-- | test/test_temporal_ef.ml | 102 |
1 files changed, 101 insertions, 1 deletions
diff --git a/test/test_temporal_ef.ml b/test/test_temporal_ef.ml index 96c7761..aa84014 100644 --- a/test/test_temporal_ef.ml +++ b/test/test_temporal_ef.ml @@ -162,6 +162,100 @@ let test_resumed_sundays () = in Alcotest.(check bool) "2035 has resumed Epiphany Sundays" true (resumed <> []) +module Cel = Colitur_kernel.Celebration +module Sl = Colitur_kernel.Slug +module Colr = Colitur_kernel.Colour + +let office dt = (T.temporal dt).Colitur_kernel.Temporal.office +let slug_of dt = Sl.to_string (office dt).Cel.slug +let rank_of dt = V.rank_to_string (office dt).Cel.rank +let colour_of dt = Colr.to_string (office dt).Cel.colour + +let test_ferial_slugs_and_ranks () = + (* Ferias key on season-week-weekday, matching lectio's lectionary keys. *) + Alcotest.(check string) "Lent feria" "ef-lent-3-monday" (slug_of (d 2026 3 9)); + (* RG 91 entry 22: Lent and Passiontide ferias are III class. *) + Alcotest.(check string) "Lent feria is III class" "class-3" (rank_of (d 2026 3 9)); + (* RG 91 entry 25: Advent ferias to 16 December are III class ... *) + Alcotest.(check string) "Advent 15 Dec is III class" "class-3" (rank_of (d 2026 12 15)); + (* ... entry 18: Advent 17-23 December are II class. lectio marks all Advent + ferias III class; this is a deliberate divergence. 21 Dec (not 18 Dec) is + used deliberately: 18 Dec 2026 is also the Advent Ember Friday, which + would independently be II class via the Ember rule and so would not + isolate this one. *) + Alcotest.(check string) "Advent 21 Dec is II class" "class-2" (rank_of (d 2026 12 21)); + (* RG 91 entry 28: per annum ferias are IV class. *) + Alcotest.(check string) "per annum feria is IV class" "class-4" (rank_of (d 2026 7 15)); + (* RG 91 entries 7 and 10: Holy Week and the privileged octaves are I class. *) + Alcotest.(check string) "Holy Monday is I class" "class-1" (rank_of (d 2026 3 30)); + (* Good Friday: RG 91 entry 7 covers only Ash Wed and Mon-Wed of Holy Week -- + Thursday-Saturday are the Sacred Triduum, entry 2, still I class. *) + Alcotest.(check string) "Good Friday is I class" "class-1" (rank_of (d 2026 4 3)); + Alcotest.(check string) "Easter Monday is I class" "class-1" (rank_of (d 2026 4 6)); + Alcotest.(check string) "Whit Monday is I class" "class-1" (rank_of (d 2026 5 25)) + +let test_after_ashes () = + Alcotest.(check string) "Thursday after Ash Wednesday" "ef-lent-after-ashes-thursday" + (slug_of (d 2026 2 19)); + Alcotest.(check (option int)) "outside a numbered week" None + (T.temporal (d 2026 2 19)).Colitur_kernel.Temporal.week + +let test_ember_days () = + (* September Ember days: Wed/Fri/Sat after the third Sunday of September. + Third Sunday of September 2026 = 20 September. *) + Alcotest.(check string) "September Ember Wed" "ef-september-ember-wed" (slug_of (d 2026 9 23)); + Alcotest.(check string) "September Ember Sat" "ef-september-ember-sat" (slug_of (d 2026 9 26)); + Alcotest.(check string) "September Ember is II class" "class-2" (rank_of (d 2026 9 23)); + (* Advent Ember days: after Advent III (2026: 13 December). *) + Alcotest.(check string) "Advent Ember Wed" "ef-advent-ember-wed" (slug_of (d 2026 12 16)); + (* Lenten Ember days: after Lent I (2026: 22 February). RG 91 entry 18 makes + them II class -- entry 22 excepts them from the III-class Lenten ferias. + lectio treats them as ordinary Lenten ferias. *) + Alcotest.(check string) "Lent Ember Wed" "ef-lent-ember-wed" (slug_of (d 2026 2 25)); + Alcotest.(check string) "Lent Ember is II class" "class-2" (rank_of (d 2026 2 25)); + (* Whitsun Ember days sit inside the I-class Pentecost octave. *) + Alcotest.(check string) "Whit Ember Wed" "ef-pentecost-ember-wed" (slug_of (d 2026 5 27)); + Alcotest.(check string) "Whit Ember is I class" "class-1" (rank_of (d 2026 5 27)); + (* Thursday is not an Ember day: the [day_of] guard matches only Wed/Fri/Sat + (3/5/6 days after the anchor), never day 4. 24 Sept 2026 is the Thursday + after the September anchor and must fall back to an ordinary IV-class + per annum feria, not an Ember slug. *) + Alcotest.(check string) "Thursday after the September anchor is not Ember" "class-4" + (rank_of (d 2026 9 24)) + +let test_rogations () = + (* RG 80/87: Minor Litanies on the Monday and Tuesday before Ascension. The + Wednesday is the Ascension vigil (see Task 11). *) + Alcotest.(check string) "Rogation Monday" "ef-rogation-monday" (slug_of (d 2026 5 11)); + Alcotest.(check string) "Rogation Tuesday" "ef-rogation-tuesday" (slug_of (d 2026 5 12)); + Alcotest.(check string) "Wednesday is the vigil" "ef-ascension-vigil" (slug_of (d 2026 5 13)); + (* RG 88: "de Litaniis minoribus nihil fit in Officio" -- the Rogation + changes the Mass, not the Office, and no RG 91 table entry ranks these + days specially, so they keep the ordinary IV-class rank of an unprivileged + Paschaltide feria (entry 28's catch-all). *) + Alcotest.(check string) "Rogation Monday keeps the ordinary ferial rank" "class-4" + (rank_of (d 2026 5 11)) + +let test_colours () = + Alcotest.(check string) "Advent is violet" "violet" (colour_of (d 2026 12 1)); + Alcotest.(check string) "per annum is green" "green" (colour_of (d 2026 7 15)); + Alcotest.(check string) "Paschaltide is white" "white" (colour_of (d 2026 4 20)); + Alcotest.(check string) "Pentecost octave is red" "red" (colour_of (d 2026 5 25)); + (* Gaudete = Advent III, Laetare = Lent IV. *) + Alcotest.(check string) "Gaudete is rose" "rose" (colour_of (d 2026 12 13)); + Alcotest.(check string) "Laetare is rose" "rose" (colour_of (d 2026 3 15)) + +let test_totality () = + (* Every day of 2026 yields an office, and every slug is well-formed. *) + let jan1 = d 2026 1 1 in + for i = 0 to 364 do + let dt = D.add_days jan1 i in + let s = slug_of dt in + match Sl.of_string s with + | Ok _ -> () + | Error e -> Alcotest.failf "%s: %s" (D.to_iso8601 dt) e + done + let suite_extra = [ Alcotest.test_case "advent start" `Quick test_advent_start; Alcotest.test_case "seasons" `Quick test_seasons; @@ -171,7 +265,13 @@ let suite_extra = Alcotest.test_case "week numbers" `Quick test_week_numbers; Alcotest.test_case "sunday slugs" `Quick test_sunday_slugs; Alcotest.test_case "week/sunday_slug agree" `Quick test_week_sunday_slug_agree; - Alcotest.test_case "resumed sundays" `Quick test_resumed_sundays ] + Alcotest.test_case "resumed sundays" `Quick test_resumed_sundays; + Alcotest.test_case "ferial slugs and ranks" `Quick test_ferial_slugs_and_ranks; + Alcotest.test_case "after ashes" `Quick test_after_ashes; + Alcotest.test_case "ember days" `Quick test_ember_days; + Alcotest.test_case "rogations" `Quick test_rogations; + Alcotest.test_case "colours" `Quick test_colours; + Alcotest.test_case "totality" `Quick test_totality ] let suite = ( "Rite_ef", |
