From 723d09ff852aa3a49a07e7d728d68bb12a86fda1 Mon Sep 17 00:00:00 2001 From: alkor2000 <131229172+alkor2000@users.noreply.github.com> Date: Mon, 1 Jun 2026 00:59:43 +0800 Subject: [PATCH] fix(cli): extend holiday tagline dates through 2030 Extend the CLI holiday tagline tables for Lunar New Year, Eid al-Fitr, Easter, Diwali, and Hanukkah through 2030 so those taglines do not silently disappear after 2027. Maintainer fixup: corrected the 2030 Diwali row to October 25 and added explicit regression coverage for that date. Verification: - node scripts/run-vitest.mjs src/cli/tagline.test.ts - Direct pickTagline() probe confirmed 2030-10-25 activates Diwali and 2030-10-26 does not. Co-authored-by: alkor2000 <200923177@qq.com> --- src/cli/tagline.test.ts | 49 +++++++++++++++++++++++++++++++++++++++++ src/cli/tagline.ts | 15 +++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/cli/tagline.test.ts b/src/cli/tagline.test.ts index c60a29d9e3d..c8463a185ba 100644 --- a/src/cli/tagline.test.ts +++ b/src/cli/tagline.test.ts @@ -31,3 +31,52 @@ describe("pickTagline", () => { ).toBe("Your terminal just grew claws\u2014type something and let the bot pinch the busywork."); }); }); + +describe("future holiday tagline windows (2028-2030)", () => { + // Regression coverage for the 2028-2030 floating-holiday rows. Before those + // rows existed, the holiday rule returned false for these dates and the + // tagline was silently filtered out of the active pool. activeTaglines is no + // longer exported, so we sample the public pickTagline() across every pool + // index (by sweeping the injected random()) to recover the full active pool + // for a given date, then assert the matching holiday tagline is present. + // UTC dates are used because the holiday rules compare in UTC. + const activePoolOn = (year: number, monthIndex: number, day: number): string[] => { + const now = () => new Date(Date.UTC(year, monthIndex, day, 12, 0, 0)); + const seen = new Set(); + for (let i = 0; i < 200; i++) { + const r = i / 200; + seen.add(pickTagline({ mode: "random", now, random: () => r })); + } + return [...seen]; + }; + const poolHas = (pool: string[], term: string) => + pool.some((t) => t.toLowerCase().includes(term)); + + it("activates the Lunar New Year tagline on 2028-01-26", () => { + expect(poolHas(activePoolOn(2028, 0, 26), "lunar new year")).toBe(true); + }); + + it("activates the Diwali tagline on 2029-11-05", () => { + expect(poolHas(activePoolOn(2029, 10, 5), "diwali")).toBe(true); + }); + + it("activates the Diwali tagline on 2030-10-25", () => { + expect(poolHas(activePoolOn(2030, 9, 25), "diwali")).toBe(true); + }); + + it("activates the Easter tagline on 2030-04-21", () => { + expect(poolHas(activePoolOn(2030, 3, 21), "easter")).toBe(true); + }); + + it("activates the Hanukkah tagline across its full 2028 window (Dec 13 and Dec 20)", () => { + expect(poolHas(activePoolOn(2028, 11, 13), "hanukkah")).toBe(true); + expect(poolHas(activePoolOn(2028, 11, 20), "hanukkah")).toBe(true); + }); + + it("does not activate floating holiday taglines on a plain date (2028-07-15)", () => { + const pool = activePoolOn(2028, 6, 15); + for (const term of ["lunar new year", "diwali", "easter", "hanukkah", "eid al-fitr"]) { + expect(poolHas(pool, term)).toBe(false); + } + }); +}); diff --git a/src/cli/tagline.ts b/src/cli/tagline.ts index 053fd5b29e6..bf320b3993f 100644 --- a/src/cli/tagline.ts +++ b/src/cli/tagline.ts @@ -187,6 +187,9 @@ const HOLIDAY_RULES = new Map([ [2025, 0, 29], [2026, 1, 17], [2027, 1, 6], + [2028, 0, 26], + [2029, 1, 13], + [2030, 1, 3], ], 1, ), @@ -199,6 +202,9 @@ const HOLIDAY_RULES = new Map([ [2025, 2, 31], [2026, 2, 20], [2027, 2, 10], + [2028, 1, 27], + [2029, 1, 15], + [2030, 1, 5], ], 1, ), @@ -210,6 +216,9 @@ const HOLIDAY_RULES = new Map([ [2025, 9, 20], [2026, 10, 8], [2027, 9, 28], + [2028, 9, 17], + [2029, 10, 5], + [2030, 9, 25], ], 1, ), @@ -221,6 +230,9 @@ const HOLIDAY_RULES = new Map([ [2025, 3, 20], [2026, 3, 5], [2027, 2, 28], + [2028, 3, 16], + [2029, 3, 1], + [2030, 3, 21], ], 1, ), @@ -231,6 +243,9 @@ const HOLIDAY_RULES = new Map([ { year: 2025, month: 11, day: 15, duration: 8 }, { year: 2026, month: 11, day: 5, duration: 8 }, { year: 2027, month: 11, day: 25, duration: 8 }, + { year: 2028, month: 11, day: 13, duration: 8 }, + { year: 2029, month: 11, day: 2, duration: 8 }, + { year: 2030, month: 11, day: 21, duration: 8 }, ]), ], [HOLIDAY_TAGLINES.halloween, onMonthDay(9, 31)],