package calendar import "testing" func TestTemporalEFSeasons(t *testing.T) { cases := []struct { date string season Season }{ {"2025-01-01", Christmas}, // Circumcision {"2025-01-20", TimeAfterEpiphany}, // after II Sunday after Epiphany {"2025-02-16", Septuagesima}, // Septuagesima Sunday (easter-63) {"2025-03-05", Lent}, // Ash Wednesday {"2025-04-06", Passiontide}, // Passion Sunday (easter-14) {"2025-04-13", Passiontide}, // Palm Sunday {"2025-04-20", Easter_}, // Easter {"2025-06-08", Easter_}, // Pentecost (still Paschaltide) {"2025-06-15", TimeAfterPentecost}, // Trinity {"2025-06-22", TimeAfterPentecost}, // II Sunday after Pentecost {"2025-10-26", TimeAfterPentecost}, // Christ the King {"2025-11-30", Advent}, // I Sunday of Advent {"2025-12-25", Christmas}, // Nativity } for _, c := range cases { got := temporalEF(d(c.date)) if got.Season != c.season { t.Errorf("temporalEF(%s).Season = %s, want %s", c.date, got.Season, c.season) } } } func TestTemporalEFChristTheKing(t *testing.T) { // EF: last Sunday of October (2025-10-26), not the last before Advent. if got := temporalEF(d("2025-10-26")); got.Cel.Slug != "ef-christ-the-king" { t.Errorf("2025-10-26 slug = %q want ef-christ-the-king", got.Cel.Slug) } if got := efChristTheKing(2025).Format("2006-01-02"); got != "2025-10-26" { t.Errorf("efChristTheKing(2025) = %s want 2025-10-26", got) } } // TestTemporalEFSundayRanks: RG 11-12 / RG 91 entry 6 -- Sundays of Advent, // Lent and Passiontide, and Low Sunday, are I class; all others (including // Septuagesima's own three Sundays and the ordinary Sundays after Epiphany/ // Pentecost) stay II class. Before the fix, only Advent I was I class; every // other Advent/Lent Sunday was left at the generic-Sunday II-class default. func TestTemporalEFSundayRanks(t *testing.T) { cases := []struct { date string want Rank }{ {"2025-11-30", RankClass1}, // Advent I {"2025-12-07", RankClass1}, // Advent II {"2025-12-14", RankClass1}, // Advent III (Gaudete) {"2025-12-21", RankClass1}, // Advent IV {"2025-03-09", RankClass1}, // Lent I {"2025-03-16", RankClass1}, // Lent II {"2025-03-23", RankClass1}, // Lent III {"2025-03-30", RankClass1}, // Lent IV (Laetare) {"2025-04-06", RankClass1}, // Passion Sunday {"2025-04-13", RankClass1}, // Palm Sunday {"2025-04-27", RankClass1}, // Low Sunday {"2025-02-16", RankClass2}, // Septuagesima Sunday -- NOT I class {"2025-02-23", RankClass2}, // Sexagesima Sunday -- NOT I class {"2025-03-02", RankClass2}, // Quinquagesima Sunday -- NOT I class {"2025-06-22", RankClass2}, // II Sunday after Pentecost -- ordinary II class } for _, c := range cases { got := temporalEF(d(c.date)) if got.Cel.Rank != c.want { t.Errorf("temporalEF(%s).Cel.Rank = %s, want %s (%s)", c.date, got.Cel.Rank, c.want, got.Cel.Slug) } } } // TestTemporalEFRoseSundays: RG 131 -- rose is permitted on Gaudete (Advent // III) and Laetare (Lent IV), for that Sunday's own Office and Mass only. // Before the fix, efColour had no Rose case at all. func TestTemporalEFRoseSundays(t *testing.T) { if got := temporalEF(d("2025-12-14")).Cel.Colour; got != Rose { t.Errorf("Gaudete (2025-12-14) colour = %s, want rose", got) } if got := temporalEF(d("2025-03-30")).Cel.Colour; got != Rose { t.Errorf("Laetare (2025-03-30) colour = %s, want rose", got) } // The Advent/Lent Sundays either side stay violet -- rose is an indult for // that one Sunday, not a season colour. if got := temporalEF(d("2025-12-07")).Cel.Colour; got != Violet { t.Errorf("Advent II (2025-12-07) colour = %s, want violet", got) } if got := temporalEF(d("2025-03-23")).Cel.Colour; got != Violet { t.Errorf("Lent III (2025-03-23) colour = %s, want violet", got) } } // TestTemporalEFHolyThursdayColour: RG 128(b)/RG 122 -- Holy Thursday's Mass // of Chrism and Mass in Cena Domini are white, a whole-day exception to // Passiontide's violet. Good Friday and Holy Saturday, either side, stay // violet (their own black/no-colour exceptions are a separate, unmodelled // gap -- see RG 132, precedence_ef.go's own doc comments). func TestTemporalEFHolyThursdayColour(t *testing.T) { easter := d("2025-04-20") holyThu := easter.AddDate(0, 0, -3) goodFri := easter.AddDate(0, 0, -2) holySat := easter.AddDate(0, 0, -1) if got := temporalEF(holyThu).Cel.Colour; got != White { t.Errorf("Holy Thursday colour = %s, want white", got) } if got := temporalEF(goodFri).Cel.Colour; got != Violet { t.Errorf("Good Friday colour = %s, want violet (unchanged)", got) } if got := temporalEF(holySat).Cel.Colour; got != Violet { t.Errorf("Holy Saturday colour = %s, want violet (unchanged)", got) } } // TestTemporalEFEmberDayRanks: RG 91 entry 18 -- the Ember days of Lent (and, // unchanged, September and Advent) are II-class privileged ferias, not the // ordinary III-class Lenten ferias around them. Before the fix, efEmberSlug // had no Lent case at all, so Lent's Ember Wed/Fri/Sat fell through to the // ordinary III-class Lenten-feria rank. func TestTemporalEFEmberDayRanks(t *testing.T) { // Lent I Sunday 2025 = 2025-03-09; Ember Wed/Fri/Sat = +3/+5/+6. lentI := d("2025-03-09") for _, off := range []int{3, 5, 6} { day := lentI.AddDate(0, 0, off) got := temporalEF(day) if got.Cel.Rank != RankClass2 { t.Errorf("Lent Ember day %s rank = %s, want class-2 (%s)", day.Format("2006-01-02"), got.Cel.Rank, got.Cel.Slug) } } }