import { test } from 'node:test'; import assert from 'node:assert/strict'; import { criteriaOf, queryOf, applyFilter, facetCounts, toggle, collectValues } from '../src/core/kfs/ledger.js'; /** 六维各取不同值,便于验证「同维 OR、跨维 AND」 */ const rows = [ { id: '1', title: '夜宵低卡拌面', oneLiner: '加班', priority: 'S', category: '拌面', status: 'candidate', layer: 'process', stage: 'S3 机会识别', ownerName: '张伟' }, { id: '2', title: '办公室速食拌面', oneLiner: '午休', priority: 'A', category: '拌面', status: 'approved', layer: 'process', stage: 'S4 验证评估', ownerName: '李娜' }, { id: '3', title: '银发低钠汤面', oneLiner: '控盐', priority: 'B', category: '汤面', status: 'candidate', layer: 'sediment', stage: 'S1 品类市场分析', ownerName: '张伟' }, { id: '4', title: '露营拌面', oneLiner: '户外', priority: 'S', category: '杯面', status: 'rejected', layer: 'record', stage: 'S5 场景与卖点设计', ownerName: '陈静' }, ]; const ids = (c) => applyFilter(rows, criteriaOf(c)).map((r) => r.id).sort(); test('单维多选:任一命中(OR)', () => { assert.deepEqual(ids({ priority: 'S,A' }), ['1', '2', '4']); assert.deepEqual(ids({ stage: 'S1,S5' }), ['3', '4']); }); test('跨维组合:取交集(AND)', () => { assert.deepEqual(ids({ priority: 'S', category: '拌面' }), ['1']); assert.deepEqual(ids({ priority: 'S,A', category: '拌面', member: '张伟' }), ['1']); assert.deepEqual(ids({ priority: 'S,A', category: '拌面', member: '张伟', stage: 'S4' }), [], '张伟在 S4 没成果'); }); test('六维全部叠加', () => { assert.deepEqual(ids({ status: 'candidate', priority: 'B', category: '汤面', stage: 'S1', member: '张伟', layer: 'sediment' }), ['3']); assert.deepEqual(ids({ status: 'candidate', priority: 'B', category: '汤面', stage: 'S1', member: '张伟', layer: 'process' }), []); }); test('搜索词跨字段', () => { assert.deepEqual(ids({ q: '户外' }), ['4']); assert.deepEqual(ids({ q: '张伟' }), ['1', '3']); }); test('URL 状态:条件 → 查询串 → 条件 往返不丢', () => { const c = criteriaOf({ priority: 'S,A', stage: 'S3', q: '面', sort: 'score' }); const q = queryOf(c); assert.equal(q.priority, 'S,A'); assert.deepEqual(criteriaOf(q), c); assert.deepEqual(queryOf(criteriaOf({})), {}, '空条件不写进 URL'); }); test('分面计数受其他维度约束、不受本维约束', () => { const c = criteriaOf({ priority: 'S,A', category: '拌面' }); const m = facetCounts(rows, c, 'priority'); // 在「拌面」范围内,S 有 1 条、A 有 1 条;B 的拌面没有 assert.equal(m.get('S'), 1); assert.equal(m.get('A'), 1); assert.equal(m.get('B'), undefined); }); test('toggle 与取值收集', () => { const c = toggle({ priority: [] }, 'priority', 'S'); assert.deepEqual(c.priority, ['S']); assert.deepEqual(toggle(c, 'priority', 'S').priority, []); assert.deepEqual(collectValues(rows, 'category').map((x) => x.value), ['拌面', '杯面', '汤面'], '次数相同按中文排序'); });