package caldata import ( "strings" "testing" "time" "github.com/lukaszkasprzak/lectio/internal/calendar" ) func TestOFReadingsByCycle(t *testing.T) { // A synthetic OF day keyed christ-the-king-A must resolve to Matt 25. day := calendar.LiturgicalDay{ Observed: calendar.Celebration{Slug: "christ-the-king", Layer: "temporal"}, SundayCycle: "A", Weekday: time.Sunday, } sel := calendar.Selection{Form: "new"} rs := Readings(sel, nil, time.Date(2026, 11, 22, 0, 0, 0, 0, time.UTC), day) var gospel string for _, r := range rs { if r.Part == "gospel" { gospel = r.Citation } } // The gospel of Christ the King (cycle A) is Matthew 25:31-46. The citation // may spell Matthew as "Mat"/"Matt" (niedziela/ToEnglishRef) or "Matthew" // (catholic-resources.org); all resolve to Matthew via books.ini. if !strings.Contains(gospel, "25:31-46") || !(strings.HasPrefix(gospel, "Mat 25") || strings.HasPrefix(gospel, "Matt 25") || strings.HasPrefix(gospel, "Matthew 25")) { t.Fatalf("christ-the-king-A gospel = %q, want Matthew 25:31-46", gospel) } } func TestOFReadings2026Sunday(t *testing.T) { // End-to-end: the real engine + embedded table resolve a 2026 (cycle A) // Sunday's first + gospel. sel := calendar.DefaultSelection() // Form defaults to the OF ("new") layers := []calendar.Layer{Universal()} d := time.Date(2026, 6, 7, 0, 0, 0, 0, time.UTC) // Ordinary Sunday 10, cycle A day := calendar.Compute(d, sel, layers) rs := Readings(sel, layers, d, day) var hasFirst, hasGospel bool for _, r := range rs { if r.Part == "first" && r.Citation != "" { hasFirst = true } if r.Part == "gospel" && r.Citation != "" { hasGospel = true } } if !hasFirst || !hasGospel { t.Fatalf("2026-06-07 OF readings missing first/gospel: %+v (slug %s cycle %s)", rs, day.Observed.Slug, day.SundayCycle) } } func TestOFWeekdayEmpty(t *testing.T) { day := calendar.LiturgicalDay{ Observed: calendar.Celebration{Slug: "ordinary-weekday", Layer: "temporal"}, Weekday: time.Wednesday, // no SundayCycle key -> deferred phase -> empty } if rs := Readings(calendar.Selection{Form: "new"}, nil, time.Now().UTC(), day); len(rs) != 0 { t.Fatalf("weekday should be empty, got %v", rs) } } func TestOFSundayCompleteReadings(t *testing.T) { // Every OF Sunday/solemnity Mass has a SECOND reading; the niedziela harvest // had dropped it on 271 entries, restored from catholic-resources.org. for _, tc := range []struct{ slug, cycle string }{ {"ordinary-sunday-11", "A"}, {"trinity-sunday", "A"}, {"palm-sunday", "B"}, {"pentecost", "C"}, } { day := calendar.LiturgicalDay{ Observed: calendar.Celebration{Slug: tc.slug, Layer: "temporal"}, SundayCycle: tc.cycle, Weekday: time.Sunday, } parts := map[string]bool{} for _, r := range Readings(calendar.Selection{Form: "new"}, nil, time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC), day) { parts[r.Part] = true } if !parts["first"] || !parts["second"] || !parts["gospel"] { t.Errorf("%s-%s: got parts %v, want first+second+gospel", tc.slug, tc.cycle, parts) } } } func TestOFSeasonalFerials(t *testing.T) { // Seasonal weekday ferials re-sourced from catholic-resources.org: an Easter // weekday no longer contaminated, the Easter octave (was missing), and the // date-based late-Advent days (Dec 17-24, keyed by date not by Advent week). for _, tc := range []struct{ key, firstHas string }{ {"easter-3-mon-I", "Acts 6:8-15"}, // had 1 Cor 15 (contamination) {"easter-octave-mon-I", "Acts 2:14"}, // was absent {"advent-dec-17-I", "Genesis 49"}, {"advent-dec-24-I", "2 Samuel 7"}, {"christmas-dec-29-I", "1 John 2:3-11"}, // Christmas octave, by date {"christmas-jan-2-I", "1 John 2:22-28"}, // before Epiphany, by date {"christmas-after-epiphany-mon-I", "1 John 3:22"}, // after Epiphany, by weekday } { var first string for _, r := range TemporalReadings("new", tc.key) { if r.Part == "first" { first = r.Citation } } if !strings.Contains(first, tc.firstHas) { t.Errorf("%s: first = %q, want containing %q", tc.key, first, tc.firstHas) } } }