From 2baaa9a441aaeb22f6fcab096c74d9bfd82f3188 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Tue, 11 Aug 2026 13:47:39 +0200 Subject: rite(ef): Sunday slugs, week numbering and the resumed-Sunday tail Week origins are Sundays, so week numbers are constant Sunday-to-Saturday; the origin is season-specific, which is why Validate must not assume a run starts at 1. When Easter is early the surplus Sundays after Pentecost resume the Sundays after Epiphany that Septuagesima cut short, and the last Sunday before Advent always keeps the 24th (Last) Mass. --- test/test_temporal_ef.ml | 56 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test_temporal_ef.ml b/test/test_temporal_ef.ml index 1353c43..84ee031 100644 --- a/test/test_temporal_ef.ml +++ b/test/test_temporal_ef.ml @@ -88,12 +88,66 @@ let test_nativity_octave () = Alcotest.(check string) "29 Dec" "ef-nativity-octave-day-5" (named_slug (d 2026 12 29)); Alcotest.(check string) "31 Dec" "ef-nativity-octave-day-7" (named_slug (d 2026 12 31)) +let sunday_slug_of dt = match T.sunday_slug dt with Some s -> s | None -> "" + +let test_week_numbers () = + Alcotest.(check (option int)) "Advent I 2026" (Some 1) (T.week (T.advent_start 2026)); + Alcotest.(check (option int)) "Advent II 2026" (Some 2) + (T.week (D.add_days (T.advent_start 2026) 7)); + (* Weeks are Sunday-aligned: the Saturday of week 1 is still week 1. *) + Alcotest.(check (option int)) "Advent I Saturday" (Some 1) + (T.week (D.add_days (T.advent_start 2026) 6)); + (* Time after Pentecost counts from Pentecost, so Trinity is week 1. *) + Alcotest.(check (option int)) "Trinity 2026 is week 1" (Some 1) (T.week (d 2026 5 31)); + (* Christmastide has no numbered weeks. *) + Alcotest.(check (option int)) "Christmastide has no week" None (T.week (d 2026 12 30)) + +let test_sunday_slugs () = + Alcotest.(check string) "Advent I" "ef-advent-sunday-1" (sunday_slug_of (T.advent_start 2026)); + Alcotest.(check string) "Lent I 2026 (22 Feb)" "ef-lent-sunday-1" (sunday_slug_of (d 2026 2 22)); + (* Slugs use lectio's season words: Paschaltide slugs as "easter". *) + Alcotest.(check string) "Paschaltide III 2026 (19 Apr)" "ef-easter-sunday-3" + (sunday_slug_of (d 2026 4 19)); + (* The Sunday within the Octave of the Nativity keeps lectio's key. *) + Alcotest.(check string) "27 Dec 2026" "ef-christmas-sunday-0" (sunday_slug_of (d 2026 12 27)); + (* The Sunday falling 7-13 Jan is the 1st Sunday after Epiphany. Its season is + Christmastide (RG 72-73) but its lectionary key stays lectio's. *) + Alcotest.(check string) "11 Jan 2026" "ef-time-after-epiphany-sunday-1" + (sunday_slug_of (d 2026 1 11)) + +(* The resumed-Sunday tail: when Easter is early there are more than 23 Sundays + after Pentecost, and the surplus resume the Sundays after Epiphany that + Septuagesima cut short. 2038 has Easter on 25 April (the latest possible) and + 1943-style early years have the most Sundays; 2035 (Easter 25 March) is an + early-Easter year with a long tail. *) +let test_resumed_sundays () = + let last_sunday_before_advent y = D.add_days (T.advent_start y) (-7) in + (* The last Sunday before Advent always keeps the 24th (Last) Mass. *) + Alcotest.(check string) "2035 last Sunday" "ef-time-after-pentecost-sunday-24" + (sunday_slug_of (last_sunday_before_advent 2035)); + Alcotest.(check string) "2026 last Sunday" "ef-time-after-pentecost-sunday-24" + (sunday_slug_of (last_sunday_before_advent 2026)); + (* In an early-Easter year the surplus Sundays route to Epiphany Masses. *) + let resumed = + List.filter_map + (fun n -> + let dt = D.add_days (T.advent_start 2035) (-7 - (7 * n)) in + let s = sunday_slug_of dt in + if String.length s >= 27 && String.sub s 0 27 = "ef-time-after-epiphany-sund" then Some s + else None) + [ 1; 2; 3; 4; 5 ] + in + Alcotest.(check bool) "2035 has resumed Epiphany Sundays" true (resumed <> []) + let suite_extra = [ Alcotest.test_case "advent start" `Quick test_advent_start; Alcotest.test_case "seasons" `Quick test_seasons; Alcotest.test_case "named feasts" `Quick test_named_feasts; Alcotest.test_case "christ the king" `Quick test_christ_the_king; - Alcotest.test_case "nativity octave" `Quick test_nativity_octave ] + Alcotest.test_case "nativity octave" `Quick test_nativity_octave; + Alcotest.test_case "week numbers" `Quick test_week_numbers; + Alcotest.test_case "sunday slugs" `Quick test_sunday_slugs; + Alcotest.test_case "resumed sundays" `Quick test_resumed_sundays ] let suite = ( "Rite_ef", -- cgit v1.3