105 lines
3.7 KiB
TypeScript
105 lines
3.7 KiB
TypeScript
import { describe, it } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {
|
|
addJalaliMonths,
|
|
endOfJalaliMonth,
|
|
jalaliMonthName,
|
|
toGregorian,
|
|
toJalali,
|
|
} from '../src/common/jalali';
|
|
import {
|
|
addDays,
|
|
dayDiff,
|
|
eachDay,
|
|
isDayKey,
|
|
isTimeOfDay,
|
|
jalaliDayOfMonth,
|
|
persianWeekday,
|
|
tehranDateTime,
|
|
tehranDayKey,
|
|
tehranHour,
|
|
weekStartKey,
|
|
} from '../src/routines/routine-dates';
|
|
import {
|
|
formatTehranJalaliNumeric,
|
|
isDueInDays,
|
|
} from '../src/finance/cheque-reminder.util';
|
|
|
|
describe('تبدیل تاریخ شمسی', () => {
|
|
const pairs: Array<[[number, number, number], [number, number, number]]> = [
|
|
[[2026, 10, 8], [1405, 7, 16]],
|
|
[[2025, 3, 21], [1404, 1, 1]],
|
|
[[2024, 3, 20], [1403, 1, 1]],
|
|
[[2025, 3, 20], [1403, 12, 30]],
|
|
[[2000, 1, 1], [1378, 10, 11]],
|
|
];
|
|
for (const [[gy, gm, gd], [jy, jm, jd]] of pairs) {
|
|
it(`${gy}-${gm}-${gd} ⇄ ${jy}/${jm}/${jd}`, () => {
|
|
assert.deepEqual(toJalali(gy, gm, gd), { jy, jm, jd });
|
|
assert.deepEqual(toGregorian(jy, jm, jd), { gy, gm, gd });
|
|
});
|
|
}
|
|
|
|
it('رفتوبرگشت برای هر روز دو سال', () => {
|
|
const d = new Date(Date.UTC(2024, 0, 1));
|
|
for (let i = 0; i < 731; i += 1) {
|
|
const gy = d.getUTCFullYear();
|
|
const gm = d.getUTCMonth() + 1;
|
|
const gd = d.getUTCDate();
|
|
const j = toJalali(gy, gm, gd);
|
|
assert.deepEqual(toGregorian(j.jy, j.jm, j.jd), { gy, gm, gd });
|
|
d.setUTCDate(gd + 1);
|
|
}
|
|
});
|
|
|
|
it('ماهها', () => {
|
|
assert.deepEqual(addJalaliMonths(1405, 12, 1), { jy: 1406, jm: 1 });
|
|
assert.deepEqual(addJalaliMonths(1405, 1, -1), { jy: 1404, jm: 12 });
|
|
assert.equal(jalaliMonthName(7), 'مهر');
|
|
assert.equal(jalaliMonthName(13), '');
|
|
const end = endOfJalaliMonth(1405, 6);
|
|
const j = toJalali(end.getFullYear(), end.getMonth() + 1, end.getDate());
|
|
assert.deepEqual(j, { jy: 1405, jm: 6, jd: 31 });
|
|
});
|
|
});
|
|
|
|
describe('روزهای روتین (وقت تهران)', () => {
|
|
it('کلید روز با منطقهٔ زمانی تهران', () => {
|
|
// ۰۰:۳۰ بامداد تهران = ۲۱:۰۰ UTC روز قبل
|
|
assert.equal(tehranDayKey(new Date('2026-10-07T21:00:00Z')), '2026-10-08');
|
|
assert.equal(tehranDayKey(new Date('2026-10-07T20:29:00Z')), '2026-10-07');
|
|
assert.equal(tehranHour(new Date('2026-10-07T21:00:00Z')), 0);
|
|
});
|
|
|
|
it('اعتبارسنجی', () => {
|
|
assert.ok(isDayKey('2026-10-08'));
|
|
assert.ok(!isDayKey('1405/07/16'));
|
|
assert.ok(isTimeOfDay('23:59'));
|
|
assert.ok(!isTimeOfDay('24:00'));
|
|
});
|
|
|
|
it('محاسبات روز و هفته', () => {
|
|
assert.equal(addDays('2026-12-31', 1), '2027-01-01');
|
|
assert.equal(dayDiff('2026-10-01', '2026-10-08'), 7);
|
|
assert.equal(persianWeekday('2026-10-08'), 5); // پنجشنبه
|
|
assert.equal(persianWeekday('2026-10-03'), 0); // شنبه
|
|
assert.equal(weekStartKey('2026-10-08'), '2026-10-03');
|
|
assert.equal(jalaliDayOfMonth('2026-10-08'), 16);
|
|
assert.deepEqual(eachDay('2026-10-01', '2026-10-03'), ['2026-10-01', '2026-10-02', '2026-10-03']);
|
|
assert.equal(tehranDateTime('2026-10-08', '09:00').toISOString(), '2026-10-08T05:30:00.000Z');
|
|
});
|
|
});
|
|
|
|
describe('یادآور چک', () => {
|
|
it('تاریخ شمسی به وقت تهران', () => {
|
|
assert.equal(formatTehranJalaliNumeric(new Date('2026-10-08T10:00:00Z')), '۱۴۰۵/۰۷/۱۶');
|
|
assert.equal(formatTehranJalaliNumeric(new Date('2026-10-07T21:00:00Z')), '۱۴۰۵/۰۷/۱۶');
|
|
});
|
|
|
|
it('سررسید سه روز بعد', () => {
|
|
const now = new Date('2026-10-08T06:00:00Z');
|
|
assert.ok(isDueInDays(new Date('2026-10-11T12:00:00Z'), 3, now));
|
|
assert.ok(!isDueInDays(new Date('2026-10-12T12:00:00Z'), 3, now));
|
|
});
|
|
});
|