UNPKG

als-statistics

Version:

Modular JS statistics toolkit for Node.js and the browser: descriptive stats, correlations (Pearson/Spearman/Kendall), t-tests & ANOVA (Student/Welch), reliability (Cronbach’s alpha), regression (linear/logistic), clustering (DBSCAN/HDBSCAN), and table/co

114 lines (92 loc) 4.08 kB
// tests/cache.test.mjs import { describe, it, beforeEach } from 'node:test'; import assert from 'node:assert'; // хотели именно assert(..) import { Cache } from '../../lib/column/cache.js'; describe('Cache', () => { describe('ленивые вычисления и инвалидация кэша', () => { let c, calls, SUM; beforeEach(() => { c = new Cache([1, 2, 3]); calls = 0; SUM = Cache.key('sum'); }); it('кэширует результат $(key, compute)', () => { const sum = c.$(SUM, ({ values }) => { calls++; return values.reduce((a, b) => a + b, 0); }); assert.strictEqual(sum, 6); assert.strictEqual(calls, 1, 'compute должен быть вызван один раз'); // Повторный вызов с тем же ключом — берем из кэша const sum2 = c.$(SUM, () => { calls++; return -1; }); assert.strictEqual(sum2, 6); assert.strictEqual(calls, 1, 'повтор не должен вычислять заново'); }); it('очищает кэш при изменении values', () => { c.$(SUM, ({ values }) => { calls++; return values.reduce((a, b) => a + b, 0); }); assert.strictEqual(calls, 1); c.push(4); // меняем данные -> кэш должен очиститься const sum2 = c.$(SUM, ({ values }) => { calls++; return values.reduce((a, b) => a + b, 0); }); assert.strictEqual(sum2, 10); assert.strictEqual(calls, 2, 'после изменения данных должен быть пересчет'); }); }); describe('onchange события и meta.type', () => { it('эмитит set/undo/redo с прошлым values', () => { const c = new Cache([1, 2, 3]); const events = []; c.onchange((self, prev, meta) => { events.push({ prev: Array.from(prev), next: Array.from(self.values), type: meta.type }); }); c.push(4); // set assert.strictEqual(events.length, 1); assert.deepStrictEqual(events[0], { prev: [1, 2, 3], next: [1, 2, 3, 4], type: 'set' }); }); }); describe('set values(next) игнорирует ту же ссылку', () => { it('не триггерит событие и не добавляет состояние при той же ссылке', () => { const arr = [1, 2]; const c = new Cache(arr); let events = 0; c.onchange(() => { events++; }); // та же ссылка — ничего не меняется c.values = arr; assert.strictEqual(events, 0); assert.deepStrictEqual(c.values, [1, 2]); // новая ссылка — событие есть c.values = [...arr, 3]; assert.strictEqual(events, 1); assert.deepStrictEqual(c.values, [1, 2, 3]); }); }); }); describe('Cache API', () => { it('key/insertAt/setAt/removeAt/splice/push корректно меняют ссылку и валидируют', () => { const c = new Cache([1, 2, 3]); let fired = 0; c.onchange(() => fired++); c.insertAt(1, 9); assert.deepEqual(c.values, [1, 9, 2, 3]); c.setAt(0, 7); assert.deepEqual(c.values, [7, 9, 2, 3]); c.removeAt(2, 1); assert.deepEqual(c.values, [7, 9, 3]); c.push(2,5); assert.deepEqual(c.values, [7,9,3,2,5]); assert.ok(fired >= 4); // операции меняли ссылку }); it('валидатор отклоняет не числа', () => { const c = new Cache([1]); assert.throws(() => c.push('2'), /not valid/i); assert.throws(() => c.push(NaN), /not valid/i); }); });