diff options
Diffstat (limited to 'internal/calendar')
| -rw-r--r-- | internal/calendar/temporal_ef.go | 26 | ||||
| -rw-r--r-- | internal/calendar/temporal_ef_test.go | 44 |
2 files changed, 70 insertions, 0 deletions
diff --git a/internal/calendar/temporal_ef.go b/internal/calendar/temporal_ef.go index 26ad930..7d31b8b 100644 --- a/internal/calendar/temporal_ef.go +++ b/internal/calendar/temporal_ef.go @@ -276,6 +276,32 @@ func temporalEF(date time.Time) temporalDay { // Unique ferial slug (season-week-weekday) so proper ferias (Lent, Advent, // Holy Week, Ember days) can key their own readings; green-season ferias // simply have no lectionary entry and fall back to the Sunday. + // RG 78 (Caput IX, "De sancta Maria in sabbato"): "In sabbatis, in quibus + // occurrit Officium de feria IV classis, fit de sancta Maria in sabbato." + // On a Saturday whose office would otherwise be a IV-class feria, the + // office is the votive Office of Our Lady, and it is white -- RG 431(e) + // classes that Mass as "Missa votiva IV classis ... de B. Maria Virg.", + // RG 121(a) gives a votive Mass the colour of the feast-type it answers + // to, and RG 120(b) makes feasts of the BVM white. + // + // The protasis is "a IV-class feria", which by this point in the function + // is exactly what rank still being RankClass4 means: every branch above + // has already promoted Advent, Lent, Passiontide, the Ember days, the + // privileged ferias and the Christmas octave out of it. Nothing further + // needs testing. + // + // The SLUG IS DELIBERATELY UNCHANGED. colitur, which has built this office + // since its v0.3.0, does the same and for a reason worth repeating: a + // bespoke slug would recur many times a year and break the "one slug per + // liturgical year" invariant, and the day's readings are selected by the + // Mass formulary rather than by the slug. Only the colour moves here. + // + // This is the temporal office only. If a sanctoral feast outranks the + // IV-class Saturday it wins as before and brings its own colour, exactly + // as it did when this day was a plain green feria. + if rank == RankClass4 && date.Weekday() == time.Saturday { + col = White + } return efCel(season, "ef-"+string(slugSeason)+"-"+strconv.Itoa(week)+"-"+weekdayLower(date), col, rank, week) } diff --git a/internal/calendar/temporal_ef_test.go b/internal/calendar/temporal_ef_test.go index a7fa8b0..1290a59 100644 --- a/internal/calendar/temporal_ef_test.go +++ b/internal/calendar/temporal_ef_test.go @@ -1,6 +1,7 @@ package calendar import ( + "strings" "testing" "time" ) @@ -256,3 +257,46 @@ func TestTemporalEFEpiphanyWeekAnchor(t *testing.T) { y, anchor.Format("2006-01-02"), got) } } + +// TestTemporalEFBVMSaturday pins RG 78, the votive Office of Our Lady on +// Saturday: "In sabbatis, in quibus occurrit Officium de feria IV classis, fit +// de sancta Maria in sabbato." A Saturday whose office would otherwise be a +// IV-class feria keeps Our Lady's office instead, and it is white. +// +// Two things are asserted in opposite directions on purpose. The office +// applies only where the feria really is IV class, so a Saturday in Lent or +// Advent -- III class ferias, violet -- must NOT turn white; and the slug must +// NOT change, because the day's readings are still the feria's and a bespoke +// slug would recur many times a year. +func TestTemporalEFBVMSaturday(t *testing.T) { + // Ordinary per-annum Saturdays: IV class, so Our Lady's office, white. + for _, day := range []string{"2026-06-20", "2026-06-27", "2026-07-04", "2026-10-31"} { + got := temporalEF(d(day)) + if got.Cel.Colour != White { + t.Errorf("%s: colour = %s, want white (RG 78, Our Lady on Saturday)", day, got.Cel.Colour) + } + if got.Cel.Rank != RankClass4 { + t.Errorf("%s: rank = %v, want class-4 -- the office does not change the rank", day, got.Cel.Rank) + } + if !strings.HasPrefix(got.Cel.Slug, "ef-time-after-pentecost-") { + t.Errorf("%s: slug = %q, want the ferial slug unchanged -- the readings are "+ + "still the feria's and a bespoke slug would recur many times a year", day, got.Cel.Slug) + } + } + // Saturdays whose feria is NOT IV class keep their own colour. Lent and + // Advent ferias are III class and violet; a fix that whitened every + // Saturday would fail here. + for _, c := range []struct { + day string + colour Colour + }{ + {"2026-03-07", Violet}, // Saturday in Lent + {"2026-12-05", Violet}, // Saturday in Advent + {"2026-04-04", Violet}, // Holy Saturday -- I class, privileged + } { + if got := temporalEF(d(c.day)).Cel.Colour; got != c.colour { + t.Errorf("%s: colour = %s, want %s -- RG 78 applies only where the feria is IV class", + c.day, got, c.colour) + } + } +} |
