tricu

A lazy functional language based on Tree Calculus
Log | Files | Refs | README | LICENSE

ide-probe.mjs (5080B)


      1 import {syntaxProbe} from './syntax-probe.mjs';
      2 import {el,input,change,status,wait,inspect,result,description,card,evaluateSource} from './source-probe-helpers.mjs';
      3 const assert=(condition,message)=>{if(!condition)throw Error(message);};
      4 export async function run(control,backend='haskell-wasm'){
      5  const phase=name=>fetch(control+'/phase',{method:'POST',body:JSON.stringify({name:'ide: '+name})});
      6  await status('Ready');await syntaxProbe();await status('Ready');
      7  assert(!el('runtime-backend'),'No runtime selector');
      8  for(const path of ['worker.js','compiler-worker.js','conformance/worker.js','conformance/compiler-worker.js'])assert((await fetch(new URL('./'+path,document.querySelector('script[type=module][src]').src))).status===404,'JS conformance Workers not shipped');
      9  assert(!el('expression-editor')&&card().hidden,'Arrival is source-first and does not inspect automatically');
     10  el('settings-toggle').click();assert(!el('settings-panel').hidden,'Settings opens');el('settings-close').click();assert(document.activeElement===el('settings-toggle'),'Settings returns focus');
     11  change('program-picker','demo:language-reference');await status('Ready');
     12  for(const [format,want] of [['tricu','t'],['triangle','△'],['dag','tree △\ntree\n'],['ternary','0']])assert(await inspect('leaf',format)===want,'Direct definition '+format);
     13  for(const [format,want] of [['tricu','(t t t)'],['triangle','(△ △ △)'],['ternary','200']])assert(await evaluateSource('identity (t t t)',format)===want,'Source-authored application '+format);
     14  let copied,blob,download;const clipboard=Object.getOwnPropertyDescriptor(navigator,'clipboard');
     15  Object.defineProperty(navigator,'clipboard',{configurable:true,value:{writeText:async value=>{copied=value;}}});
     16  const createURL=URL.createObjectURL,click=HTMLAnchorElement.prototype.click;
     17  URL.createObjectURL=value=>{blob=value;return createURL(value);};HTMLAnchorElement.prototype.click=function(){download=this.download;};
     18  try{
     19   await phase('complete text download');
     20   await evaluateSource(JSON.stringify('a'.repeat(600)),'tricu');assert(result().length===16384&&description().includes('Preview: first 16,384'),'Bounded preview is explicit');
     21   card().querySelector('.definition-actions button').click();await wait(()=>copied!==undefined,'complete copy');assert(copied.length>16384&&copied.startsWith(result()),'Copy has complete tree source');
     22   card().querySelectorAll('.definition-actions button')[1].click();assert(download==='probeResult.tri'&&await blob.text()===copied,'Download matches complete copy');
     23   // Package export uses original DAG records and does not normalize functions.
     24   change('program-picker','demo:language-reference');await status('Ready');change('stored-definition','leaf');change('stored-format','tricu');blob=undefined;
     25   el('stored-download').click();await wait(()=>!!blob&&el('status').textContent==='Ready','stored export');assert(download==='leaf.tri'&&await blob.text()==='t','Stored-record tree export');
     26   const expectedHash=el('bundle-hash').value;blob=undefined;el('download-bundle').click();await wait(()=>!!blob&&/Downloaded original/.test(el('bundle-download-status').textContent),'verified original bundle');
     27   const digest=[...new Uint8Array(await crypto.subtle.digest('SHA-256',await blob.arrayBuffer()))].map(n=>n.toString(16).padStart(2,'0')).join('');assert(digest===expectedHash&&download===expectedHash+'.arboricx','Immutable authenticated bundle bytes');
     28  }finally{URL.createObjectURL=createURL;HTMLAnchorElement.prototype.click=click;if(clipboard)Object.defineProperty(navigator,'clipboard',clipboard);else delete navigator.clipboard;}
     29  el('reload-package').click();await status('Ready');
     30  await phase('shared DAG');
     31  const bindings=['x0 = t t t'];for(let i=1;i<=28;i++)bindings.push(`x${i} = t x${i-1} x${i-1}`);
     32  const expression='let\n  '+bindings.join('\n  ')+'\n  in x28';
     33  assert((await evaluateSource(expression,'dag')).length<20000,'DAG preserves exponential sharing');
     34  await phase('expanded tree refusal');
     35  await inspect('probeResult','tricu');assert(/Expanded tree exceeds 32 MiB/.test(description()),'Refuse oversized expansion before constructing output');
     36  assert([...card().querySelectorAll('.definition-actions button')].every(button=>button.disabled),'Partial result never downloadable');
     37  assert(await evaluateSource('identity 52')==='52','Rendering error preserves definitions');
     38  input('bundle-hash','not-a-hash');el('program-hash').requestSubmit();assert(el('status').textContent==='Stopped'&&card().hidden,'Invalid replacement cannot retain old output');
     39  change('program-picker','demo:language-reference');await status('Ready');
     40  await phase('live revisions and IO');
     41  const live=await(await import('/live-ux-probe.mjs')).run(control,backend);
     42  change('program-picker','demo:language-reference');await status('Ready');
     43  return {userAgent:navigator.userAgent,checks:[...live.checks,'source-first workspace; native settings; t/triangle/DAG/ternary; complete inline Copy/Download; expansion refusal; non-evaluating stored export; immutable bundle download']};
     44 }