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/);
});