Files
Store.Management/DesignDemo2/check.cjs
T
2026-11-10 16:33:51 +08:00

59 lines
3.4 KiB
JavaScript

const fs = require('node:fs');
const vm = require('node:vm');
const assert = require('node:assert/strict');
const html = fs.readFileSync(__dirname + '/index.html', 'utf8');
const script = html.match(/<script>([\s\S]*?)<\/script>/)[1];
const elements = new Map();
function element(id) {
if (!elements.has(id)) elements.set(id, { value: id === 'pageSize' ? '50' : '', innerHTML: '', textContent: '', classList: { toggle() { return true; } }, setAttribute() {}, showModal() {}, close() {} });
return elements.get(id);
}
const context = vm.createContext({ document: { getElementById: element, querySelectorAll: () => [] }, console: { assert: assert.ok }, setTimeout: () => 1, clearTimeout() {}, FormData, assert });
vm.runInContext(script, context);
vm.runInContext(`
assert.equal(visibleRows().length, 50);
page=2; assert.equal(visibleRows().length, 22);
query='乐乐'; assert.equal(filtered().length, 3);
query=''; group='服饰鞋包'; assert.equal(filtered().length, 24);
group=''; tab='已过期'; assert.ok(filtered().every(r=>r.status==='已过期'));
for (const key of Object.keys(configs)) {
switchPage(key);
assert.ok($('tbody').innerHTML.includes('data-edit'));
openEditor(data[key][0].id);
assert.ok($('editorFields').innerHTML.includes('name="name"'));
hiddenColumns.add('group'); renderTable();
assert.ok(!$('thead').innerHTML.includes('所属分组'));
}
switchPage('stores');
assert.equal(configs.stores.columns.length, 11);
assert.equal(configs.users.columns.length, 13);
assert.ok($('tbody').innerHTML.includes('data-store-action'));
selected.add(data.stores[3].id); $('login').onclick();
assert.equal(data.stores[3].login, '登录成功');
$('batch').onclick();
assert.equal(data.stores[3].status, '正常');
assert.equal(selected.size, 0);
query='no-matching-record'; renderTable();
assert.ok($('tbody').innerHTML.includes('没有匹配的记录'));
assert.equal($('next').disabled, true);
assert.equal(escapeHtml('<img onerror="bad">'), '&lt;img onerror=&quot;bad&quot;&gt;');
`, context);
console.log('PASS: script syntax, five page renders, pagination, filters, editors, columns, batch action, empty state and HTML escaping.');
// Verify contextual navigation against the actual HTML attributes.
const markup = html.split("<script>")[0];
const ids = [...markup.matchAll(/\bid="([^"]+)"/g)].map(m => m[1]);
assert.equal(ids.length, new Set(ids).size);
const modules = [...markup.matchAll(/data-module="([^"]+)" data-start="([^"]+)"/g)].map(m => ({ dataset: { module: m[1], start: m[2] }, classList: { toggle() {} }, setAttribute(name, value) { this[name] = value; } }));
const pages = [...markup.matchAll(/data-area="([^"]+)" data-page="([^"]+)"/g)].map(m => ({ dataset: { area: m[1], page: m[2] }, classList: { toggle() {} }, setAttribute() {} }));
context.document.querySelectorAll = selector => selector === "[data-module]" ? modules : pages;
assert.equal(modules.length, 3); assert.equal(pages.length, 5);
for (const page of pages) {
vm.runInContext("switchPage(" + JSON.stringify(page.dataset.page) + ")", context);
assert.equal(page.hidden, false);
assert.ok(pages.every(p => p.hidden === (p.dataset.area !== page.dataset.area)));
assert.equal(modules.filter(m => m["aria-pressed"]).length, 1);
assert.equal(modules.find(m => m["aria-pressed"]).dataset.module, page.dataset.area);
}
console.log("PASS: three icon modules, five contextual pages, active and hidden navigation states.");