// 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), ""); }); });