contracts-conformance.mjs (2181B)
1 import {COMPILER_BUDGET} from './budgets.mjs'; 2 // Opt-in source compilation against independent Haskell contract goldens. 3 import assert from 'node:assert/strict'; 4 import {readFile} from 'node:fs/promises'; 5 import {createHash} from 'node:crypto'; 6 import {Graph} from '../dist/graph.js'; 7 import {COMPILER_BUNDLE_LIMIT,decodeBundle,loadBundle} from '../dist/bundle.js'; 8 import {contractEnvironment,CONTRACT_BINDINGS} from '../dist/contracts.js'; 9 import {COMPILER_EXPORT,COMPILER_COLLECTION,sourceLiteral,compiledDefinitions} from '../dist/compiler.js'; 10 const goldens=JSON.parse(await readFile(new URL('./contracts-conformance.json',import.meta.url))); 11 const bytes=await readFile(new URL('../bundles/'+goldens.compilerBundleSha256+'.arboricx',import.meta.url)); 12 const hash=bytes=>createHash('sha256').update(bytes).digest('hex'); 13 assert.equal(hash(bytes),goldens.compilerBundleSha256); 14 assert.equal(hash(await readFile(new URL('../src/contracts.ts',import.meta.url))),goldens.contractsSourceSha256); 15 assert.deepEqual(CONTRACT_BINDINGS,goldens.bindings); 16 const bundle=decodeBundle(bytes,COMPILER_BUNDLE_LIMIT); 17 for(const source of new Set(goldens.cases.map(c=>c.source))){ 18 // Higher-order/multiple checks cost more than the UI's default work allowance. 19 const g=new Graph({...COMPILER_BUDGET,fuel:500_000_000},COMPILER_COLLECTION),library=loadBundle(g,bundle); 20 const start=performance.now(),environment=contractEnvironment(g,library); 21 const definitions=compiledDefinitions(g,g.apply(library.get(COMPILER_EXPORT),[environment,sourceLiteral(g,source)])); 22 g.collect(definitions.values()); 23 for(const c of goldens.cases.filter(c=>c.source===source)){ 24 assert.deepEqual([...definitions.keys()],Object.keys(c.definitions)); 25 for(const [name,tree] of Object.entries(c.definitions))assert.equal(g.toTernary(definitions.get(name),50000),tree); 26 const result=g.apply(definitions.get(c.export),c.arguments.map(tree=>g.fromTernary(tree))); 27 assert.equal(g.toTernary(result,50000),c.result); 28 } 29 assert.ok(g.stats.collections>0);assert.ok(g.stats.peakNodes<600_000); 30 console.log('PASS Haskell contract comparison',JSON.stringify(source),Math.round(performance.now()-start)+'ms',g.stats); 31 }