From a8232892b0ec94f8d077e3730143a09efcac452d Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 27 Jul 2026 12:24:24 +0200 Subject: fix(calendar): Christmas solemnity in temporal; feasts of the Lord band 5; Sunday band before solemnity-rank fallback --- internal/calendar/precedence.go | 12 ++++++++---- internal/calendar/refine_test.go | 30 ++++++++++++++++++++++++++++++ internal/calendar/temporal.go | 2 ++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 internal/calendar/refine_test.go (limited to 'internal') diff --git a/internal/calendar/precedence.go b/internal/calendar/precedence.go index 7919879..c27c5d3 100644 --- a/internal/calendar/precedence.go +++ b/internal/calendar/precedence.go @@ -26,12 +26,12 @@ func precedence(c candidate) int { return 1 case c.Privileged: return 2 + case c.Sunday: // Ordinary/Christmas Sunday (checked before the solemnity-rank fallback) + return 6 case c.Cel.Rank == RankSolemnity: // Trinity, Corpus Christi, Sacred Heart, Christ the King return 3 case c.Cel.Rank == RankFeast: // feasts of the Lord (Baptism, Holy Family) return 5 - case c.Sunday: - return 6 case c.PrivFeria: return 9 default: @@ -45,10 +45,14 @@ func precedence(c candidate) int { } return 3 case RankFeast: - if proper { + switch { + case proper: return 8 + case c.Cel.Class == ClassLord: // feasts of the Lord in the General Calendar + return 5 + default: + return 7 } - return 7 case RankMemorial: if proper { return 11 diff --git a/internal/calendar/refine_test.go b/internal/calendar/refine_test.go new file mode 100644 index 0000000..1f376c4 --- /dev/null +++ b/internal/calendar/refine_test.go @@ -0,0 +1,30 @@ +package calendar + +import "testing" + +func TestChristmasIsSolemnity(t *testing.T) { + got := Compute(d("2025-12-25"), DefaultSelection(), []Layer{universalTest()}) + if got.Season != Christmas || got.Observed.Slug != "christmas" || got.Observed.Rank != RankSolemnity { + t.Errorf("2025-12-25 = %s/%s/%v, want christmas/solemnity", got.Season, got.Observed.Slug, got.Observed.Rank) + } +} + +func TestFeastOfLordReplacesSunday(t *testing.T) { + // A feast of the Lord (band 5) must replace an Ordinary Sunday (band 6); + // a saint's feast (band 7) must not. 2025-08-10 is an Ordinary Sunday. + layer := Layer{ID: "universal", Cels: map[string]RawCelebration{ + "transfiguration-test": {Fields: map[string]string{"date": "08-10", "rank": "feast", "class": "lord", "name.en": "L"}, Variants: map[string]map[string]string{}}, + }} + got := Compute(d("2025-08-10"), DefaultSelection(), []Layer{layer}) + if got.Observed.Slug != "transfiguration-test" { + t.Errorf("feast of the Lord did not replace the Sunday: observed %q", got.Observed.Slug) + } + + saintLayer := Layer{ID: "universal", Cels: map[string]RawCelebration{ + "a-saint": {Fields: map[string]string{"date": "08-10", "rank": "feast", "class": "saint", "name.en": "S"}, Variants: map[string]map[string]string{}}, + }} + got2 := Compute(d("2025-08-10"), DefaultSelection(), []Layer{saintLayer}) + if got2.Observed.Layer != "temporal" { + t.Errorf("a saint's feast must not replace the Sunday: observed %q", got2.Observed.Slug) + } +} diff --git a/internal/calendar/temporal.go b/internal/calendar/temporal.go index 011e023..568efdc 100644 --- a/internal/calendar/temporal.go +++ b/internal/calendar/temporal.go @@ -150,6 +150,8 @@ func temporal(date time.Time, sel Selection) temporalDay { return solemn(Ordinary, "sacred-heart", White, false) case sameDay(date, christTheKing): return solemn(Ordinary, "christ-the-king", White, false) + case sameDay(date, christmasThis): + return solemn(Christmas, "christmas", White, true) case sameDay(date, epiphany(y, sel)): return solemn(Christmas, "epiphany", White, true) case sameDay(date, baptismThis): -- cgit v1.3