134 lines
5.5 KiB
JavaScript
134 lines
5.5 KiB
JavaScript
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.');
|
|
}
|