| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- 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), ['拌面', '杯面', '汤面'], '次数相同按中文排序');
- });
|