mirror of
https://github.com/KingHWJ/WeReadBoard.git
synced 2026-11-03 18:24:58 +08:00
72 lines
3.2 KiB
JavaScript
72 lines
3.2 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const vm = require('node:vm');
|
|
|
|
function app() {
|
|
const nodes = new Map();
|
|
const node = selector => {
|
|
if (!nodes.has(selector)) nodes.set(selector, {
|
|
value: '', textContent: '', innerHTML: '', disabled: false,
|
|
classList: { add() {}, remove() {}, toggle() {} },
|
|
setAttribute() {}, addEventListener() {}, setCustomValidity() {}, reportValidity() {},
|
|
showModal() { this.open = true; }, close() { this.open = false; },
|
|
});
|
|
return nodes.get(selector);
|
|
};
|
|
const pending = () => new Promise(() => {});
|
|
const context = vm.createContext({
|
|
document: { querySelector: node, querySelectorAll: () => [], addEventListener() {}, documentElement: { dataset: {} } },
|
|
localStorage: { getItem: () => null },
|
|
WeApi: { status: pending, shelf: pending, dashboard: pending, goals: pending },
|
|
crypto: { randomUUID: () => 'test-goal' },
|
|
setTimeout() {}, clearTimeout() {}, console,
|
|
});
|
|
vm.runInContext(fs.readFileSync('static/js/app.js', 'utf8'), context);
|
|
return { context, node, run: code => vm.runInContext(code, context) };
|
|
}
|
|
|
|
test('目标书籍不在当前书架时仍保留总数,并可打开和编辑', () => {
|
|
const { run, node } = app();
|
|
run(`loadState.goals = 'ready';
|
|
books = [{id:'known',title:'已读书',status:'done'}];
|
|
goals = [{id:'g',name:'阅读',start:'2026-09-01',end:'2026-09-30',ids:['known','missing'],sources:[]}];
|
|
shelfData = {};`);
|
|
assert.equal(run('goalMetrics(goals[0]).total'), 2);
|
|
assert.equal(run('goalMetrics(goals[0]).percent'), 50);
|
|
run("openGoalDetail('g'); openGoalEditor('g');");
|
|
assert.match(node('#goal-picker').innerHTML, /状态待同步/);
|
|
assert.equal(run("selectedGoalBooks().includes('missing')"), true);
|
|
});
|
|
|
|
test('数据库保存失败时保留原目标和编辑草稿,允许重试', async () => {
|
|
const { context, run, node } = app();
|
|
run(`loadState.goals = 'ready';
|
|
shelfData = {}; books = [{id:'known',title:'一本书',status:'done'}];
|
|
goals = [{id:'g',name:'原名称',start:'2026-09-01',end:'2026-09-30',ids:['known'],sources:[]}];
|
|
openGoalEditor('g');`);
|
|
node('#goal-name').value = '新名称';
|
|
context.WeApi.saveGoal = async () => { throw new Error('数据库暂不可用'); };
|
|
await run('saveGoal({preventDefault(){}})');
|
|
assert.equal(run('goals[0].name'), '原名称');
|
|
assert.equal(node('#goal-editor').open, true);
|
|
assert.equal(node('#goal-name').value, '新名称');
|
|
assert.match(node('#goal-error').textContent, /数据库暂不可用/);
|
|
context.WeApi.saveGoal = async goal => ({ goal });
|
|
await run('saveGoal({preventDefault(){}})');
|
|
assert.equal(run('goals[0].name'), '新名称');
|
|
assert.equal(node('#goal-editor').open, false);
|
|
});
|
|
|
|
test('目标列表未完成加载时不打开编辑器', () => {
|
|
const { run, node } = app();
|
|
run(`page = 'overview';
|
|
loadState.goals = 'loading';
|
|
shelfData = {};
|
|
books = [{id:'known',title:'一本书',status:'done'}];
|
|
openGoalEditor(null, ['known'], []);`);
|
|
assert.notEqual(node('#goal-editor').open, true);
|
|
assert.equal(run('page'), 'goals');
|
|
assert.match(node('#page-content').innerHTML, /正在读取阅读目标/);
|
|
});
|