Files
Clipboard/test/clip-list-prepend.test.js
2026-09-12 13:59:12 +08:00

92 lines
3.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
const assert = require('node:assert');
const fs = require('node:fs');
const path = require('node:path');
const rendererSrc = fs.readFileSync(
path.join(__dirname, '..', 'renderer', 'renderer.js'), 'utf8'
);
let passed = 0;
function check(name, fn) {
try { fn(); console.log(' ok -', name); passed++; }
catch (e) { console.error(' FAIL -', name, e.message); process.exitCode = 1; }
}
// ---------- buildCard 抽函数 ----------
check('renderer.js 定义了 buildCard 函数', () => {
assert.ok(
/function\s+buildCard\s*\(/.test(rendererSrc),
'找不到 buildCard(c, i) 定义'
);
});
check('render() 调用 buildCard 而不是手写卡片构建', () => {
const renderFn = rendererSrc.match(/function\s+render\s*\(\s*\)\s*\{[\s\S]*?\n\}/);
assert.ok(renderFn, '找不到 render()');
assert.ok(
/buildCard\s*\(/.test(renderFn[0]),
'render() 没调用 buildCard'
);
// 抽函数后render() 内不应该有 cloneNode(true) 这种属于 buildCard 的细节
assert.ok(
!/cloneNode\s*\(\s*true\s*\)/.test(renderFn[0]),
'render() 还在做 cloneNodebuildCard 抽得不够彻底'
);
});
// ---------- onAdded 增量插入路径 ----------
check('onAdded 在 history Tab + 无搜索时走 prepend 而非 reload', () => {
const onAdded = rendererSrc.match(/onAdded\s*\(\s*\(\s*\w+\s*\)\s*=>\s*\{[\s\S]*?\}\s*\)/);
assert.ok(onAdded, '找不到 onAdded 回调');
// 存在非 reload 的快路径增量插入。reload 只应出现在跳过分支(收藏 Tab/
// 搜索中)和 catch 兜底里 —— 最多 2 次。快路径由下一条断言insertBefore/
// unshift单独保证。原计划写死 <=1 与 spec 强制的 catch fallback 冲突,
// 这里修正为 <=2 以匹配 spec见 task-7 报告的 controller addendum
const reloadCount = (onAdded[0].match(/\breload\s*\(/g) || []).length;
assert.ok(reloadCount <= 2, `onAdded 内 reload 次数 ${reloadCount},应是跳过分支 + catch 兜底 ≤ 2 次`);
// 应该有 prepend 路径或 append 增量逻辑
assert.ok(
/insertBefore|prepend|unshift/.test(onAdded[0]),
'onAdded 没走增量插入路径(看不到 insertBefore / unshift'
);
});
check('onAdded 跳过条件:搜索框非空或非 history Tab', () => {
const onAdded = rendererSrc.match(/onAdded\s*\(\s*\(\s*\w+\s*\)\s*=>\s*\{[\s\S]*?\}\s*\)/);
assert.ok(onAdded, '找不到 onAdded 回调');
assert.ok(
/currentTab\s*!==\s*'history'/.test(onAdded[0]),
'onAdded 没判断非 history Tab 时跳过 prepend'
);
assert.ok(
/\$search\.value\.trim\s*\(\s*\)\s*!==\s*''/.test(onAdded[0]),
'onAdded 没判断搜索框非空时跳过 prepend'
);
});
// ---------- 增量插入的两个回归坑 ----------
check('prependClip 熄灭空状态(#empty', () => {
// 空列表时 render() 亮起 #empty第一条增量不走 render()
// 不主动隐藏就会出现"卡片 + 暂无内容"同屏。
const prepend = rendererSrc.match(/function\s+prependClip\s*\([\s\S]*?\n\}/);
assert.ok(prepend, '找不到 prependClip()');
assert.ok(
/\$empty\.classList\.add\(\s*'hidden'\s*\)/.test(prepend[0]),
'prependClip 没有隐藏 #empty —— 空列表收到第一条增量时空状态不熄灭'
);
});
check('buildCard 的点击选中按运行时下标,不捕获构建时 i', () => {
// prependClip 会把已有卡片整体后移,捕获构建时下标的闭包会选中错误的项。
assert.ok(
/node\.onclick\s*=\s*\(\)\s*=>\s*select\(\s*\$cards\.indexOf\(node\)\s*\)/.test(rendererSrc),
'node.onclick 应在点击时从 $cards 现取下标select($cards.indexOf(node))),而不是捕获构建时的 i'
);
});
console.log(`\n${passed} checks passed`);