Ctrl K
ComunidadGuías…

src/lib/date-input.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { describe, expect, it } from "vitest";
import { parseDateInput, parseDateTimeInput } from "./date-input";

describe("parseDateInput", () => {
  it("reads the canonical form back unchanged", () => {
    expect(parseDateInput("2024-06-01")).toBe("2024-06-01");
  });

  it("accepts loose separators and single digits", () => {
    for (const text of [
      "2024-6-1",
      "2024/06/01",
      "2024.6.01",
      "2024 06 01",
      "20240601",
      "  2024-06-01  ",
    ]) {
      expect(parseDateInput(text)).toBe("2024-06-01");
    }
  });

  it("refuses a day-first or month-first date rather than guessing", () => {
    // "01/06/2024" is two different days depending on who typed it, and a
    // picker that picks one stores the wrong dive date silently.
    expect(parseDateInput("01/06/2024")).toBeNull();
    expect(parseDateInput("06/01/2024")).toBeNull();
    expect(parseDateInput("1 June 2024")).toBeNull();
  });

  it("refuses a day the month does not have", () => {
    expect(parseDateInput("2024-06-31")).toBeNull();
    expect(parseDateInput("2025-02-29")).toBeNull();
    expect(parseDateInput("2024-02-29")).toBe("2024-02-29");
    expect(parseDateInput("2000-02-29")).toBe("2000-02-29");
    expect(parseDateInput("1900-02-29")).toBeNull();
  });

  it("refuses an impossible month or day", () => {
    expect(parseDateInput("2024-13-01")).toBeNull();
    expect(parseDateInput("2024-00-01")).toBeNull();
    expect(parseDateInput("2024-06-00")).toBeNull();
  });

  it("refuses a half-typed date", () => {
    expect(parseDateInput("2")).toBeNull();
    expect(parseDateInput("2024-")).toBeNull();
    expect(parseDateInput("2024-06")).toBeNull();
    expect(parseDateInput("2024-06-011")).toBeNull();
  });

  it("tells a cleared field from an unreadable one", () => {
    expect(parseDateInput("")).toBe("");
    expect(parseDateInput("   ")).toBe("");
    expect(parseDateInput("soon")).toBeNull();
  });
});

describe("parseDateTimeInput", () => {
  it("reads a date and time in either ISO separator", () => {
    expect(parseDateTimeInput("2024-06-01 10:04:47")).toBe(
      "2024-06-01 10:04:47",
    );
    expect(parseDateTimeInput("2024-06-01T10:04:47")).toBe(
      "2024-06-01 10:04:47",
    );
  });

  it("fills in the parts the diver left off", () => {
    expect(parseDateTimeInput("2024-06-01 10:04")).toBe("2024-06-01 10:04:00");
    expect(parseDateTimeInput("2024-6-1 9:4")).toBe("2024-06-01 09:04:00");
    expect(parseDateTimeInput("2024-06-01")).toBe("2024-06-01 00:00:00");
  });

  it("drops a fraction the field has no room for", () => {
    expect(parseDateTimeInput("2024-06-01T10:04:47.910")).toBe(
      "2024-06-01 10:04:47",
    );
  });

  it("refuses a string carrying a UTC offset", () => {
    // The offset is the dive's own zone and lives in its own control; honouring
    // it here is impossible and dropping it would move the dive by that many
    // hours without saying so.
    expect(parseDateTimeInput("2024-06-01T10:04:47+02:00")).toBeNull();
    expect(parseDateTimeInput("2024-06-01T10:04:47Z")).toBeNull();
  });

  it("refuses an out-of-range time rather than clamping it", () => {
    expect(parseDateTimeInput("2024-06-01 25:00:00")).toBeNull();
    expect(parseDateTimeInput("2024-06-01 10:60:00")).toBeNull();
    expect(parseDateTimeInput("2024-06-01 10:04:60")).toBeNull();
  });

  it("applies the same calendar rules as the date-only field", () => {
    expect(parseDateTimeInput("2025-02-29 10:00")).toBeNull();
    expect(parseDateTimeInput("")).toBe("");
    expect(parseDateTimeInput("tomorrow")).toBeNull();
  });
});