File size: 2,509 Bytes
09aeaeb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | import test from 'node:test';
import assert from 'node:assert/strict';
import {createHash} from 'node:crypto';
import {buildDeclaredModule} from './build_declared_module.mjs';
import {buildGraphPlan} from './build_graph_plan.mjs';
function fixture(source){
const raw={'rollup.config.js':`const pkg=require('./package.json');export default {input:'src/core.js',output:{file:pkg.module,format:'es'}}`,
'package.json':JSON.stringify({module:'dist/core.js',scripts:{sync:'cp dist/core.js web/core.js'}}),
'src/core.js':source,'web/main.js':`import {twice} from './core'; export const answer=twice(21);`};
return {digest:'a'.repeat(64),repository:{files:Object.fromEntries(Object.entries(raw).map(([p,s])=>{const b=Buffer.from(s);return[p,{base64:b.toString('base64'),bytes:b.length,sha256:createHash('sha256').update(b).digest('hex')}];}))}};
}
test('bundles declared generated alias using captured bytes only',async()=>{
const p=fixture('export const twice=x=>x*2;');const before=JSON.stringify(p);
const r=await buildDeclaredModule(p,'web/main.js','modern-esm-bundle-v1');
assert.equal(r.used['web/core.js'].source,'src/core.js');
assert.equal(r.status,'UNVERIFIED_CANDIDATE');assert.equal(JSON.stringify(p),before);
assert.ok(r.bytes>0);
});
test('external and dynamic module acquisition refuse',async()=>{
await assert.rejects(()=>buildDeclaredModule(fixture(`import x from 'https://example.com/a.js';export const twice=x;`),'web/main.js','modern-esm-bundle-v1'));
await assert.rejects(()=>buildDeclaredModule(fixture(`export const twice=()=>import('./later.js');`),'web/main.js','modern-esm-bundle-v1'));
});
test('graph readiness detects transitive gaps without executing source',()=>{
const p=fixture(`throw Error('must not execute');export {twice} from './helper';`);
const r=buildGraphPlan(p,'web/main.js');
assert.deepEqual(r.graph.missing_paths,['src/helper']);
assert.equal(r.graph.status,'CAPTURE_REQUIRED');
assert.equal(r.graph.verified_application,false);
for(const source of [`import x from 'external';`, `import('./later.js');`, `import '../../../escape.js';`])
assert.throws(()=>buildGraphPlan(fixture(source),'web/main.js'));
});
test('graph readiness terminates cycles and checks source bytes',()=>{
const p=fixture(`import '../web/main.js';export const twice=x=>x*2;`);
assert.equal(buildGraphPlan(p,'web/main.js').graph.status,'READY');
p.repository.files['src/core.js'].sha256='0'.repeat(64);
assert.throws(()=>buildGraphPlan(p,'web/main.js'),/SOURCE_BINDING/);
});
|