mirror of
https://github.com/acamarata/luxon-hijri.git
synced 2026-06-30 18:54:28 +00:00
Convert all LOCAL-noon Date anchors (new Date(y, m, d, 12)) to UTC-explicit
anchors (new Date(Date.UTC(y, m-1, d))) in test.mjs and test-cjs.cjs.
Add UAQ default-engine round-trip regression suite (5 cases).
Extend FCNA round-trips; update vitest header comment.
README: add "Day boundaries and time zones" section explaining the UTC-day
contract, the correct pattern for zone-aware Luxon DateTimes, and ISO-string
parsing behaviour. Quick Start examples updated to use Date.UTC.
CHANGELOG: document inherited UTC-day fix under [Unreleased].
Lock-step dependency: requires hijri-core fix (commit 3419378,
branch fix/utc-day-boundary). Both packages release together per ADR-013.
Verified: TZ={UTC,America/New_York,Pacific/Auckland} × {test.mjs,
test-cjs.cjs, test-crossval.mjs, vitest} — all pass (88+26+120+15 tests).
123 lines
4.9 KiB
JavaScript
123 lines
4.9 KiB
JavaScript
// test-cjs.cjs — CJS test suite for luxon-hijri
|
|
'use strict';
|
|
const { describe, it } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
const {
|
|
toHijri,
|
|
toGregorian,
|
|
isValidHijriDate,
|
|
formatHijriDate,
|
|
hDatesTable,
|
|
hwLong,
|
|
hwShort,
|
|
hwNumeric,
|
|
} = require('./dist/index.cjs');
|
|
|
|
const FCNA = { calendar: 'fcna' };
|
|
|
|
// ─── Exports ────────────────────────────────────────────────────────────────
|
|
|
|
describe('CJS exports', () => {
|
|
it('toHijri is a function', () => assert.strictEqual(typeof toHijri, 'function'));
|
|
it('toGregorian is a function', () => assert.strictEqual(typeof toGregorian, 'function'));
|
|
it('isValidHijriDate is a function', () =>
|
|
assert.strictEqual(typeof isValidHijriDate, 'function'));
|
|
it('formatHijriDate is a function', () => assert.strictEqual(typeof formatHijriDate, 'function'));
|
|
it('hDatesTable has 184 entries', () => assert.strictEqual(hDatesTable.length, 184));
|
|
it('hwLong has 7 entries', () => assert.strictEqual(hwLong.length, 7));
|
|
it('hwShort has 7 entries', () => assert.strictEqual(hwShort.length, 7));
|
|
it('hwNumeric has 7 entries', () => assert.strictEqual(hwNumeric.length, 7));
|
|
});
|
|
|
|
// ─── Core conversions ──────────────────────────────────────────────────────
|
|
|
|
describe('CJS core conversions', () => {
|
|
it('toGregorian(1444, 1, 1) = 2022-07-30', () => {
|
|
const d = toGregorian(1444, 1, 1);
|
|
assert(d instanceof Date);
|
|
assert.strictEqual(d.toISOString().slice(0, 10), '2022-07-30');
|
|
});
|
|
it('toGregorian(1444, 9, 1) = 2023-03-23', () => {
|
|
const d = toGregorian(1444, 9, 1);
|
|
assert.strictEqual(d.toISOString().slice(0, 10), '2023-03-23');
|
|
});
|
|
it('toHijri(2022-07-30) = 1 Muharram 1444', () => {
|
|
const h = toHijri(new Date(Date.UTC(2022, 6, 30)));
|
|
assert.deepEqual(h, { hy: 1444, hm: 1, hd: 1 });
|
|
});
|
|
it('toHijri(2023-03-23) = 1 Ramadan 1444', () => {
|
|
const h = toHijri(new Date(Date.UTC(2023, 2, 23)));
|
|
assert.deepEqual(h, { hy: 1444, hm: 9, hd: 1 });
|
|
});
|
|
});
|
|
|
|
// ─── Validation ─────────────────────────────────────────────────────────────
|
|
|
|
describe('CJS validation', () => {
|
|
it('isValidHijriDate(1444, 9, 1) = true', () =>
|
|
assert.strictEqual(isValidHijriDate(1444, 9, 1), true));
|
|
it('isValidHijriDate(1444, 0, 1) = false', () =>
|
|
assert.strictEqual(isValidHijriDate(1444, 0, 1), false));
|
|
it('isValidHijriDate(1317, 1, 1) = false (out of range)', () =>
|
|
assert.strictEqual(isValidHijriDate(1317, 1, 1), false));
|
|
});
|
|
|
|
// ─── Formatting ─────────────────────────────────────────────────────────────
|
|
|
|
const ramadan1 = { hy: 1444, hm: 9, hd: 1 };
|
|
|
|
describe('CJS formatting', () => {
|
|
it('iYYYY-iMM-iDD = 1444-09-01', () => {
|
|
assert.strictEqual(formatHijriDate(ramadan1, 'iYYYY-iMM-iDD'), '1444-09-01');
|
|
});
|
|
it('iMMMM = Ramadan', () => {
|
|
assert.strictEqual(formatHijriDate(ramadan1, 'iMMMM'), 'Ramadan');
|
|
});
|
|
it('iEEEE = Yawm al-Khamis (Thursday)', () => {
|
|
assert.strictEqual(formatHijriDate(ramadan1, 'iEEEE'), 'Yawm al-Khamis');
|
|
});
|
|
it('iooo = AH', () => {
|
|
assert.strictEqual(formatHijriDate(ramadan1, 'iooo'), 'AH');
|
|
});
|
|
});
|
|
|
|
describe('CJS formatHijriDate - invalid month', () => {
|
|
it('throws for month 0', () => {
|
|
assert.throws(
|
|
() => formatHijriDate({ hy: 1444, hm: 0, hd: 1 }, 'iMMMM'),
|
|
/Hijri month must be 1-12/,
|
|
);
|
|
});
|
|
it('throws for month 13', () => {
|
|
assert.throws(
|
|
() => formatHijriDate({ hy: 1444, hm: 13, hd: 1 }, 'iMMMM'),
|
|
/Hijri month must be 1-12/,
|
|
);
|
|
});
|
|
});
|
|
|
|
// ─── FCNA calendar ──────────────────────────────────────────────────────────
|
|
|
|
describe('CJS FCNA calendar', () => {
|
|
it('1 Ramadan 1446 = 2025-03-01', () => {
|
|
const d = toGregorian(1446, 9, 1, FCNA);
|
|
assert(d instanceof Date);
|
|
assert.strictEqual(d.toISOString().slice(0, 10), '2025-03-01');
|
|
});
|
|
it('2025-03-01 = 1 Ramadan 1446', () => {
|
|
const h = toHijri(new Date(Date.UTC(2025, 2, 1)), FCNA);
|
|
assert.deepEqual(h, { hy: 1446, hm: 9, hd: 1 });
|
|
});
|
|
it('isValidHijriDate(1446, 9, 1) = true', () => {
|
|
assert.strictEqual(isValidHijriDate(1446, 9, 1, FCNA), true);
|
|
});
|
|
it('isValidHijriDate(1, 1, 1) = true (year 1 AH)', () => {
|
|
assert.strictEqual(isValidHijriDate(1, 1, 1, FCNA), true);
|
|
});
|
|
it('round-trip 1446/9/1', () => {
|
|
const greg = toGregorian(1446, 9, 1, FCNA);
|
|
const hijri = toHijri(greg, FCNA);
|
|
assert.deepEqual(hijri, { hy: 1446, hm: 9, hd: 1 });
|
|
});
|
|
});
|