Files

121 lines
4.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { parseRepeat, parseWhen } from "../src/lib/when";
// A Wednesday, so weekday arithmetic has somewhere to go in both directions.
const WED = new Date(2026, 7, 12);
const on = (text: string): string | null => parseWhen(text, WED);
describe("parseWhen", () => {
it("takes an ISO date as written", () => {
expect(on("2026-08-20")).toBe("2026-08-20");
expect(on("2026-8-3")).toBe("2026-08-03");
});
it("refuses a date that does not exist", () => {
expect(on("2026-02-30")).toBeNull();
expect(on("2026-13-01")).toBeNull();
});
it("knows the words for the days around now", () => {
expect(on("today")).toBe("2026-08-12");
expect(on("tod")).toBe("2026-08-12");
expect(on("tomorrow")).toBe("2026-08-13");
expect(on("tmr")).toBe("2026-08-13");
expect(on("yesterday")).toBe("2026-08-11");
});
it("counts forward in days, weeks and months", () => {
expect(on("in 3 days")).toBe("2026-08-15");
expect(on("3 days")).toBe("2026-08-15");
expect(on("3d")).toBe("2026-08-15");
expect(on("in a week")).toBe("2026-08-19");
expect(on("2w")).toBe("2026-08-26");
expect(on("in 1 month")).toBe("2026-09-12");
expect(on("next week")).toBe("2026-08-19");
expect(on("next year")).toBe("2027-08-12");
});
it("reads a weekday as the next one, never today", () => {
expect(on("friday")).toBe("2026-08-14");
expect(on("fri")).toBe("2026-08-14");
expect(on("monday")).toBe("2026-08-17");
expect(on("wednesday")).toBe("2026-08-19");
expect(on("next friday")).toBe("2026-08-14");
});
it("reads a day and a month either way round", () => {
expect(on("20 aug")).toBe("2026-08-20");
expect(on("aug 20")).toBe("2026-08-20");
expect(on("20 august")).toBe("2026-08-20");
expect(on("20 aug 2027")).toBe("2027-08-20");
});
it("rolls a date that has already gone into next year", () => {
expect(on("1 aug")).toBe("2027-08-01");
expect(on("1 aug 2026")).toBe("2026-08-01");
});
it("reads a numeric date day first", () => {
expect(on("20.08")).toBe("2026-08-20");
expect(on("20/8")).toBe("2026-08-20");
expect(on("20.08.27")).toBe("2027-08-20");
});
it("reads a bare number as a day of the month", () => {
expect(on("20")).toBe("2026-08-20");
expect(on("12")).toBe("2026-08-12");
expect(on("3")).toBe("2026-09-03");
});
it("says nothing when the words mean nothing", () => {
expect(on("")).toBeNull();
expect(on(" ")).toBeNull();
expect(on("buy milk")).toBeNull();
expect(on("someday")).toBeNull();
expect(on("99")).toBeNull();
});
it("ignores case and extra spaces", () => {
expect(on(" In 3 Days ")).toBe("2026-08-15");
expect(on("TOMORROW")).toBe("2026-08-13");
});
});
describe("parseRepeat", () => {
it("normalises the everyday phrasings", () => {
expect(parseRepeat("daily")).toBe("every day");
expect(parseRepeat("weekly")).toBe("every week");
expect(parseRepeat("monthly")).toBe("every month");
expect(parseRepeat("yearly")).toBe("every year");
expect(parseRepeat("fortnightly")).toBe("every 2 weeks");
});
it("takes a bare unit or a count", () => {
expect(parseRepeat("week")).toBe("every week");
expect(parseRepeat("2 weeks")).toBe("every 2 weeks");
expect(parseRepeat("every 3 days")).toBe("every 3 days");
expect(parseRepeat("every 1 day")).toBe("every 1 day");
});
it("takes a weekday with or without the every", () => {
expect(parseRepeat("monday")).toBe("every monday");
expect(parseRepeat("mondays")).toBe("every monday");
expect(parseRepeat("every tue")).toBe("every tuesday");
});
it("clears on the words for nothing", () => {
expect(parseRepeat("none")).toBe("");
expect(parseRepeat("never")).toBe("");
});
it("passes an unknown every-rule through for Tasks to read", () => {
expect(parseRepeat("every 2nd wednesday")).toBe("every 2nd wednesday");
expect(parseRepeat("every month on the last")).toBe("every month on the last");
});
it("says nothing when it is not a rule at all", () => {
expect(parseRepeat("")).toBeNull();
expect(parseRepeat("buy milk")).toBeNull();
});
});