fb66f60770
Deploy / deploy (push) Successful in 51s
Three things prompted by today's date resolving wrong: 1. St. Joseph's own Lauds suffrage was never modeled at all. Added lauds-suffrage-joseph.yml, sourced from Tridentine 1906/1910 (the reference engine's "Tridentine - 1906" version) per direct instruction -- Monastic 1617's own suffrage set has no Joseph suffrage at Lauds, so this one genuinely comes from a different track than the other four. 2. The Cross suffrage's actual gating rule, live-verified against a plain ferial win, a plain Sunday win, a low-rank saint's own win (even bare Simplex), and Marian Saturday: it shows only when the bare temporal feria itself is what's being prayed -- the opposite of "Sunday or a feast of the Lord." Expressed as `!isSundayOrFeast(day)` (the same ferial/festive split Prime's capitulum already uses) plus one more exclusion for a named temporal identity like Marian Saturday, which isn't Sunday or a sanctoral win either but still isn't a bare ferial office. 3. The BVM suffrage is correctly dropped on Marian Saturday (unchanged behavior, just now understood and commented correctly): it's specific to a day whose own office is already Marian, confirmed via the same live source, not a guess. Also models St. Clare (Aug 12, Simplex under Monastic 1617) and surfaces active octaves in getDayLabel, since today's date was resolving as a plain ferial day instead of showing St. Lawrence's octave with St. Clare commemorated. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
86 lines
4.9 KiB
TypeScript
86 lines
4.9 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { resolveOrdo } from '../../src/hours';
|
|
|
|
describe('Lauds psalmody override (duplex-majus+ sanctoral, and Marian Saturday)', () => {
|
|
it("substitutes St. Lawrence's own proper psalmody on his own day (Duplex II. classis, above the threshold)", () => {
|
|
const ordo = resolveOrdo('lauds', '2026-08-10');
|
|
const psalmNumbers = ordo.parts
|
|
.filter((p) => p.kind === 'psalm')
|
|
.map((p) => (p.kind === 'psalm' ? p.psalmNumber : undefined));
|
|
expect(psalmNumbers).toEqual([66, 92, 99, 62, 148, 149, 150]);
|
|
|
|
const ps92 = ordo.parts.find((p) => p.kind === 'psalm' && p.psalmNumber === 92);
|
|
expect(ps92?.kind === 'psalm' ? ps92.antiphon?.text.en : undefined).toContain('Lawrence went in to be a martyr');
|
|
|
|
const canticle = ordo.parts.find((p) => p.kind === 'canticle' && p.canticleId !== 'benedictus');
|
|
expect(canticle?.kind === 'canticle' ? canticle.canticleId : undefined).toBe('canticum-trium-puerorum');
|
|
});
|
|
|
|
it("doesn't override a saint below duplex-majus (e.g. Semiduplex) -- plain weekday psalmody still used", () => {
|
|
// 2026-09-19: St. Januarius, Semiduplex (below duplex-majus) -- see
|
|
// tests/calendar/marian-saturday.test.ts for confirming he wins
|
|
// outright as the day's winner despite it being a Saturday.
|
|
const ordo = resolveOrdo('lauds', '2026-09-19');
|
|
const psalmNumbers = ordo.parts
|
|
.filter((p) => p.kind === 'psalm')
|
|
.map((p) => (p.kind === 'psalm' ? p.psalmNumber : undefined));
|
|
// Saturday's own plain default (Ps 50 + 142), not the Common-shaped
|
|
// override -- no lauds-psalmody-overrides/st-januarius.yml exists.
|
|
expect(psalmNumbers).toEqual([66, 50, 142, 148, 149, 150]);
|
|
});
|
|
|
|
it("substitutes Our Lady's Saturday own proper psalmody, unconditionally, whenever it wins", () => {
|
|
const ordo = resolveOrdo('lauds', '2026-10-24'); // a clean, otherwise-empty Marian Saturday
|
|
const psalmNumbers = ordo.parts
|
|
.filter((p) => p.kind === 'psalm')
|
|
.map((p) => (p.kind === 'psalm' ? p.psalmNumber : undefined));
|
|
expect(psalmNumbers).toEqual([66, 92, 99, 62, 148, 149, 150]);
|
|
|
|
const ps92 = ordo.parts.find((p) => p.kind === 'psalm' && p.psalmNumber === 92);
|
|
expect(ps92?.kind === 'psalm' ? ps92.antiphon?.text.la : undefined).toContain('Dum esset Rex');
|
|
|
|
const benedictus = ordo.parts.find((p) => p.kind === 'canticle' && p.canticleId === 'benedictus');
|
|
expect(benedictus?.kind === 'canticle' ? benedictus.antiphon?.text.la : undefined).toContain('Beáta Dei Génitrix');
|
|
|
|
const collect = ordo.parts.find((p) => p.kind === 'prayer');
|
|
expect(collect?.kind === 'prayer' ? collect.text.text.en : undefined).toContain('glorious intercession of the Blessed Mary');
|
|
});
|
|
|
|
it("drops the Holy Cross and Blessed Virgin Mary suffrages on Our Lady's Saturday (the latter redundant with the day's already-Marian office; the former because Marian Saturday isn't a bare ferial office either), keeping Joseph, Apostles, and Peace", () => {
|
|
const ordo = resolveOrdo('lauds', '2026-10-24');
|
|
const labels = ordo.parts.filter((p) => p.kind === 'preces' && p.label).map((p) => (p.kind === 'preces' ? p.label : undefined));
|
|
expect(labels).toEqual(['Of St. Joseph', 'Of the Holy Apostles Peter and Paul', 'For Peace', 'Salve Regina']);
|
|
});
|
|
|
|
it("substitutes Christ the King's own proper psalmody and office bundle, and omits the suffrages entirely (Duplex I. classis)", () => {
|
|
const ordo = resolveOrdo('lauds', '2026-10-25');
|
|
const psalmNumbers = ordo.parts
|
|
.filter((p) => p.kind === 'psalm')
|
|
.map((p) => (p.kind === 'psalm' ? p.psalmNumber : undefined));
|
|
expect(psalmNumbers).toEqual([66, 92, 99, 62, 148, 149, 150]);
|
|
|
|
const ps92 = ordo.parts.find((p) => p.kind === 'psalm' && p.psalmNumber === 92);
|
|
expect(ps92?.kind === 'psalm' ? ps92.antiphon?.text.en : undefined).toContain('The God of heaven');
|
|
|
|
const chapter = ordo.parts.find((p) => p.kind === 'chapter');
|
|
expect(chapter?.kind === 'chapter' ? chapter.text.citation?.en : undefined).toBe('Col 1:12-13');
|
|
|
|
const hymn = ordo.parts.find((p) => p.kind === 'hymn');
|
|
expect(hymn?.kind === 'hymn' ? hymn.text.text.la : undefined).toContain('Vexílla Christus ínclita');
|
|
|
|
const benedictus = ordo.parts.find((p) => p.kind === 'canticle' && p.canticleId === 'benedictus');
|
|
expect(benedictus?.kind === 'canticle' ? benedictus.antiphon?.text.en : undefined).toContain(
|
|
'He hath made us',
|
|
);
|
|
|
|
// Two extra collects: the commemorated Sunday's own, and the Simplex
|
|
// saint already commemorated under that Sunday before Christ the King
|
|
// displaced it too -- see tests/calendar/christ-the-king.test.ts.
|
|
const collects = ordo.parts.filter((p) => p.kind === 'prayer');
|
|
expect(collects.length).toBe(3);
|
|
|
|
const suffrages = ordo.parts.filter((p) => p.kind === 'preces' && p.label && p.label !== 'Salve Regina');
|
|
expect(suffrages).toEqual([]);
|
|
});
|
|
});
|