tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

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 }