Ctrl K
ComunidadGuías…

tests/dates.test.ts

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

Archivo original ↗Preguntar a KiBot
// Month names follow the chrome language. An English visitor on an Arabic
// instance used to read "14 أغسطس 2026" because siteDate() passed blogLocale
// straight to Intl. Digits stay on localeDigits (Western unless asked).

import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { siteDate } from "../client/dates.ts";
import { setLang } from "../client/i18n.ts";
import { dateNamesLocale, formatCalendarDate, formatCalendarRange } from "../shared/dates.ts";

const ISO = "2026-01-09T00:00:00.000Z";
const LONG_UTC: Intl.DateTimeFormatOptions = { dateStyle: "long", timeZone: "UTC" };

describe("dateNamesLocale", () => {
  it("an English reader on an Arabic instance gets an English tag", () => {
    assert.equal(dateNamesLocale("ar", "en"), "en");
    assert.equal(dateNamesLocale("ar-EG", "en"), "en");
    assert.equal(dateNamesLocale("ar-SA-u-nu-latn", "en"), "en");
  });

  it("keeps a regional English tag for an English reader", () => {
    assert.equal(dateNamesLocale("en-GB", "en"), "en-GB");
    assert.equal(dateNamesLocale("en", "en"), "en");
  });

  it("an Arabic reader keeps an Arabic regional tag", () => {
    assert.equal(dateNamesLocale("ar-EG", "ar"), "ar-EG");
    assert.equal(dateNamesLocale("ar", "ar"), "ar");
  });

  it("an Arabic reader on an English instance still gets Arabic names", () => {
    assert.equal(dateNamesLocale("en", "ar"), "ar");
    assert.equal(dateNamesLocale("en-GB", "ar"), "ar");
  });
});

describe("a `both` date's order and separator", () => {
  const d = new Date(ISO);
  it("follows the language by default, with a bar between the halves", () => {
    const ar = formatCalendarDate(d, "ar", "both", "ar", LONG_UTC);
    const en = formatCalendarDate(d, "en", "both", "en", LONG_UTC);
    assert.match(ar, /هـ.*\|.*يناير.*م/, "Arabic leads with the Hijri date, a bar, then the Gregorian one with its era mark");
    assert.match(en, /January.*\|.*AH/, "English leads with the Gregorian date");
  });
  it("takes an explicit order and separator", () => {
    const hijriFirst = formatCalendarDate(d, "en", "both", "en", LONG_UTC, { order: "hijri-first", separator: "dot" });
    assert.match(hijriFirst, /AH.*·.*January/);
    const parens = formatCalendarDate(d, "en", "both", "en", LONG_UTC, { order: "gregorian-first", separator: "parens" });
    assert.match(parens, /January.*\(.*AH.*\)/);
  });
});

describe("English chrome does not print Arabic month names", () => {
  it("formatCalendarDate in en says January, not يناير", () => {
    const en = formatCalendarDate(new Date(ISO), "en", "gregorian", "en", LONG_UTC);
    const ar = formatCalendarDate(new Date(ISO), "ar", "gregorian", "ar", LONG_UTC);
    assert.match(en, /January/);
    assert.doesNotMatch(en, /يناير/);
    assert.match(ar, /يناير/);
    assert.doesNotMatch(ar, /January/);
  });

  it("siteDate remaps an Arabic blogLocale when chrome is English", () => {
    setLang("en");
    const text = siteDate(ISO, "ar", LONG_UTC);
    assert.match(text, /January/);
    assert.doesNotMatch(text, /يناير/);
  });

  it("siteDate keeps Arabic month names when chrome is Arabic", () => {
    setLang("ar");
    const text = siteDate(ISO, "ar", LONG_UTC);
    assert.match(text, /يناير/);
    assert.doesNotMatch(text, /January/);
  });

  it("digits stay Western on an Arabic instance", () => {
    setLang("ar");
    const text = siteDate(ISO, "ar", LONG_UTC);
    assert.match(text, /2026/);
    assert.doesNotMatch(text, /[٠-٩]/);
  });
});

// A span of days (formatCalendarRange): the week, month or year a periodic
// note names, in the instance's calendar.
describe("formatCalendarRange", () => {
  const from = new Date(2026, 8, 14, 12);
  const to = new Date(2026, 8, 20, 12);
  const span: Intl.DateTimeFormatOptions = { day: "numeric", month: "long", year: "numeric" };
  it("prints a Gregorian span with the shared parts once", () => {
    const en = formatCalendarRange(from, to, "en-GB", "gregorian", "en", span);
    assert.match(en, /14.*20 September 2026/);
    assert.doesNotMatch(en, /September.*September/);
    assert.match(formatCalendarRange(from, to, "en", "gregorian", "en", span), /September 14.*20, 2026/);
  });
  it("prints a Hijri span, and both halves on a both instance", () => {
    const hijri = formatCalendarRange(from, to, "en", "hijri", "en", span);
    assert.match(hijri, /AH/);
    const both = formatCalendarRange(from, to, "ar", "both", "ar", span);
    assert.match(both, /هـ.*\|.*سبتمبر.*م/);
  });
  it("returns nothing for an invalid end", () => {
    assert.equal(formatCalendarRange(from, new Date(NaN), "en", "gregorian", "en", span), "");
  });
});