aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-07-27 12:24:24 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-07-27 12:24:24 +0200
commita8232892b0ec94f8d077e3730143a09efcac452d (patch)
tree35e823967d3b98c52107e732f5382f382a583011 /internal
parent0b68ec046c26292e368494e158cc36b342901a80 (diff)
downloadlectio-a8232892b0ec94f8d077e3730143a09efcac452d.tar.gz
lectio-a8232892b0ec94f8d077e3730143a09efcac452d.zip
fix(calendar): Christmas solemnity in temporal; feasts of the Lord band 5; Sunday band before solemnity-rank fallback
Diffstat (limited to 'internal')
-rw-r--r--internal/calendar/precedence.go12
-rw-r--r--internal/calendar/refine_test.go30
-rw-r--r--internal/calendar/temporal.go2
3 files changed, 40 insertions, 4 deletions
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):