- remove onBackPress interception (was swallowing back press to fake-confirm) - '=' with no pending op no longer zeroes the display (AC + 2 + = was 0) - AC no longer leaves stale fresh flag (first digit after AC appended to 0) - leading zero replaced by first digit (00 + 2 was 002) - operators auto-evaluate pending op (2+3x4 = 20, left-to-right) - repeated = re-applies last operation (2+3=== -> 11) - stale test updated to current list UI bindings
48 lines
2.1 KiB
JavaScript
48 lines
2.1 KiB
JavaScript
const fs = require('node:fs');
|
|
const vm = require('node:vm');
|
|
const assert = require('node:assert/strict');
|
|
const ux = fs.readFileSync('src/pages/index/index.ux', 'utf8');
|
|
const script = ux.match(/<script>([\s\S]*?)<\/script>/)[1];
|
|
function page() {
|
|
const spec = vm.runInNewContext(script.replace('export default', 'globalThis.spec =') + '\nspec');
|
|
const o = Object.assign({}, spec.private, spec);
|
|
o.$element = () => ({ scrollTo: () => {} });
|
|
o.onInit && o.onInit();
|
|
return o;
|
|
}
|
|
const p = page();
|
|
assert.equal(typeof p.press, 'function', 'Keypress handler must exist');
|
|
['2','+','3','='].forEach(k => p.press(k));
|
|
assert.equal(p.display, '5');
|
|
console.log('PASS addition through page keypress handler');
|
|
const cases = [
|
|
['subtract',['9','-','4','='],'5'],
|
|
['multiply',['6','x','7','='],'42'],
|
|
['divide',['8','/','2','='],'4'],
|
|
['decimals',['0','.','1','+','0','.','2','='],'0.3'],
|
|
['duplicate dot',['1','.','.','2'],'1.2'],
|
|
['sign',['5','+/-','x','2','='],'-10'],
|
|
['percent',['5','0','%'],'0.5'],
|
|
['percent add',['2','0','0','+','1','0','%','='],'200.1'],
|
|
['percent multiply',['2','0','0','x','1','0','%','='],'20'],
|
|
['clear',['9','+','AC','2','='],'2'],
|
|
['zero division',['8','/','0','='],'Error'],
|
|
['recover',['8','/','0','=','3'],'3'],
|
|
['chain',['2','+','3','x','4','='],'20'],
|
|
['replace operator',['2','+','x','3','='],'6'],
|
|
['repeat equals',['2','+','3','=','=', '='],'11'],
|
|
['fresh entry',['2','+','3','=','7'],'7'],
|
|
['input cap',Array(20).fill('9'),'999999999'],
|
|
['leading zero',['0','0','2'],'2']
|
|
];
|
|
for(const [name,keys,expected] of cases) {
|
|
const c=page(); keys.forEach(k=>c.press(k)); assert.equal(c.display,expected,name);
|
|
}
|
|
assert.match(ux, /\{\{ display \}\}/);
|
|
const labels = ux.match(/const labels = \[([^\]]+)\]/)[1].match(/'([^']+)'/g).map(s => s.slice(1, -1));
|
|
assert.equal(labels.length, 19, '19 keys defined');
|
|
assert.equal(new Set(labels).size, 19, 'all keys unique');
|
|
assert.match(ux, /onclick="confirmKey"/, 'list items confirm focused key');
|
|
assert.doesNotMatch(ux, /onBackPress/, 'back button must not be intercepted (exits app)');
|
|
console.log('PASS',cases.length,'edge cases and all 19 button bindings');
|