41 lines
2.7 KiB
JavaScript
41 lines
2.7 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { readFileSync } = require('node:fs');
|
|
const vm = require('node:vm');
|
|
function fixture() {
|
|
const inserted = [], listeners = {}, writes = [];
|
|
const manifest = { buildTag: 'own', groups: { core: { files: [] }, 'layout:classic': { files: ['/classic.css'] }, 'layout:glass-stage': { files: ['/glass.css', '/one.js', '/two.js'] }, 'feature:test': { files: ['/one.js', '/two.js'] } }, files: { '/classic.css': {h:'c'}, '/glass.css':{h:'g'}, '/one.js':{h:'1'}, '/two.js':{h:'2'} } };
|
|
const doc = { readyState:'loading', documentElement: { dataset:{} }, getElementById: () => ({ textContent:JSON.stringify(manifest) }), querySelectorAll: () => [], createElement: tag => ({ tagName:tag.toUpperCase() }), write: value => writes.push(value), addEventListener: (t,f) => listeners[t]=f };
|
|
doc.head = { append: node => { inserted.push(node); queueMicrotask(() => node.onload?.()); } };
|
|
const root = { document:doc, localStorage:{ getItem:() => '{"settings":{"layout":"glass-stage"}}' }, console, Promise, URL, setTimeout, clearTimeout, navigator:{}, addEventListener(){} };
|
|
root.window=root; root.globalThis=root;
|
|
vm.runInNewContext(readFileSync(require.resolve('./lazy.js'),'utf8'), root);
|
|
return { root, inserted, writes, listeners };
|
|
}
|
|
test('external head bootstrap selects remembered CSS before paint without fetching a manifest', () => {
|
|
const {root,writes}=fixture();
|
|
assert.equal(root.document.documentElement.dataset.layout,'glass-stage');
|
|
assert.deepEqual(writes,['<link rel="stylesheet" href="/glass.css?v=g" data-lazy-css="/glass.css">']);
|
|
});
|
|
test('lazy groups execute ordered classic scripts once, sharing concurrent calls and dependencies', async () => {
|
|
const {root,inserted}=fixture();
|
|
const one=root.Lazy.load('feature:test'), two=root.Lazy.load('feature:test');
|
|
await Promise.all([one,two]);
|
|
assert.deepEqual(inserted.map(n=>n.src),['/one.js?v=1','/two.js?v=2']);
|
|
assert.equal(root.Lazy.loaded('feature:test'),true);
|
|
await root.Lazy.load('layout:glass-stage');
|
|
assert.equal(inserted.filter(n=>n.tagName==='SCRIPT').length,2);
|
|
});
|
|
test('failed injection can retry and proxy dispatches only after execution', async () => {
|
|
const {root,inserted}=fixture();
|
|
const append=root.document.head.append;
|
|
root.document.head.append=n=>{inserted.push(n);queueMicrotask(()=>n.onerror?.());};
|
|
await assert.rejects(root.Lazy.load('feature:test'),/one.js/);
|
|
root.document.head.append=append;
|
|
root.TestApi={open:value=>value+1};
|
|
const proxy=root.Lazy.proxy('feature:test',['open'],'TestApi');
|
|
assert.equal(await proxy.open(4),5);
|
|
assert.equal(root.Lazy.url('/two.js'),'/two.js?v=2');
|
|
await assert.rejects(root.Lazy.load('feature:missing'),/Unknown/);
|
|
});
|