diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-14 13:22:16 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-14 13:22:16 +0200 |
| commit | 913974b10a993af251b25125d1a417c452ad785c (patch) | |
| tree | 5dd82811c100de6daa995bebd115a12434296508 /internal/calendar/precedence_ef_test.go | |
| parent | d7da4b09f7775276231d0241cfe2700d247728ee (diff) | |
| parent | 3b32c002d3eddda5ece9422442717657b9fee63b (diff) | |
| download | lectio-913974b10a993af251b25125d1a417c452ad785c.tar.gz lectio-913974b10a993af251b25125d1a417c452ad785c.zip | |
Merge branch 'polish-ui-and-calendar': the gomobile facade and the EF calendar fixes
Two bodies of work that shared a branch.
The gomobile facade (2026-08-03..05): mobile.PartLabels, Days, and the
observed rank on DayInfo, so dlectio stops hardcoding part IDs and rank
strings; the 1962 part labels become i18n data; the documented gomobile
bind command is corrected so it reproduces the shipped .aar.
The EF calendar fixes (2026-08-12): seven defects found by differencing
this engine against colitur, a second 1962 implementation built from the
Missal's General Rubrics rather than from this codebase. RG 96 transfers
were not skipping II-class days; a II-class privileged feria was not
yielding to a feast; Sunday ranks, the two Rose Sundays and Holy Thursday's
colour were wrong; and scripts/gen-sanctoral-ef inferred ranks, deduped
and tagged classes wrongly, which put 15 III-class feasts into the shipped
tridentine-calendar.ini as bare commemorations and dropped four entries
outright.
Holy Thursday was violet in both engines, which is how a shared lineage
hides a defect: this project's ini is generated from missalemeum and
colitur's data was bootstrapped from here, so an error inherited by both
is invisible to a differential. It took the Missal itself to see it.
The EF oracle test now asserts rank and colour, not season alone. One
known gap is recorded in the source rather than fixed, as out of scope:
RG 95 chained transfers (calendar.go).
Diffstat (limited to 'internal/calendar/precedence_ef_test.go')
| -rw-r--r-- | internal/calendar/precedence_ef_test.go | 67 |
1 files changed, 58 insertions, 9 deletions
diff --git a/internal/calendar/precedence_ef_test.go b/internal/calendar/precedence_ef_test.go index 818b452..d5e254f 100644 --- a/internal/calendar/precedence_ef_test.go +++ b/internal/calendar/precedence_ef_test.go @@ -6,6 +6,14 @@ func efCand(rank Rank, temporal bool) candidate { return candidate{Cel: Celebration{Rank: rank}, Temporal: temporal} } +// efTemporalCand builds a temporal candidate with the season/Sunday flags +// precedenceEF's tie-break actually reads, so a test claiming to exercise +// "a Sunday" or "a Lenten feria" genuinely sets those fields rather than +// happening to pass for an unrelated reason (e.g. a class difference alone). +func efTemporalCand(rank Rank, season Season, sunday bool) candidate { + return candidate{Cel: Celebration{Rank: rank}, Temporal: true, Season: season, Sunday: sunday} +} + func TestPrecedenceEF(t *testing.T) { c1 := efCand(RankClass1, false) c3 := efCand(RankClass3, false) @@ -14,16 +22,57 @@ func TestPrecedenceEF(t *testing.T) { if !(precedenceEF(c1) < precedenceEF(c3) && precedenceEF(c3) < precedenceEF(c4) && precedenceEF(c4) < precedenceEF(comm)) { t.Error("EF class ordering broken (class-1 > class-3 > class-4 > commemoration)") } - // at equal class, the temporal office wins. - temp := efCand(RankClass2, true) + // a I-class feast beats a II-class Sunday (RG 91 entry 11 vs entry 15 -- + // different classes, so this holds regardless of the tie-break, but the + // candidate is still marked Sunday so the test means what its name says). + sunday2 := efTemporalCand(RankClass2, TimeAfterPentecost, true) + feast1 := efCand(RankClass1, false) + obs, others := pickEF([]candidate{sunday2, feast1}) + if obs.Cel.Rank != RankClass1 || len(others) != 1 { + t.Errorf("I-class feast should win over II-class Sunday, got %+v", obs.Cel) + } +} + +// TestPrecedenceEFClass2SundayVsFeria: RG 91 entries 15/16/18 -- at class 2, +// a SUNDAY wins its tie against an equal-class feast (entry 15 above 16), but +// a privileged FERIA (the Ember days, the late-Advent 17-23 Dec ferias, entry +// 18) YIELDS to one (entry 16 above 18) -- the opposite of the Sunday case. +// This is defect 2's own witness: before the fix, precedenceEF treated every +// non-ordinaryFeria temporal candidate the same way, so an Ember/late-Advent +// feria wrongly won its tie exactly like a Sunday does. +func TestPrecedenceEFClass2SundayVsFeria(t *testing.T) { saint := efCand(RankClass2, false) - obs, _ := pickEF([]candidate{saint, temp}) - if !obs.Temporal { - t.Error("equal-class: temporal office should be observed") + + sunday := efTemporalCand(RankClass2, TimeAfterPentecost, true) + obsSunday, _ := pickEF([]candidate{saint, sunday}) + if !obsSunday.Temporal { + t.Errorf("a II-class Sunday should win its tie against an equal-class feast, got %+v observed", obsSunday.Cel) } - // a I-class feast beats a II-class Sunday. - obs2, others := pickEF([]candidate{efCand(RankClass2, true), efCand(RankClass1, false)}) - if obs2.Cel.Rank != RankClass1 || len(others) != 1 { - t.Errorf("I-class feast should win over II-class Sunday, got %+v", obs2.Cel) + + emberFeria := efTemporalCand(RankClass2, TimeAfterPentecost, false) // e.g. the September Ember Wednesday + obsFeria, _ := pickEF([]candidate{saint, emberFeria}) + if obsFeria.Temporal { + t.Errorf("a II-class privileged feria should yield its tie to an equal-class feast, got %+v observed (temporal)", obsFeria.Cel) + } +} + +// TestPrecedenceEFClass3FeriaSeason: the pre-existing rule (unchanged by +// defect 2's fix), stated explicitly rather than left implicit: an ORDINARY +// III/IV-class feria (per annum, Advent to 16 Dec, Septuagesima) yields to an +// equal-class feast; the ferias of Lent and Passiontide are privileged and +// win instead. +func TestPrecedenceEFClass3FeriaSeason(t *testing.T) { + saint := efCand(RankClass3, false) + + ordinary := efTemporalCand(RankClass3, Advent, false) + obsOrdinary, _ := pickEF([]candidate{saint, ordinary}) + if obsOrdinary.Temporal { + t.Errorf("an ordinary Advent feria should yield to an equal-class feast, got %+v observed (temporal)", obsOrdinary.Cel) + } + + lenten := efTemporalCand(RankClass3, Lent, false) + obsLenten, _ := pickEF([]candidate{saint, lenten}) + if !obsLenten.Temporal { + t.Errorf("a Lenten feria should win its tie against an equal-class feast, got %+v observed", obsLenten.Cel) } } |
