contracts.test.mjs (2448B)
1 import test from 'node:test'; 2 import assert from 'node:assert/strict'; 3 import {readFile} from 'node:fs/promises'; 4 import {createHash} from 'node:crypto'; 5 import {Graph} from '../dist/graph.js'; 6 import {COMPILER_BUNDLE_LIMIT,decodeBundle,loadBundle} from '../dist/bundle.js'; 7 import {readList,readText} from '../dist/codecs.js'; 8 import {contractEnvironment,CONTRACT_BINDINGS} from '../dist/contracts.js'; 9 10 test('contract environment aliases authenticated existing trees without forcing code',async()=>{ 11 const descriptor=JSON.parse(await readFile(new URL('../compiler.json',import.meta.url))); 12 const bundle=decodeBundle(await readFile(new URL('../bundles/'+descriptor.hash+'.arboricx',import.meta.url)),COMPILER_BUNDLE_LIMIT); 13 const g=new Graph(),library=loadBundle(g,bundle),before=g.stats.allocations; 14 const environment=contractEnvironment(g,library); 15 const records=readList(g,environment,100); 16 assert.equal(records.length,38);assert.ok(g.stats.allocations-before<5000); 17 assert.equal(CONTRACT_BINDINGS.id,undefined);assert.equal(CONTRACT_BINDINGS.pair,undefined); 18 assert.equal(CONTRACT_BINDINGS.Nat,undefined);assert.equal(CONTRACT_BINDINGS.Bool,undefined); 19 assert.equal(CONTRACT_BINDINGS['nat?'],'base.nat?'); 20 for(const [i,[name,exported]] of Object.entries(CONTRACT_BINDINGS).entries()){ 21 const [label,value]=g.pair(records[i]); 22 assert.equal(readText(g,label),name);assert.equal(value,library.get(exported)); 23 } 24 const loop=g.app(g.fromTernary('212110021100'),g.fromTernary('212110021100')); 25 const divergent=new Map(Object.values(CONTRACT_BINDINGS).map(name=>[name,loop])); 26 assert.doesNotThrow(()=>contractEnvironment(g,divergent)); // Binding names, not interpreting functions. 27 assert.throws(()=>contractEnvironment(g,new Map()),/missing contract export/); 28 }); 29 test('contract Haskell goldens authenticate environment source and packaged bytes',async()=>{ 30 const goldens=JSON.parse(await readFile(new URL('./contracts-conformance.json',import.meta.url))); 31 const hash=bytes=>createHash('sha256').update(bytes).digest('hex'); 32 assert.deepEqual(goldens.bindings,CONTRACT_BINDINGS); 33 assert.equal(goldens.contractsSourceSha256,hash(await readFile(new URL('../src/contracts.ts',import.meta.url)))); 34 const descriptor=JSON.parse(await readFile(new URL('../compiler.json',import.meta.url))); 35 assert.equal(goldens.compilerBundleSha256,descriptor.hash);assert.equal(goldens.backend,'stable'); 36 assert.equal(goldens.cases.length,11); 37 });