From 95901ef56a37481c83bd20ea327bf0f5d9da9f02 Mon Sep 17 00:00:00 2001 From: Will Estes Date: Sun, 30 Aug 2026 06:10:14 -0400 Subject: [PATCH] Always list the day's actual winner first in getDayLabel The anchor-day and plain-temporal-fallback branches were listing any commemorated saint before the winning identity, so a lower-ranked saint merely riding along as a commemoration (e.g. St. Andrew on Advent I, or Ss. Tryphon/Respicius/Nympha on an ordinary Sunday) read as if it were the day's own winner, with the actual winner's rank label dangling at the end with no name attached. The winner should always lead. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01ME8QNPdEmHSbSx1r6VmDRG --- src/calendar/day-label.ts | 8 ++++---- tests/calendar/day-label.test.ts | 16 ++++++++-------- tests/hours/compline.test.ts | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/calendar/day-label.ts b/src/calendar/day-label.ts index c5a4928..fe1b61e 100644 --- a/src/calendar/day-label.ts +++ b/src/calendar/day-label.ts @@ -561,12 +561,12 @@ export function getDayLabel(day: LiturgicalDay): Partial> // anchorDayName's own doc comment — checked before the octave case // below since Trinity Sunday, e.g., also happens to be day 8 of // Pentecost's octave, and the anchor name is what actually governs. - // Existing convention: a commemorated saint *leads* here, before the - // anchor name — not "winner first" like every branch above. + // Winner first, same as every other branch here — the anchor day is + // what's actually being celebrated even when a lesser saint rides along. const anchorName = anchorDayName(day); if (anchorName) { const { sanctoral } = collectCommemorations(day, { showOctaves: false }); - return joinBi([...sanctoral, anchorName]); + return joinBi([anchorName, ...sanctoral]); } // An active octave (St. Lawrence's, ...) is this day's real primary @@ -609,5 +609,5 @@ export function getDayLabel(day: LiturgicalDay): Partial> const label = temporalLabel(day); const temporal = bi(`${label.en} (${temporalRank.en})`, `${label.la} (${temporalRank.la})`); const { sanctoral } = collectCommemorations(day, { showOctaves: false }); - return joinBi([...sanctoral, temporal]); + return joinBi([temporal, ...sanctoral]); } diff --git a/tests/calendar/day-label.test.ts b/tests/calendar/day-label.test.ts index 32c1f0f..612d454 100644 --- a/tests/calendar/day-label.test.ts +++ b/tests/calendar/day-label.test.ts @@ -60,9 +60,9 @@ describe('getDayLabel — ordinal temporal label', () => { // the November sanctoral pull, he's correctly commemorated alongside // Advent I rather than simply absent (confirmed against the live // reference engine, which shows the same pairing), so the label - // reflects both, feast name first, same pattern as Trinity Sunday's - // own St. Felix I case above. - expect(getDayLabel(resolveDay('2025-11-30')).en).toBe('St. Andrew, Apostle — The 1st Sunday of Advent (Semiduplex)'); + // reflects both, winner (Advent I, so privileged nothing can displace + // it) first, commemorated saint after. + expect(getDayLabel(resolveDay('2025-11-30')).en).toBe('The 1st Sunday of Advent (Semiduplex) — St. Andrew, Apostle'); // Advent drops the redundant leading weekday word now that the header // always shows the weekday on its own (see temporalLabel's // `dropWeekdayPrefix`). @@ -98,10 +98,10 @@ describe('getDayLabel — resumed post-Epiphany Sunday (overflow years)', () => // Sundays) -- see calendar/temporal-id.test.ts for the id-level // coverage this label check builds on. Nov 10 itself also carries a // Simplex commemoration (Ss. Tryphon, Respicius, and Nympha), shown - // appended to the Sunday's own label per this app's usual - // commemorated-Simplex display. + // trailing after the Sunday's own winning label per this app's usual + // winner-first display. expect(getDayLabel(resolveDay('2024-11-10')).en).toBe( - 'Ss. Tryphon, Respicius, and Nympha, Martyrs — The 5th Sunday after Epiphany (Semiduplex)', + 'The 5th Sunday after Epiphany (Semiduplex) — Ss. Tryphon, Respicius, and Nympha, Martyrs', ); // 2024-11-11 is St. Martin of Tours (Duplex, pre-existing content) -- // an ordinary (non-privileged) Monday fully yields to a real winning @@ -368,12 +368,12 @@ describe('getDayLabel — feast name combination', () => { expect(getDayLabel(day).en).toBe('St. Ereden (Duplex)'); }); - it('shows both, feast first, when the feast is merely commemorated', () => { + it('shows both, winner first, when a feast is merely commemorated', () => { const day: LiturgicalDay = { ...base, commemorations: [{ kind: 'sanctoral', id: 'x', name: 'St. Ereden', rank: 'duplex-2-classis' }], }; - expect(getDayLabel(day).en).toBe('St. Ereden — Monday in the 3rd week after Trinity (Feria)'); + expect(getDayLabel(day).en).toBe('Monday in the 3rd week after Trinity (Feria) — St. Ereden'); }); it('shows just the temporal label when nothing is commemorated at all', () => { diff --git a/tests/hours/compline.test.ts b/tests/hours/compline.test.ts index 6db02d4..f5c1649 100644 --- a/tests/hours/compline.test.ts +++ b/tests/hours/compline.test.ts @@ -114,7 +114,7 @@ describe('resolveOrdo("compline", ...)', () => { const eve = resolveOrdo('compline', '2025-11-29'); const last = eve.parts[eve.parts.length - 1]; expect(last?.kind === 'preces' ? last.label : undefined).toBe('Alma Redemptoris Mater'); - expect(eve.dayLabel?.en).toBe('St. Andrew, Apostle — The 1st Sunday of Advent (Semiduplex)'); + expect(eve.dayLabel?.en).toBe('The 1st Sunday of Advent (Semiduplex) — St. Andrew, Apostle'); const dayBefore = resolveOrdo('compline', '2025-11-28'); const lastBefore = dayBefore.parts[dayBefore.parts.length - 1];