Omit responsories' own closing Gloria Patri throughout Passiontide

A different, wider rule than the psalm/canticle Gloria (Triduum-only):
responsories drop their Gloria for the whole of Passiontide (Passion
Sunday through Holy Saturday), except on a Sancti feast's own day —
live-verified (St. Joseph, Duplex I, 2027-03-19, landing in Passiontide
that year, keeps it; an ordinary ferial day in the same window omits it,
at both Compline and Prime).

Every responsory's stored text differs, Gloria-bearing vs Gloria-free,
by exactly one fixed-wording line, so resolve-common.ts's new
resolveResponsory filters that line out rather than requiring separate
per-season files or a data migration — mechanism first, per the
project's own stated content-authoring order. Wired into the four hours
that have a real responsory (Compline, Prime, Lauds, Vespers); Lauds/
Vespers' existing hand-authored Passiontide-proper responsories were
already Gloria-free and are unaffected.
This commit is contained in:
2026-08-19 06:38:21 -04:00
parent e93fc4032a
commit 9364185f70
9 changed files with 141 additions and 7 deletions
+35
View File
@@ -143,3 +143,38 @@ describe('resolveOrdo("compline", ...)', () => {
);
});
});
describe('resolveOrdo("compline", ...) responsory Gloria omission', () => {
// Passiontide (Passion Sunday through Holy Saturday) is a wider window
// than the psalm/canticle Gloria's own Triduum-only rule, and doesn't
// apply on a Sancti feast's own day even within that window --
// live-verified: 2027-03-19 is St. Joseph (Duplex I), landing inside
// Passiontide that year, keeping "In manus tuas"'s Gloria; 2027-03-15
// is a plain ferial in the same window, and omits it.
const FERIAL_PASSIONTIDE = '2027-03-15';
const FEAST_IN_PASSIONTIDE = '2027-03-19'; // St. Joseph, Duplex I.
const ORDINARY_DATE = '2026-08-20';
it('omits the Gloria on a ferial Passiontide day', () => {
const ordo = resolveOrdo('compline', FERIAL_PASSIONTIDE);
const responsory = ordo.parts.find((p) => p.kind === 'responsory');
expect(responsory?.kind === 'responsory' ? responsory.text.text.la : undefined).not.toContain('Glória Patri');
expect(responsory?.kind === 'responsory' ? responsory.text.text.en : undefined).not.toContain(
'Glory be to the Father',
);
// Everything else about the responsory is untouched.
expect(responsory?.kind === 'responsory' ? responsory.text.text.en : undefined).toContain('Into thy hands, O Lord');
});
it("keeps the Gloria on a Sancti feast's own day, even inside Passiontide", () => {
const ordo = resolveOrdo('compline', FEAST_IN_PASSIONTIDE);
const responsory = ordo.parts.find((p) => p.kind === 'responsory');
expect(responsory?.kind === 'responsory' ? responsory.text.text.la : undefined).toContain('Glória Patri');
});
it('keeps the Gloria on an ordinary date outside Passiontide', () => {
const ordo = resolveOrdo('compline', ORDINARY_DATE);
const responsory = ordo.parts.find((p) => p.kind === 'responsory');
expect(responsory?.kind === 'responsory' ? responsory.text.text.la : undefined).toContain('Glória Patri');
});
});
+19
View File
@@ -320,3 +320,22 @@ describe('resolveOrdo("lauds", ...)', () => {
expect(hymn?.kind === 'hymn' ? hymn.text.text.la : undefined).toContain('Auróra lucis rútilat');
});
});
describe('resolveOrdo("lauds", ...) responsory Gloria omission', () => {
// Real Passiontide already routes to a wholesale different proper-of-
// season responsory (lauds-responsory-passiontide.yml, "Érue a frámea")
// that was already transcribed without a Gloria line -- this just
// confirms the shared mechanism (resolve-common.ts's resolveResponsory)
// doesn't break that, and still applies correctly on an ordinary date.
// Same Passiontide-wide, Sancti-exempt rule as Compline's -- see
// tests/hours/compline.test.ts's own describe block for the live-
// verification dates.
it('has no Gloria on a ferial Passiontide day, has one on an ordinary date', () => {
const passiontideResponsory = resolveOrdo('lauds', '2027-03-15').parts.find((p) => p.kind === 'responsory');
const ordinaryResponsory = resolveOrdo('lauds', '2026-08-20').parts.find((p) => p.kind === 'responsory');
expect(passiontideResponsory?.kind === 'responsory' ? passiontideResponsory.text.text.la : undefined).not.toContain(
'Glória Patri',
);
expect(ordinaryResponsory?.kind === 'responsory' ? ordinaryResponsory.text.text.la : undefined).toContain('Glória Patri');
});
});
+20
View File
@@ -224,3 +224,23 @@ describe('resolveOrdo("prime", ...)', () => {
}
});
});
describe('resolveOrdo("prime", ...) chapter-responsory Gloria omission', () => {
// Same Passiontide-wide, Sancti-exempt rule as Compline's — see
// tests/hours/compline.test.ts's own describe block for the live-
// verification dates.
it('omits the Gloria on a ferial Passiontide day, keeps it on an ordinary date', () => {
const passiontideResponsory = resolveOrdo('prime', '2027-03-15').parts.find((p) => p.kind === 'responsory');
const ordinaryResponsory = resolveOrdo('prime', '2026-08-20').parts.find((p) => p.kind === 'responsory');
expect(passiontideResponsory?.kind === 'responsory' ? passiontideResponsory.text.text.la : undefined).not.toContain(
'Glória Patri',
);
expect(ordinaryResponsory?.kind === 'responsory' ? ordinaryResponsory.text.text.la : undefined).toContain('Glória Patri');
});
it("keeps the Gloria on a Sancti feast's own day, even inside Passiontide", () => {
const ordo = resolveOrdo('prime', '2027-03-19'); // St. Joseph, Duplex I.
const responsory = ordo.parts.find((p) => p.kind === 'responsory');
expect(responsory?.kind === 'responsory' ? responsory.text.text.la : undefined).toContain('Glória Patri');
});
});
+13
View File
@@ -261,3 +261,16 @@ describe('resolveOrdo("vespers", ...)', () => {
expect(versicle).toBeDefined();
});
});
describe('resolveOrdo("vespers", ...) responsory Gloria omission', () => {
// Same shared mechanism/rule as Lauds' — see tests/hours/lauds.test.ts's
// and tests/hours/compline.test.ts's own describe blocks.
it('has no Gloria on a ferial Passiontide day, has one on an ordinary date', () => {
const passiontideResponsory = resolveOrdo('vespers', '2027-03-15').parts.find((p) => p.kind === 'responsory');
const ordinaryResponsory = resolveOrdo('vespers', '2026-08-20').parts.find((p) => p.kind === 'responsory');
expect(passiontideResponsory?.kind === 'responsory' ? passiontideResponsory.text.text.la : undefined).not.toContain(
'Glória Patri',
);
expect(ordinaryResponsory?.kind === 'responsory' ? ordinaryResponsory.text.text.la : undefined).toContain('Glória Patri');
});
});