2026-05-14 17:12:01 +08:00
|
|
|
import { test, expect } from '@playwright/test';
|
2026-05-15 00:57:35 +08:00
|
|
|
import fs from 'fs';
|
|
|
|
|
import path from 'path';
|
2026-05-14 17:12:01 +08:00
|
|
|
|
|
|
|
|
test('modular unit tests and benchmark', async ({ page }) => {
|
|
|
|
|
page.on('console', msg => console.log('BROWSER LOG:', msg.text()));
|
|
|
|
|
await page.goto('http://localhost:8081/test/index.html');
|
|
|
|
|
|
|
|
|
|
await page.waitForFunction(() => window.testStatus !== undefined, { timeout: 10000 });
|
|
|
|
|
const status = await page.evaluate(() => window.testStatus);
|
|
|
|
|
expect(status).toBe('passed');
|
|
|
|
|
|
2026-05-15 00:57:35 +08:00
|
|
|
// Read benchmarks from TEST.md
|
|
|
|
|
const testMd = fs.readFileSync(path.join(process.cwd(), 'TEST.md'), 'utf-8');
|
|
|
|
|
const getBench = (name) => {
|
|
|
|
|
const match = testMd.match(new RegExp(`\\*\\*${name}\\*\\*\\s*\\|\\s*([\\d.]+)`));
|
|
|
|
|
return match ? parseFloat(match[1]) : null;
|
|
|
|
|
};
|
|
|
|
|
const baseInitial = getBench('首次渲染 \\(1000 items\\)');
|
|
|
|
|
const baseUpdate = getBench('浅更新 \\(Shallow Update\\)');
|
|
|
|
|
|
2026-05-14 17:12:01 +08:00
|
|
|
// Benchmark: Large list rendering
|
|
|
|
|
const renderTime = await page.evaluate(async () => {
|
|
|
|
|
const start = performance.now();
|
|
|
|
|
document.body.innerHTML = `
|
|
|
|
|
<ul id="bench-list">
|
|
|
|
|
<template $each="state.benchItems" as="item">
|
|
|
|
|
<li $text="item.val"></li>
|
|
|
|
|
</template>
|
|
|
|
|
</ul>
|
|
|
|
|
`;
|
|
|
|
|
const items = [];
|
|
|
|
|
for(let i=0; i<1000; i++) items.push({val: 'item ' + i});
|
|
|
|
|
window.state.benchItems = items;
|
|
|
|
|
const { RefreshState } = await import('@web/state');
|
|
|
|
|
RefreshState(document.documentElement);
|
|
|
|
|
return performance.now() - start;
|
|
|
|
|
});
|
|
|
|
|
console.log(`BENCHMARK: 1000 items initial render: ${renderTime.toFixed(2)}ms`);
|
2026-05-15 00:57:35 +08:00
|
|
|
if (baseInitial) expect(renderTime).toBeLessThan(baseInitial * 1.2);
|
2026-05-14 17:12:01 +08:00
|
|
|
|
|
|
|
|
// Benchmark: Large list update
|
|
|
|
|
const updateTime = await page.evaluate(async () => {
|
|
|
|
|
const start = performance.now();
|
|
|
|
|
window.state.benchItems[0].val = 'updated';
|
|
|
|
|
window.state.benchItems = [...window.state.benchItems];
|
|
|
|
|
return performance.now() - start;
|
|
|
|
|
});
|
|
|
|
|
console.log(`BENCHMARK: 1000 items update (shallow): ${updateTime.toFixed(2)}ms`);
|
2026-05-15 00:57:35 +08:00
|
|
|
if (baseUpdate) expect(updateTime).toBeLessThan(baseUpdate * 1.2);
|
|
|
|
|
|
|
|
|
|
// Extreme Data Test
|
|
|
|
|
await page.evaluate(async () => {
|
|
|
|
|
const { RefreshState } = await import('@web/state');
|
|
|
|
|
document.body.innerHTML = '<div id="extreme" $each="state.extreme"></div>';
|
|
|
|
|
window.state.extreme = null;
|
|
|
|
|
RefreshState(document.getElementById('extreme'));
|
|
|
|
|
window.state.extreme = undefined;
|
|
|
|
|
window.state.extreme = { a: 1 };
|
|
|
|
|
window.state.extreme = [1, 2];
|
|
|
|
|
window.state.extreme = "not iterable";
|
|
|
|
|
});
|
2026-05-14 17:12:01 +08:00
|
|
|
});
|