base/test/base.test.js

134 lines
5.5 KiB
JavaScript
Raw Normal View History

import { HTTP, UI, State } from '@apigo.cc/base';
export async function runTests() {
console.log('Starting comprehensive Base.js tests...');
// 1. HTTP Test
console.log('Testing HTTP (local check)...');
if (typeof HTTP.request !== 'function') throw new Error('HTTP.request missing');
// 2. State Test
console.log('Testing State...');
State.exitBlocks = 1;
if (State.exitBlocks !== 1) throw new Error('State update failed');
State.exitBlocks = 0;
// 3. UI Namespace Test
console.log('Testing UI...');
if (typeof UI.alert !== 'function') throw new Error('UI.alert missing');
if (typeof UI.toast !== 'function') throw new Error('UI.toast missing');
// 4. API Component Test
console.log('Testing API Component...');
const api = document.createElement('API');
document.body.appendChild(api);
await new Promise(r => setTimeout(r, 50));
api.request.url = '../package.json';
const apiResp = await api.do();
if (!apiResp.ok) throw new Error('API component request failed');
api.remove();
// 5. AutoForm & TagsInput Test
console.log('Testing AutoForm...');
const { NewState } = await import('@apigo.cc/state');
const form = document.createElement('AutoForm');
document.body.appendChild(form);
await new Promise(r => setTimeout(r, 200));
// Test dynamic schema and visibility
form.data = NewState({ showName: false, name: 'Gemini' });
form.state.schema = [
{ name: 'tags', type: 'TagsInput', label: '标签' },
{ name: 'showName', type: 'switch', label: 'Show Name' },
{ name: 'name', type: 'text', label: 'Name', if: 'this.data.showName' }
];
await new Promise(r => setTimeout(r, 200));
if (!form.querySelector('TagsInput')) throw new Error('TagsInput not rendered');
if (form.querySelector('[name="name"]')) throw new Error('Name field should be hidden');
form.data.showName = true;
await new Promise(r => setTimeout(r, 200));
if (!form.querySelector('[name="name"]')) throw new Error('Name field should be visible');
form.remove();
// 6. New Controls (DatePicker, ColorPicker, IconPicker) Test
console.log('Testing New Controls...');
const controlForm = document.createElement('AutoForm');
document.body.appendChild(controlForm);
await new Promise(r => setTimeout(r, 200));
controlForm.state.schema = [
{ name: 'startDate', type: 'DatePicker', setting: { rangeEnd: 'endDate' } },
{ name: 'endDate', type: 'date' },
{ name: 'color', type: 'ColorPicker' },
{ name: 'icon', type: 'IconPicker' }
];
controlForm.data = { startDate: '2026-05-01', endDate: '2026-05-31', color: '#ff0000', icon: 'gear' };
await new Promise(r => setTimeout(r, 400));
const dp = controlForm.querySelector('DatePicker');
const cp = controlForm.querySelector('ColorPicker');
const ip = controlForm.querySelector('IconPicker');
if (!dp) throw new Error('DatePicker not rendered');
if (!cp) throw new Error('ColorPicker not rendered');
if (!ip) throw new Error('IconPicker not rendered');
// Test DatePicker range sync
dp.updateEnd('2026-06-01');
if (controlForm.data.endDate !== '2026-06-01') throw new Error('DatePicker rangeEnd sync failed');
// Test ColorPicker
cp.updateValue('#00ff00');
if (controlForm.data.color !== '#00ff00') throw new Error('ColorPicker sync failed');
// Test IconPicker
ip.selectIcon('star');
if (controlForm.data.icon !== 'star') throw new Error('IconPicker sync failed');
controlForm.remove();
// 7. List Components Basic Verification
console.log('Verifying List Components...');
const { Component } = await import('@apigo.cc/state');
console.log('FastList exists:', Component.exists('FastList'));
const listIds = ['ll', 'gl', 'tt', 'ct'];
for (const id of listIds) {
window.switchTab?.(id);
await new Promise(r => setTimeout(r, 100)); // wait for render
const el = document.getElementById(id);
if (!el) throw new Error(`Component #${id} not found`);
console.log(`Component #${id} tagName:`, el.tagName, 'has refresh:', !!el.refresh, 'setupFunc exists:', !!Component.getSetupFunction(el.tagName));
if (!el.state.list || el.state.list.length === 0) throw new Error(`Component #${id} list data not bound`);
}
// 7. Benchmarks
console.log('Recording list benchmarks...');
window.benchResults = {};
const measure = async (id, name) => {
window.switchTab?.(id);
await new Promise(r => setTimeout(r, 100)); // wait for render
const el = document.getElementById(id);
const start = performance.now();
console.log(`[MEASURE] ${name} setting scrollTop to 5000`);
el.scrollTop = 5000;
console.log(`[MEASURE] ${name} calling refresh`);
el.refresh?.();
console.log(`[MEASURE] ${name} refresh called, waiting 50ms`);
await new Promise(r => setTimeout(r, 50));
console.log(`[MEASURE] ${name} wait done`);
const time = performance.now() - start;
window.benchResults[name] = time;
console.log(`BENCHMARK: ${name} scroll & refresh: ${time.toFixed(2)}ms`);
console.log(`DEBUG [${id}]: _renderedList len: ${el.state._renderedList?.length}, _flatList len: ${el.state._flatList?.length}`);
};
await measure('ll', 'FastList');
await measure('gl', 'FastGroupedList');
await measure('tt', 'FastTree');
await measure('ct', 'CollapseTree');
console.log('All Base.js unit tests completed.');
}