mirror of
https://github.com/prdlk/leetcode.git
synced 2026-09-17 07:26:27 +00:00
test(tests): add comprehensive rest day and ladder tests
This commit is contained in:
@@ -1,11 +1,30 @@
|
|||||||
/**
|
/**
|
||||||
* DST-guard and date-math checks with fixed instants — the acceptance proof
|
* Acceptance proof for the two rules that cannot be eyeballed in production:
|
||||||
* that the double crons fire exactly once at 8 AM ET (digest) and midnight
|
* the double crons fire exactly once at 8 AM ET (digest) and midnight Saturday
|
||||||
* Saturday ET (review issue) on BOTH UTC offsets.
|
* ET (review issue) on BOTH UTC offsets, and NOTHING is ever scheduled on the
|
||||||
|
* Sunday rest day — which is the whole reason the ladder's windows are 3 and 7.
|
||||||
*/
|
*/
|
||||||
import { describe, expect, test } from "bun:test";
|
import { describe, expect, test } from "bun:test";
|
||||||
|
|
||||||
import { addDays, campaignDay, campaignWeek, etDate, etHour, isoWeek, rng, sample, weekdayOf } from "./srs.ts";
|
import {
|
||||||
|
INTERVAL,
|
||||||
|
STAGES,
|
||||||
|
WINDOWS,
|
||||||
|
addDays,
|
||||||
|
campaignDay,
|
||||||
|
campaignWeek,
|
||||||
|
etDate,
|
||||||
|
etHour,
|
||||||
|
isRestDay,
|
||||||
|
isoWeek,
|
||||||
|
rng,
|
||||||
|
sample,
|
||||||
|
weekdayOf,
|
||||||
|
workingDay,
|
||||||
|
} from "./srs.ts";
|
||||||
|
|
||||||
|
/** Every ET date of the campaign, plus the deferred-Hard tail. */
|
||||||
|
const CALENDAR = Array.from({ length: 70 }, (_, i) => addDays("2026-08-17", i));
|
||||||
|
|
||||||
describe("DST-proof cron guard", () => {
|
describe("DST-proof cron guard", () => {
|
||||||
test("digest fires only at ET hour 8 — EDT (UTC-4)", () => {
|
test("digest fires only at ET hour 8 — EDT (UTC-4)", () => {
|
||||||
@@ -50,6 +69,69 @@ describe("date math (noon-UTC anchored)", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("the rest day", () => {
|
||||||
|
test("Sunday is the only rest day", () => {
|
||||||
|
expect(isRestDay("2026-08-30")).toBe(true); // Sunday
|
||||||
|
expect(isRestDay("2026-08-29")).toBe(false); // Saturday: gate day, still work
|
||||||
|
expect(isRestDay("2026-08-31")).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("workingDay never returns a Sunday, from any day and any offset", () => {
|
||||||
|
for (const date of CALENDAR) {
|
||||||
|
for (let offset = 0; offset < 10; offset++) {
|
||||||
|
expect(isRestDay(workingDay(date, offset))).toBe(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("workingDay(date) leaves a working day alone and slides Sunday to Monday", () => {
|
||||||
|
expect(workingDay("2026-09-04")).toBe("2026-09-04"); // Friday
|
||||||
|
expect(workingDay("2026-09-05")).toBe("2026-09-05"); // Saturday
|
||||||
|
expect(workingDay("2026-09-06")).toBe("2026-09-07"); // Sunday → Monday
|
||||||
|
});
|
||||||
|
|
||||||
|
test("offsets count working days, so a spill skips the rest day", () => {
|
||||||
|
// Levelling from Saturday: tomorrow is Sunday, so the spill starts Monday.
|
||||||
|
expect(workingDay("2026-09-05", 1)).toBe("2026-09-07");
|
||||||
|
expect(workingDay("2026-09-05", 2)).toBe("2026-09-08");
|
||||||
|
// Two deferred Hards per working day from a Monday.
|
||||||
|
expect(workingDay("2026-09-28", 5)).toBe("2026-10-03"); // Saturday
|
||||||
|
expect(workingDay("2026-09-28", 6)).toBe("2026-10-05"); // Sunday skipped
|
||||||
|
});
|
||||||
|
|
||||||
|
test("every ladder interval lands on a working day, from every learning day", () => {
|
||||||
|
for (const date of CALENDAR) {
|
||||||
|
if (isRestDay(date)) continue;
|
||||||
|
for (const days of WINDOWS) {
|
||||||
|
const review = workingDay(addDays(date, days));
|
||||||
|
expect(isRestDay(review)).toBe(false);
|
||||||
|
// Never earlier than the interval: a review may slip, never shorten.
|
||||||
|
expect(review >= addDays(date, days)).toBe(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("only Thursday's +3 needs the slide", () => {
|
||||||
|
const slid = CALENDAR.filter(
|
||||||
|
(date) => !isRestDay(date) && workingDay(addDays(date, 3)) !== addDays(date, 3),
|
||||||
|
);
|
||||||
|
expect(new Set(slid.map(weekdayOf))).toEqual(new Set([4])); // Thursday only
|
||||||
|
for (const date of CALENDAR) {
|
||||||
|
if (isRestDay(date)) continue;
|
||||||
|
expect(workingDay(addDays(date, 7))).toBe(addDays(date, 7)); // +7 keeps the weekday
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("the ladder", () => {
|
||||||
|
test("two rungs, named after the windows", () => {
|
||||||
|
expect(STAGES).toEqual(["new", "+3", "+7", "retired"]);
|
||||||
|
expect(WINDOWS.map((w) => INTERVAL[`+${w}`])).toEqual([...WINDOWS]);
|
||||||
|
// Every non-terminal stage has an interval, and only those.
|
||||||
|
expect(Object.keys(INTERVAL).sort()).toEqual(STAGES.slice(1, -1).sort());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("deterministic sampling", () => {
|
describe("deterministic sampling", () => {
|
||||||
test("same seed, same picks", () => {
|
test("same seed, same picks", () => {
|
||||||
const pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
const pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||||
|
|||||||
Reference in New Issue
Block a user