import assert from 'node:assert/strict'; import test from 'node:test'; import { applyFormulaEvent, buildFormulaMap, clearLegacyFormulaStorage, formatFormulaHint, formulaKey, isFormulaActual, } from './cellFormulaUtils.js'; const user = { id: 7, full_name: 'Иванов И.И.' }; test('formulaKey склеивает line_id и column', () => { assert.equal(formulaKey(5, 'q1'), '5|q1'); }); test('buildFormulaMap строит карту по ключу', () => { const map = buildFormulaMap([{ line_id: 1, column: 'a', expression: '1+2', value: 3, updated_by: user, updated_at: 'x' }]); assert.equal(map.size, 1); assert.equal(map.get('1|a').expression, '1+2'); assert.equal(buildFormulaMap(null).size, 0); }); test('applyFormulaEvent: строка записывает формулу', () => { const map = new Map(); const next = applyFormulaEvent(map, { line_id: 1, column: 'a', value: '150', formula: '100+50', formula_meta: { updated_by: user, updated_at: '2026-10-27T14:03:00' }, }); assert.notEqual(next, map); assert.equal(map.size, 0); assert.deepEqual(next.get('1|a'), { line_id: 1, column: 'a', expression: '100+50', value: 150, updated_by: user, updated_at: '2026-10-27T14:03:00', }); }); test('applyFormulaEvent: formula null удаляет, вход не мутируется', () => { const map = buildFormulaMap([{ line_id: 1, column: 'a', expression: '1', value: 1 }]); const next = applyFormulaEvent(map, { line_id: 1, column: 'a', value: 2, formula: null }); assert.equal(next.size, 0); assert.equal(map.size, 1); }); test('applyFormulaEvent: без поля formula удаляет', () => { const map = buildFormulaMap([{ line_id: 1, column: 'a', expression: '1', value: 1 }]); const next = applyFormulaEvent(map, { line_id: 1, column: 'a', value: 2 }); assert.equal(next.size, 0); }); test('applyFormulaEvent: фоновое событие без line_id/column возвращает ту же карту', () => { const map = buildFormulaMap([{ line_id: 1, column: 'a', expression: '1', value: 1 }]); assert.equal(applyFormulaEvent(map, { source_sheet: 'AHR_RENT' }), map); assert.equal(applyFormulaEvent(map, { line_id: 1, source_sheet: 'X' }), map); assert.equal(map.size, 1); }); test('isFormulaActual', () => { const f = { expression: '100+50', value: 150 }; assert.equal(isFormulaActual(f, 150), true); assert.equal(isFormulaActual(f, '150'), true); assert.equal(isFormulaActual({ ...f, value: '150' }, 150.0000000001), true); assert.equal(isFormulaActual({ ...f, value: 150 }, 151), false); assert.equal(isFormulaActual(null, 150), false); assert.equal(isFormulaActual({ ...f, value: 150 }, 'abc'), false); assert.equal(isFormulaActual({ ...f, value: 150 }, null), false); assert.equal(isFormulaActual({ ...f, value: 150 }, ''), false); }); test('formatFormulaHint', () => { assert.equal( formatFormulaHint({ expression: '100+50', updated_by: user, updated_at: '2026-10-27T14:03:00' }), '=100+50 · Иванов И.И. · 27.10.2026 14:03', ); assert.equal( formatFormulaHint({ expression: '1+1', updated_by: { id: 7 }, updated_at: '2026-10-27T14:03:00' }), '=1+1 · Пользователь #7 · 27.10.2026 14:03', ); assert.equal(formatFormulaHint({ expression: '1+1', updated_by: user }), '=1+1 · Иванов И.И.'); }); test('clearLegacyFormulaStorage', () => { const keys = ['formula_v2_a', 'formula_x', 'other']; const storage = { get length() { return keys.length; }, key: (i) => keys[i] ?? null, removeItem: (k) => { keys.splice(keys.indexOf(k), 1); }, }; assert.equal(clearLegacyFormulaStorage(storage), 2); assert.deepEqual(keys, ['other']); const broken = { get length() { throw new Error('denied'); }, }; assert.equal(clearLegacyFormulaStorage(broken), 0); assert.equal(clearLegacyFormulaStorage(null), 0); });