Add regression tests for Decollation's ferial-numbers/proper-antiphons split
Deploy / deploy (push) Successful in 1m23s

Confirms 2026-08-29 Lauds and 2026-08-28 First Vespers both keep the
ferial psalm numbers (Duplex, below duplex-majus) while still layering
on the feast's own proper antiphons -- and that an override group with
no matching ferial slot (Puellae saltanti / Arguebat) is dropped, not
substituted in.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018sPkfGLiq58pmmDoBWH5UX
This commit is contained in:
2026-08-29 10:27:39 -04:00
parent 631d133b16
commit d77c9ca68f
2 changed files with 64 additions and 0 deletions
+38
View File
@@ -680,6 +680,44 @@ describe('resolveOrdo("lauds", ...)', () => {
const hymn = ordo.parts.find((p) => p.kind === 'hymn');
expect(hymn?.kind === 'hymn' ? hymn.text.text.la : undefined).toContain('Auróra lucis rútilat');
});
it("keeps Saturday's ferial psalm numbers for the Beheading of St. John the Baptist (Duplex, below duplex-majus), while still using his own proper antiphons", () => {
// Regression test: decollation-of-st-john-baptist.yml's own psalm
// numbers (92/99/62) used to leak in below duplex-majus once
// getPsalmodyProperOverrideId (f3cf30c) made the antiphon tier
// rank-agnostic -- the psalm numbers themselves must stay gated at
// duplex-majus+ and fall back to Saturday's ferial cycle (50, split
// 142 canticle) instead, with the proper antiphons layered on top by
// group index.
const ordo = resolveOrdo('lauds', '2026-08-29');
const psalmNumbers = ordo.parts
.filter((p) => p.kind === 'psalm')
.map((p) => (p.kind === 'psalm' ? p.psalmNumber : undefined));
expect(psalmNumbers).toEqual([66, 50, 142, 148, 149, 150]);
const ps50 = ordo.parts.find((p) => p.kind === 'psalm' && p.psalmNumber === 50);
expect(ps50?.kind === 'psalm' ? ps50.antiphon?.text.la : undefined).toBe(
'Ant. Heródes enim ténuit * et ligávit Joánnem et pósuit in cárcerem propter Herodíadem.',
);
const ps142 = ordo.parts.find((p) => p.kind === 'psalm' && p.psalmNumber === 142);
expect(ps142?.kind === 'psalm' ? ps142.antiphon?.text.la : undefined).toBe(
'Ant. Dómine mi rex, * da mihi in disco caput Joánnis Baptístæ.',
);
// decollation's own third group (Ps 62, "Puéllæ saltánti") has no
// matching slot in Saturday's own 2-group ferial default and is
// simply unused -- confirmed with the user 2026-08-29.
expect(psalmNumbers).not.toContain(62);
const puellaeSaltanti = ordo.parts.some(
(p) => p.kind === 'antiphon' && p.text.text.la?.includes('Puéllæ saltánti'),
);
expect(puellaeSaltanti).toBe(false);
const laudate = ordo.parts.find((p) => p.kind === 'psalm' && p.psalmNumber === 148);
expect(laudate?.kind === 'psalm' ? laudate.antiphon?.text.la : undefined).toBe(
'Ant. Da mihi in disco * caput Joánnis Baptístæ. Et contristátus est rex propter jusjurándum.',
);
});
});
describe('resolveOrdo("lauds", ...) responsory Gloria omission', () => {
+26
View File
@@ -487,6 +487,32 @@ describe('resolveOrdo("vespers", ...)', () => {
expect(psalms.some((p) => p.antiphon?.text.la?.includes('Cóllocet eum'))).toBe(false);
});
it("keeps Friday's ferial psalm numbers for the Beheading of St. John the Baptist's First Vespers (Duplex, below duplex-majus), while still using his own proper antiphons", () => {
// Regression test, mirrors the equivalent Lauds test: decollation-of-
// st-john-baptist.yml's own psalm numbers (109/111/112/115) must stay
// gated at duplex-majus+ and fall back to the ferial cycle for the
// evening's own weekday (2026-08-28 is a Friday) instead, with the
// proper's antiphons layered on top by group index. His 4th group
// ("Arguébat", keyed to Ps 115) has no matching slot in Friday's own
// 3-group ferial default and is simply unused.
const ordo = resolveOrdo('vespers', '2026-08-28');
const psalmNumbers = ordo.parts
.filter((p) => p.kind === 'psalm')
.map((p) => (p.kind === 'psalm' ? p.psalmNumber : undefined));
expect(psalmNumbers).not.toEqual(expect.arrayContaining([109, 111, 112, 115]));
const psalms = ordo.parts.filter((p) => p.kind === 'psalm') as {
psalmNumber: number;
antiphon?: { text: Record<string, string> };
}[];
expect(psalms[0]?.antiphon?.text.la).toBe(
'Ant. Heródes enim ténuit * et ligávit Joánnem et pósuit in cárcerem propter Herodíadem.',
);
const arguebat = ordo.parts.some((p) => p.kind === 'antiphon' && p.text.text.la?.includes('Arguébat'));
expect(arguebat).toBe(false);
});
it("no longer gives St. Margaret of Scotland First Vespers now that Corpus Christi's own octave is modeled", () => {
// St. Margaret of Scotland (Jun 10, Semiduplex, common-of-a-widow --
// content itself live-verified 2026-08-26 to be real, identical to