mirror of https://github.com/espruino/BangleApps
Fix App Calculator issues
- Javascript rounded float issues
- Reset after equals wasn't done properly
- Introduce unit tests 🤗
pull/323/head
parent
745e4d38a9
commit
aa168c3d5c
|
@ -1264,8 +1264,8 @@
|
||||||
"name": "Calculator",
|
"name": "Calculator",
|
||||||
"shortName":"Calculator",
|
"shortName":"Calculator",
|
||||||
"icon": "calculator.png",
|
"icon": "calculator.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "Basic calculator reminiscent of MacOs's one. Handy for small calculus. Push button1 and 3 to navigate up/down, tap right or left to navigate the sides, push button 2 to select.",
|
"description": "Basic calculator reminiscent of MacOs's one. Handy for small calculus.",
|
||||||
"tags": "app,tool",
|
"tags": "app,tool",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"calculator.app.js","url":"app.js"},
|
{"name":"calculator.app.js","url":"app.js"},
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
|
0.02: fix precision rounding issue + no reset when equals pressed
|
||||||
|
|
|
@ -144,19 +144,57 @@ function drawKey(name, k, selected) {
|
||||||
g.drawString(k.val || name, k.xy[0] + RIGHT_MARGIN + rMargin, k.xy[1] + BOTTOM_MARGIN + bMargin);
|
g.drawString(k.val || name, k.xy[0] + RIGHT_MARGIN + rMargin, k.xy[1] + BOTTOM_MARGIN + bMargin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getIntWithPrecision(x) {
|
||||||
|
var xStr = x.toString();
|
||||||
|
var xRadix = xStr.indexOf('.');
|
||||||
|
var xPrecision = xRadix === -1 ? 0 : xStr.length - xRadix - 1;
|
||||||
|
return {
|
||||||
|
num: Number(xStr.replace('.', '')),
|
||||||
|
p: xPrecision
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function multiply(x, y) {
|
||||||
|
var xNum = getIntWithPrecision(x);
|
||||||
|
var yNum = getIntWithPrecision(y);
|
||||||
|
return xNum.num * yNum.num / Math.pow(10, xNum.p + yNum.p);
|
||||||
|
}
|
||||||
|
|
||||||
|
function divide(x, y) {
|
||||||
|
var xNum = getIntWithPrecision(x);
|
||||||
|
var yNum = getIntWithPrecision(y);
|
||||||
|
return xNum.num / yNum.num / Math.pow(10, xNum.p - yNum.p);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sum(x, y) {
|
||||||
|
let xNum = getIntWithPrecision(x);
|
||||||
|
let yNum = getIntWithPrecision(y);
|
||||||
|
|
||||||
|
let diffPrecision = Math.abs(xNum.p - yNum.p);
|
||||||
|
if (diffPrecision > 0) {
|
||||||
|
if (xNum.p > yNum.p) {
|
||||||
|
yNum.num = yNum.num * Math.pow(10, diffPrecision);
|
||||||
|
} else {
|
||||||
|
xNum.num = xNum.num * Math.pow(10, diffPrecision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (xNum.num + yNum.num) / Math.pow(10, Math.max(xNum.p, yNum.p));
|
||||||
|
}
|
||||||
|
|
||||||
|
function subtract(x, y) {
|
||||||
|
return sum(x, -y);
|
||||||
|
}
|
||||||
|
|
||||||
function doMath(x, y, operator) {
|
function doMath(x, y, operator) {
|
||||||
// might not be a number due to display of dot "." algo
|
|
||||||
x = Number(x);
|
|
||||||
y = Number(y);
|
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
case '/':
|
case '/':
|
||||||
return x / y;
|
return divide(x, y);
|
||||||
case '*':
|
case '*':
|
||||||
return x * y;
|
return multiply(x, y);
|
||||||
case '+':
|
case '+':
|
||||||
return x + y;
|
return sum(x, y);
|
||||||
case '-':
|
case '-':
|
||||||
return x - y;
|
return subtract(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +242,7 @@ function displayOutput(num) {
|
||||||
}
|
}
|
||||||
|
|
||||||
len = (num + '').length;
|
len = (num + '').length;
|
||||||
if (numNumeric < 0) {
|
if (numNumeric < 0 || (numNumeric === 0 && 1/numNumeric === -Infinity)) {
|
||||||
// minus is not available in font 7x11Numeric7Seg, we use Vector
|
// minus is not available in font 7x11Numeric7Seg, we use Vector
|
||||||
g.setFont('Vector', 20);
|
g.setFont('Vector', 20);
|
||||||
g.drawString('-', 220 - (len * 15), 10);
|
g.drawString('-', 220 - (len * 15), 10);
|
||||||
|
@ -214,18 +252,33 @@ function displayOutput(num) {
|
||||||
}
|
}
|
||||||
g.drawString(num, 220 - (len * 15) + minusMarge, 10);
|
g.drawString(num, 220 - (len * 15) + minusMarge, 10);
|
||||||
}
|
}
|
||||||
|
var wasPressedEquals = false;
|
||||||
|
var hasPressedNumber = false;
|
||||||
function calculatorLogic(x) {
|
function calculatorLogic(x) {
|
||||||
if (hasPressedEquals) {
|
if (wasPressedEquals && hasPressedNumber !== false) {
|
||||||
currNumber = results;
|
|
||||||
prevNumber = null;
|
prevNumber = null;
|
||||||
operator = null;
|
currNumber = hasPressedNumber;
|
||||||
results = null;
|
wasPressedEquals = false;
|
||||||
isDecimal = null;
|
hasPressedNumber = false;
|
||||||
displayOutput(currNumber);
|
return;
|
||||||
hasPressedEquals = false;
|
|
||||||
}
|
}
|
||||||
if (prevNumber != null && currNumber != null && operator != null) {
|
if (hasPressedEquals) {
|
||||||
|
if (hasPressedNumber) {
|
||||||
|
prevNumber = null;
|
||||||
|
hasPressedNumber = false;
|
||||||
|
operator = null;
|
||||||
|
} else {
|
||||||
|
currNumber = null;
|
||||||
|
prevNumber = results;
|
||||||
|
}
|
||||||
|
hasPressedEquals = false;
|
||||||
|
wasPressedEquals = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currNumber == null && operator != null && '/*-+'.indexOf(x) !== -1) {
|
||||||
|
operator = x;
|
||||||
|
displayOutput(prevNumber);
|
||||||
|
} else if (prevNumber != null && currNumber != null && operator != null) {
|
||||||
// we execute the calculus only when there was a previous number entered before and an operator
|
// we execute the calculus only when there was a previous number entered before and an operator
|
||||||
results = doMath(prevNumber, currNumber, operator);
|
results = doMath(prevNumber, currNumber, operator);
|
||||||
operator = x;
|
operator = x;
|
||||||
|
@ -255,8 +308,10 @@ function buttonPress(val) {
|
||||||
operator = null;
|
operator = null;
|
||||||
} else {
|
} else {
|
||||||
keys.R.val = 'AC';
|
keys.R.val = 'AC';
|
||||||
drawKey('R', keys.R);
|
drawKey('R', keys.R, true);
|
||||||
}
|
}
|
||||||
|
wasPressedEquals = false;
|
||||||
|
hasPressedNumber = false;
|
||||||
displayOutput(0);
|
displayOutput(0);
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
|
@ -265,11 +320,12 @@ function buttonPress(val) {
|
||||||
} else if (currNumber != null) {
|
} else if (currNumber != null) {
|
||||||
displayOutput(currNumber /= 100);
|
displayOutput(currNumber /= 100);
|
||||||
}
|
}
|
||||||
|
hasPressedNumber = false;
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
if (results != null) {
|
if (results != null) {
|
||||||
displayOutput(results *= -1);
|
displayOutput(results *= -1);
|
||||||
} else if (currNumber != null) {
|
} else {
|
||||||
displayOutput(currNumber *= -1);
|
displayOutput(currNumber *= -1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -278,6 +334,7 @@ function buttonPress(val) {
|
||||||
case '-':
|
case '-':
|
||||||
case '+':
|
case '+':
|
||||||
calculatorLogic(val);
|
calculatorLogic(val);
|
||||||
|
hasPressedNumber = false;
|
||||||
break;
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
keys.R.val = 'C';
|
keys.R.val = 'C';
|
||||||
|
@ -290,18 +347,24 @@ function buttonPress(val) {
|
||||||
results = doMath(prevNumber, currNumber, operator);
|
results = doMath(prevNumber, currNumber, operator);
|
||||||
prevNumber = results;
|
prevNumber = results;
|
||||||
displayOutput(results);
|
displayOutput(results);
|
||||||
hasPressedEquals = true;
|
hasPressedEquals = 1;
|
||||||
}
|
}
|
||||||
|
hasPressedNumber = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
keys.R.val = 'C';
|
keys.R.val = 'C';
|
||||||
drawKey('R', keys.R);
|
drawKey('R', keys.R);
|
||||||
|
const is0Negative = (currNumber === 0 && 1/currNumber === -Infinity);
|
||||||
if (isDecimal) {
|
if (isDecimal) {
|
||||||
currNumber = currNumber == null ? 0 + '.' + val : currNumber + '.' + val;
|
currNumber = currNumber == null || hasPressedEquals === 1 ? 0 + '.' + val : currNumber + '.' + val;
|
||||||
isDecimal = false;
|
isDecimal = false;
|
||||||
} else {
|
} else {
|
||||||
currNumber = currNumber == null ? val : currNumber + val;
|
currNumber = currNumber == null || hasPressedEquals === 1 ? val : (is0Negative ? '-' + val : currNumber + val);
|
||||||
}
|
}
|
||||||
|
if (hasPressedEquals === 1) {
|
||||||
|
hasPressedEquals = 2;
|
||||||
|
}
|
||||||
|
hasPressedNumber = currNumber;
|
||||||
displayOutput(currNumber);
|
displayOutput(currNumber);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -315,38 +378,15 @@ for (var k in keys) {
|
||||||
g.setFont('7x11Numeric7Seg', 2.8);
|
g.setFont('7x11Numeric7Seg', 2.8);
|
||||||
g.drawString('0', 205, 10);
|
g.drawString('0', 205, 10);
|
||||||
|
|
||||||
|
function moveDirection(d) {
|
||||||
setWatch(function() {
|
|
||||||
drawKey(selected, keys[selected]);
|
|
||||||
// key 0 is 2 keys wide, go up to 1 if it was previously selected
|
|
||||||
if (selected == '0' && prevSelected === '1') {
|
|
||||||
prevSelected = selected;
|
|
||||||
selected = '1';
|
|
||||||
} else {
|
|
||||||
prevSelected = selected;
|
|
||||||
selected = keys[selected].trbl[0];
|
|
||||||
}
|
|
||||||
drawKey(selected, keys[selected], true);
|
|
||||||
}, BTN1, {repeat: true, debounce: 100});
|
|
||||||
|
|
||||||
setWatch(function() {
|
|
||||||
drawKey(selected, keys[selected]);
|
drawKey(selected, keys[selected]);
|
||||||
prevSelected = selected;
|
prevSelected = selected;
|
||||||
selected = keys[selected].trbl[2];
|
selected = (d === 0 && selected == '0' && prevSelected === '1') ? '1' : keys[selected].trbl[d];
|
||||||
drawKey(selected, keys[selected], true);
|
drawKey(selected, keys[selected], true);
|
||||||
}, BTN3, {repeat: true, debounce: 100});
|
}
|
||||||
|
|
||||||
Bangle.on('touch', function(direction) {
|
setWatch(_ => moveDirection(0), BTN1, {repeat: true, debounce: 100});
|
||||||
drawKey(selected, keys[selected]);
|
setWatch(_ => moveDirection(2), BTN3, {repeat: true, debounce: 100});
|
||||||
prevSelected = selected;
|
setWatch(_ => moveDirection(3), BTN4, {repeat: true, debounce: 100});
|
||||||
if (direction == 1) {
|
setWatch(_ => moveDirection(1), BTN5, {repeat: true, debounce: 100});
|
||||||
selected = keys[selected].trbl[3];
|
setWatch(_ => buttonPress(selected), BTN2, {repeat: true, debounce: 100});
|
||||||
} else if (direction == 2) {
|
|
||||||
selected = keys[selected].trbl[1];
|
|
||||||
}
|
|
||||||
drawKey(selected, keys[selected], true);
|
|
||||||
});
|
|
||||||
|
|
||||||
setWatch(function() {
|
|
||||||
buttonPress(selected);
|
|
||||||
}, BTN2, {repeat: true, debounce: 100});
|
|
||||||
|
|
|
@ -0,0 +1,273 @@
|
||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Calculator tests</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/7.1.0/mocha.min.css">
|
||||||
|
<style>
|
||||||
|
#header {
|
||||||
|
margin: 60px 50px;
|
||||||
|
font: 1em "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||||
|
font-weight: 200;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="header"></div>
|
||||||
|
<div id="mocha"></div>
|
||||||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mocha/7.1.0/mocha.min.js"></script>
|
||||||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.min.js"></script>
|
||||||
|
<script>
|
||||||
|
// mocks
|
||||||
|
const _ = () => {}
|
||||||
|
setWatch = _
|
||||||
|
drawKey = _
|
||||||
|
currentOutput = 0;
|
||||||
|
g = {
|
||||||
|
setFont: _,
|
||||||
|
drawString: n => currentOutput = n,
|
||||||
|
setColor: _,
|
||||||
|
fillRect: _,
|
||||||
|
clear: _
|
||||||
|
}
|
||||||
|
_graphics = function () {
|
||||||
|
this.setFontCustom = _
|
||||||
|
}
|
||||||
|
Graphics = _graphics
|
||||||
|
BTN1 = 1
|
||||||
|
BTN2 = 2
|
||||||
|
BTN3 = 3
|
||||||
|
BTN4 = 4
|
||||||
|
BTN5 = 5
|
||||||
|
Bangle = {
|
||||||
|
on: _
|
||||||
|
}
|
||||||
|
Terminal = { println: console.log }
|
||||||
|
</script>
|
||||||
|
<script src="app.js"></script>
|
||||||
|
<script>
|
||||||
|
header`
|
||||||
|
// Unit tests for the BangleJS's Calculator app
|
||||||
|
`
|
||||||
|
|
||||||
|
mocha.setup({ui:'bdd'})
|
||||||
|
chai.should()
|
||||||
|
var expect = chai.expect
|
||||||
|
|
||||||
|
const sequencePress = x => x.split('').forEach(y => buttonPress(y))
|
||||||
|
const sequenceReset = _ => [...Array(2)].forEach(x => buttonPress('R'))
|
||||||
|
|
||||||
|
describe("Simple arithmetic", function(){
|
||||||
|
it("multiplication", function(){
|
||||||
|
multiply(1.4,2.4).should.equal(3.36)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("division", function(){
|
||||||
|
divide(4.4,2).should.equal(2.2)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("sum", function(){
|
||||||
|
sum(4.1,2).should.equal(6.1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("subtract", function(){
|
||||||
|
subtract(4.1,2).should.equal(2.1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("Simple Operation with Reset", function(){
|
||||||
|
|
||||||
|
it("Simple addition", function(){
|
||||||
|
sequencePress("50+3=")
|
||||||
|
currentOutput.should.equal(53)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Reset output 'C' then 'AC'", function(){
|
||||||
|
sequenceReset()
|
||||||
|
currentOutput.should.equal(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Complex calculus", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("3*3+3-2/2=")
|
||||||
|
currentOutput.should.equal(5)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Change operator", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("3*+/3=")
|
||||||
|
currentOutput.should.equal(1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("Operations on Double-s", function(){
|
||||||
|
|
||||||
|
it("Simple addition", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("1.3+1.7=")
|
||||||
|
currentOutput.should.equal(3)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("some calculation", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("1.3+1.7*2.22/2=")
|
||||||
|
currentOutput.should.equal(3.33)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("No corrupt opposed to what javascript Number would", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("1.3+1.7*2.2/2=")
|
||||||
|
currentOutput.should.equal(3.3)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Complex calcul", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("48/.2/")
|
||||||
|
currentOutput.should.equal(240)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("Negative Operations", function(){
|
||||||
|
|
||||||
|
it("Negative on first number", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("50N+3=")
|
||||||
|
currentOutput.should.equal(-47)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Substract negative", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("50N-3=")
|
||||||
|
currentOutput.should.equal(-53)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Negative before number is typed", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("N50-3=")
|
||||||
|
currentOutput.should.equal(-53)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Negative addition on second number", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("50-N33=")
|
||||||
|
currentOutput.should.equal(83)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Negative zero", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("N")
|
||||||
|
currentOutput.should.equal(-0)
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("0N")
|
||||||
|
currentOutput.should.equal(-0)
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("N0")
|
||||||
|
currentOutput.should.equal('-0')
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("0N")
|
||||||
|
currentOutput.should.equal(-0)
|
||||||
|
sequencePress("N0")
|
||||||
|
currentOutput.should.equal('0')
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
describe("Zero division", function(){
|
||||||
|
|
||||||
|
it("Divide 0 by 0", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("0/0=")
|
||||||
|
currentOutput.should.equal('NOT A NUMBER')
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Divde N by 0", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("1/0=")
|
||||||
|
currentOutput.should.equal('INFINITY')
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Divde -N by 0", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("N1/0=")
|
||||||
|
currentOutput.should.equal('-INFINITY')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("Press equals '='", function(){
|
||||||
|
|
||||||
|
it("should display result when new operation button is pressed", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("5+6+")
|
||||||
|
currentOutput.should.equal(11)
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("5-6*4/2/")
|
||||||
|
currentOutput.should.equal(-2)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("New operation after '='", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("5+4=5")
|
||||||
|
currentOutput.should.equal('5')
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("N5+4*3-3/-1=5")
|
||||||
|
currentOutput.should.equal('5')
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Double '=' repeats last operation", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("2+2==")
|
||||||
|
currentOutput.should.equal(6)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("New operation applied to calculated result", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("9*9=*9=")
|
||||||
|
currentOutput.should.equal(729)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Turn result negative, do addition", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("9*9=N+1=")
|
||||||
|
currentOutput.should.equal(-80)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("New operation after '=' dissociated from previous one", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("9*9=9*")
|
||||||
|
currentOutput.should.equal('9')
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("9*9=99+1=*2=")
|
||||||
|
currentOutput.should.equal(200)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("Memory", function(){
|
||||||
|
|
||||||
|
it("Reset 1st number with 'C'", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("50R3+6=")
|
||||||
|
currentOutput.should.equal(9)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Reset 2nd number with 'C'", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("50+3R+6=")
|
||||||
|
currentOutput.should.equal(56)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Complex calcul", function(){
|
||||||
|
sequenceReset()
|
||||||
|
sequencePress("/3*3+3R-+2/2=")
|
||||||
|
currentOutput.should.equal(5.5)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mocha.run()
|
||||||
|
function header(str) { document.getElementById('header').innerHTML = str[0].replace(/\n/, '').replace(/\n/g, '<br>') }
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue