package calendar_test // Reproduction tests for three named EF precedence defects (colitur's // differential/oracle audit against lectio's ~66-line EF precedence // approximation, internal/calendar/precedence_ef.go). Each test fails before // its fix and passes after -- see the report for the exact pre-fix failure // message. These exercise the REAL tridentine sanctoral data // (caldata.Tridentine()) through the public Compute entry point, since the // bugs are about how real fixed-date feasts interact with the temporal // calendar, not about precedenceEF's arithmetic in isolation (that is // covered separately, package-internal, in precedence_ef_test.go). import ( "testing" "time" "github.com/lukaszkasprzak/lectio/internal/caldata" "github.com/lukaszkasprzak/lectio/internal/calendar" ) func efCompute(date string) calendar.LiturgicalDay { sel := calendar.DefaultSelection() sel.Form = "old" d, _ := time.Parse("2006-01-02", date) return calendar.Compute(d.UTC(), sel, []calendar.Layer{caldata.Tridentine()}) } // TestJosephYieldsToSundayOfLent: RG 91 entry 6 (Sundays of Lent, I class) // vs entry 11 (I-class feasts of the universal Church not above) -- the // Sunday holds; St Joseph (19 March) transfers to the next free day (RG 95, // RG 96), landing on the 20th. Before the fix (defect 4: Sunday ranks), Lent // Sundays were wrongly II class, so Joseph (I class) won outright every time // this collision occurred. func TestJosephYieldsToSundayOfLent(t *testing.T) { for _, year := range []string{"2006", "2017", "2023", "2028", "2034", "2045"} { sunday := efCompute(year + "-03-19") if sunday.Observed.Slug == "joseph-spouse-of-the-bl-virgin-mary" { t.Errorf("%s-03-19 observed = %q want the Lent Sunday (RG 91 entry 6 beats entry 11)", year, sunday.Observed.Slug) } next := efCompute(year + "-03-20") if next.Observed.Slug != "joseph-spouse-of-the-bl-virgin-mary" { t.Errorf("%s-03-20 observed = %q want joseph-spouse-of-the-bl-virgin-mary (transferred one day, RG 96)", year, next.Observed.Slug) } } } // TestTransferSkipsBothIAndIIClass: RG 96 -- an impeded I-class feast // transfers to the next day that is NOT ITSELF I OR II CLASS (not merely "not // I class"). 2011: the Sacred Heart (Friday after the Corpus Christi octave) // falls on 1 July and impedes the Precious Blood (also 1 July, fixed). 2 // July is the Visitation (II class, fixed); 3 July is an ordinary II-class // Sunday. Both must be skipped; the Precious Blood lands on 4 July, and the // Visitation is observed, undisplaced, on its own day. func TestTransferSkipsBothIAndIIClass(t *testing.T) { if got := efCompute("2011-07-01").Observed.Slug; got != "ef-sacred-heart" { t.Fatalf("2011-07-01 observed = %q want ef-sacred-heart", got) } if got := efCompute("2011-07-02").Observed.Slug; got != "visitation-of-the-blessed-virgin-mary" { t.Errorf("2011-07-02 observed = %q want visitation-of-the-blessed-virgin-mary (RG 96: the Precious Blood must skip past it, not displace it)", got) } if got := efCompute("2011-07-03").Observed.Slug; got != "ef-time-after-pentecost-sunday-3" { t.Errorf("2011-07-03 observed = %q want ef-time-after-pentecost-sunday-3 (an ordinary II-class Sunday also blocks a I-class transfer)", got) } if got := efCompute("2011-07-04").Observed.Slug; got != "precious-blood-of-our-lord-jesus-christ" { t.Errorf("2011-07-04 observed = %q want precious-blood-of-our-lord-jesus-christ (RG 96: first day that is neither I nor II class)", got) } } // TestMatthewBeatsSeptemberEmberWednesday: RG 91 -- St Matthew (21 September, // II class) and the September Ember Wednesday are both II class; the table // decides the tie. Entry 16 (II-class feasts of the universal Church) sits // ABOVE entry 18 (II-class ferias, including the Ember days) -- the feast // wins, the Ember feria is only commemorated. func TestMatthewBeatsSeptemberEmberWednesday(t *testing.T) { // 21 September falls on the September Ember Wednesday whenever the third // Sunday of September is the 18th -- 2016 and 2022 both qualify. for _, date := range []string{"2016-09-21", "2022-09-21"} { day := efCompute(date) if day.Observed.Slug != "matthew" { t.Errorf("%s observed = %q want matthew (RG 91 entry 16 beats entry 18)", date, day.Observed.Slug) } } }