|
|
<!doctype html> |
|
|
<html lang="en-us"> |
|
|
<head> |
|
|
<meta charset="utf-8"> |
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
|
|
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon"> |
|
|
|
|
|
<link rel="stylesheet" href="../common/testing.css"/> |
|
|
<title>SQLTester</title> |
|
|
</head> |
|
|
<style> |
|
|
fieldset { |
|
|
display: flex; |
|
|
flex-direction: row; |
|
|
padding-right: 1em; |
|
|
} |
|
|
fieldset > :not(.legend) { |
|
|
display: flex; |
|
|
flex-direction: row; |
|
|
padding-right: 1em; |
|
|
} |
|
|
</style> |
|
|
<body> |
|
|
<h1>SQLTester for JS/WASM</h1> |
|
|
<p>This app reads in a build-time-defined set of SQLTester test |
|
|
scripts and runs them through the test suite. |
|
|
</p> |
|
|
<fieldset> |
|
|
<legend>Options</legend> |
|
|
<span class='input-wrapper'> |
|
|
<input type='checkbox' id='cb-log-reverse' checked> |
|
|
<label for='cb-log-reverse'>Reverse log order?</label> |
|
|
</span> |
|
|
<input type='button' id='btn-run-tests' value='Run tests'/> |
|
|
</fieldset> |
|
|
<div id='test-output'>Test output will go here.</div> |
|
|
|
|
|
<script> |
|
|
(async function(){ |
|
|
const W = new Worker('SQLTester.run.mjs',{ |
|
|
type: 'module' |
|
|
}); |
|
|
const wPost = (type,payload)=>W.postMessage({type,payload}); |
|
|
const mapToString = (v)=>{ |
|
|
switch(typeof v){ |
|
|
case 'string': return v; |
|
|
case 'number': case 'boolean': |
|
|
case 'undefined': case 'bigint': |
|
|
return ''+v; |
|
|
default: break; |
|
|
} |
|
|
if(null===v) return 'null'; |
|
|
if(v instanceof Error){ |
|
|
v = { |
|
|
message: v.message, |
|
|
stack: v.stack, |
|
|
errorClass: v.name |
|
|
}; |
|
|
} |
|
|
return JSON.stringify(v,undefined,2); |
|
|
}; |
|
|
const normalizeArgs = (args)=>args.map(mapToString); |
|
|
const logTarget = document.querySelector('#test-output'); |
|
|
const logClass = function(cssClass,...args){ |
|
|
const ln = document.createElement('div'); |
|
|
if(cssClass){ |
|
|
for(const c of (Array.isArray(cssClass) ? cssClass : [cssClass])){ |
|
|
ln.classList.add(c); |
|
|
} |
|
|
} |
|
|
ln.append(document.createTextNode(normalizeArgs(args).join(' '))); |
|
|
logTarget.append(ln); |
|
|
}; |
|
|
{ |
|
|
const cbReverse = document.querySelector('#cb-log-reverse'); |
|
|
const cbReverseKey = 'SQLTester:cb-log-reverse'; |
|
|
const cbReverseIt = ()=>{ |
|
|
logTarget.classList[cbReverse.checked ? 'add' : 'remove']('reverse'); |
|
|
}; |
|
|
cbReverse.addEventListener('change', cbReverseIt, true); |
|
|
cbReverseIt(); |
|
|
} |
|
|
|
|
|
const btnRun = document.querySelector('#btn-run-tests'); |
|
|
const runTests = ()=>{ |
|
|
btnRun.setAttribute('disabled','disabled'); |
|
|
wPost('run-tests'); |
|
|
logTarget.innerText = 'Running tests...'; |
|
|
} |
|
|
btnRun.addEventListener('click', runTests); |
|
|
const log2 = function f(...args){ |
|
|
logClass('', ...args); |
|
|
return f; |
|
|
}; |
|
|
const log = function f(...args){ |
|
|
logClass('','index.html:',...args); |
|
|
return f; |
|
|
}; |
|
|
|
|
|
const timerId = setTimeout( ()=>{ |
|
|
logClass('error',"The SQLTester module is taking an unusually ", |
|
|
"long time to load. More information may be available", |
|
|
"in the dev console."); |
|
|
}, 3000 ); |
|
|
|
|
|
W.onmessage = function({data}){ |
|
|
switch(data.type){ |
|
|
case 'stdout': log2(data.payload.message); break; |
|
|
case 'tests-end': |
|
|
btnRun.removeAttribute('disabled'); |
|
|
delete data.payload.nTest; |
|
|
log("test results:",data.payload); |
|
|
break; |
|
|
case 'is-ready': |
|
|
clearTimeout(timerId); |
|
|
runTests(); break; |
|
|
default: |
|
|
log("unhandled onmessage",data); |
|
|
break; |
|
|
} |
|
|
}; |
|
|
})(); |
|
|
</script> |
|
|
</body> |
|
|
</html> |
|
|
|