import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import test from 'node:test'; import { bindDateInputMask, dateInputValueToIso, formatDateInputValue, isoDateToInputValue } from '../admin/js/date-input.js'; test('маска расставляет точки при последовательном вводе восьми цифр', () => { assert.equal(formatDateInputValue('0'), '0'); assert.equal(formatDateInputValue('01'), '01'); assert.equal(formatDateInputValue('010'), '01.0'); assert.equal(formatDateInputValue('0109'), '01.09'); assert.equal(formatDateInputValue('01092'), '01.09.2'); assert.equal(formatDateInputValue('01092026'), '01.09.2026'); }); test('маска удаляет посторонние символы и ограничивает год четырьмя цифрами', () => { assert.equal(formatDateInputValue('01-09/2026'), '01.09.2026'); assert.equal(formatDateInputValue('010920261234'), '01.09.2026'); }); test('привязанная маска расставляет точки прямо во время ввода', () => { const input = new DateInputStub(); bindDateInputMask(input); typeText(input, '01092026'); assert.equal(input.value, '01.09.2026'); assert.equal(input.selectionStart, 10); typeText(input, '12'); assert.equal(input.value, '01.09.2026'); assert.equal(input.selectionStart, 10); }); test('дата преобразуется между форматом поля и ISO без потери значения', () => { assert.equal(dateInputValueToIso('01.09.2026'), '2026-09-01'); assert.equal(isoDateToInputValue('2026-09-01'), '01.09.2026'); }); test('неполный, шестизначный год и несуществующие даты отклоняются', () => { assert.throws(() => dateInputValueToIso('01.09.202'), /год — 4 цифры/); assert.throws(() => dateInputValueToIso('01.09.202612'), /год — 4 цифры/); assert.throws(() => dateInputValueToIso('31.02.2026'), /существующую дату/); assert.equal(dateInputValueToIso('29.02.2024'), '2024-02-29'); assert.throws(() => dateInputValueToIso('29.02.2025'), /существующую дату/); }); test('все поля дат календарного графика подключены к числовой маске', async () => { const template = await readFile(new URL('../admin/views/academic-calendar.html', import.meta.url), 'utf8'); assert.equal(template.match(/\bdata-date-input\b/g)?.length, 6); assert.equal(template.match(/\bmaxlength="10"/g)?.length, 6); assert.doesNotMatch(template, /type="date"/); }); class DateInputStub extends EventTarget { constructor() { super(); this.value = ''; this.selectionStart = 0; this.selectionEnd = 0; this.form = null; } setSelectionRange(start, end) { this.selectionStart = start; this.selectionEnd = end; } setCustomValidity() {} setAttribute() {} removeAttribute() {} focus() {} } function typeText(input, text) { for (const character of text) { const start = input.selectionStart; const end = input.selectionEnd; input.value = input.value.slice(0, start) + character + input.value.slice(end); input.selectionStart = start + 1; input.selectionEnd = start + 1; input.dispatchEvent(new Event('input')); } }