diff --git a/__tests__/buttons.spec.js b/__tests__/buttons.spec.js new file mode 100644 index 0000000..715caf0 --- /dev/null +++ b/__tests__/buttons.spec.js @@ -0,0 +1,113 @@ +const { ButtonMachine } = require('../../src/node_modules/buttons'); + +const run_code = (expecting, code, debug=false) => { + let machine = new ButtonMachine(code); + + machine.run(debug); + + expect(machine.stack_top).toBe(expecting); + + return machine; +} + +it('Can do addition', () => { + run_code(3, [ + ['PUSH', 1], + ['PUSH', 2], + ['ADD'], + ]) +}); + +it('Can do subtraction', () => { + run_code(1, [ + ['PUSH', 2], + ['PUSH', 1], + ['SUB'], + ]) +}) + +it('Can do multiplication', () => { + run_code(20, [ + ['PUSH', 10], + ['PUSH', 2], + ['MUL'], + ]) +}) + +it('Can do division', () => { + run_code(5, [ + ['PUSH', 10], + ['PUSH', 2], + ['DIV'], + ]) +}) + +it('Can do modulus', () => { + run_code(0, [ + ['PUSH', 10], + ['PUSH', 2], + ['MOD'], + ]) +}) + +it('Can loop until the end of ticks', () => { + run_code(43, [ + ['PUSH', 1], + ['PUSH', 1], + ['ADD'], + ['JUMP', 1] + ]); +}); + + +it('Can do zero test for jump', () => { + run_code(0, [ + ['PUSH', 20], // start at 20 + ['PUSH', 1], // decrement by 1 + ['SUB'], + ['JZ', 5], // if we're at 0 jumps to the end + ['JUMP', 1] // the previous test fails so it jumps to loop again + ]); +}); + + +it('Can do NOT zero test for jump', () => { + run_code(-19, [ + ['PUSH', -20], // start at 20 + ['PUSH', 1], // decrement by 1 + ['ADD'], + ['JNZ', 5], // if we're at 0 jumps to the end + ['JUMP', 1] // the previous test fails so it jumps to loop again + ]); +}); + +it('Can store and restor', () => { + run_code(150, [ + ['PUSH', 100], // start with 100 + ['STOR', 'AX'], // put it in the regA register + ['PUSH', 50], // push 50 on too + ['ADD'], // add those for 150 + ['RSTOR', 'AX'],// recover the original 100 + ['SUB'] // sub and should be 150 + ]); +}); + +it('Halts on bad registers', () => { + run_code(0, [ + ['PUSH', 0], + ['STOR', 'AX'], + ['RSTOR', 'BAD NAME'], // should cause a halt here + ['PUSH', 100], + ['ADD'] + ]); +}); + +it('Can halt on purpose', () => { + let machine = run_code(0, [ + ['PUSH', 0], + ['HALT', 'Done on purpose.'] + ]); + + expect(machine.halted).toBe(true); + expect(machine.error).toBe('Done on purpose.'); +});