Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module.exports = {
"browser": true,
"es2021": true,
"mocha": true,
"request": true
"node": true
},
"extends": "eslint:recommended",
"overrides": [
Expand Down
15 changes: 11 additions & 4 deletions api/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ exports.calculate = function(req, res) {
'subtract': function(a, b) { return a - b },
'multiply': function(a, b) { return a * b },
'divide': function(a, b) { return a / b },
'modulo': function(a, b) { return a % b },
'sqrt': function(a) { return Math.sqrt(a) },
'power2': function(a) { return Math.pow(a, 2) },
};

if (!req.query.operation) {
Expand All @@ -29,14 +32,18 @@ exports.calculate = function(req, res) {
}

if (!req.query.operand1 ||
!req.query.operand1.match(/^(-)?[0-9\.]+(e(-)?[0-9]+)?$/) ||
!req.query.operand1.match(/^(-)?[0-9.]+(e(-)?[0-9]+)?$/) ||
req.query.operand1.replace(/[-0-9e]/g, '').length > 1) {
throw new Error("Invalid operand1: " + req.query.operand1);
}

if (!req.query.operand2 ||
!req.query.operand2.match(/^(-)?[0-9\.]+(e(-)?[0-9]+)?$/) ||
req.query.operand2.replace(/[-0-9e]/g, '').length > 1) {
// Some operations only require one operand
var unaryOperations = ['sqrt', 'power2'];
var requiresOperand2 = !unaryOperations.includes(req.query.operation);

if (requiresOperand2 && (!req.query.operand2 ||
!req.query.operand2.match(/^(-)?[0-9.]+(e(-)?[0-9]+)?$/) ||
req.query.operand2.replace(/[-0-9e]/g, '').length > 1)) {
throw new Error("Invalid operand2: " + req.query.operand2);
}

Expand Down
26 changes: 22 additions & 4 deletions public/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ function calculate(operand1, operand2, operation) {
case '/':
uri += "?operation=divide";
break;
case '%':
uri += "?operation=modulo";
break;
case '√':
uri += "?operation=sqrt";
break;
case '^2':
uri += "?operation=power2";
break;
default:
setError();
return;
Expand Down Expand Up @@ -111,9 +120,18 @@ function signPressed() {
}

function operationPressed(op) {
operand1 = getValue();
operation = op;
state = states.operator;
// Check if it's a unary operation
if (op === '√' || op === '^2') {
// For unary operations, calculate immediately
var currentValue = getValue();
calculate(currentValue, 0, op); // Pass 0 as dummy operand2
state = states.complete;
} else {
// Binary operation - store operand1 and wait for operand2
operand1 = getValue();
operation = op;
state = states.operator;
}
}

function equalPressed() {
Expand All @@ -138,7 +156,7 @@ document.addEventListener('keypress', (event) => {
numberPressed(event.key);
} else if (event.key == '.') {
decimalPressed();
} else if (event.key.match(/^[-*+/]$/)) {
} else if (event.key.match(/^[-*+/%]$/)) {
operationPressed(event.key);
} else if (event.key == '=') {
equalPressed();
Expand Down
7 changes: 4 additions & 3 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
<div class="box">
<div class="calculator">
<div class="calculator-buttons">
<button class="btn span-2"></button>
<button class="btn" onClick="clearPressed()">C</button>
<button class="btn" onClick="clearPressed()">CE</button>
<button class="btn" onClick="operationPressed('%')">%</button>
<button class="btn" onClick="operationPressed('√')">√</button>

<button class="btn" onClick="numberPressed(7)">7</button>
<button class="btn" onClick="numberPressed(8)">8</button>
Expand All @@ -37,10 +38,10 @@

<button class="btn" onClick="numberPressed(0)">0</button>
<button class="btn" onClick="decimalPressed()">.</button>
<button class="btn" onClick="operationPressed('^2')">x²</button>
<button class="btn" onClick="operationPressed('+')">+</button>
<button class="btn" onClick="equalPressed()">=</button>

<!-- TODO: Buttons -->
<button class="btn span-2" onClick="equalPressed()">=</button>
</div>
</div>
</div>
Expand Down
104 changes: 104 additions & 0 deletions test/arithmetic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,110 @@ describe('Arithmetic', function () {

// TODO: Challenge #1

describe('Modulo', function () {
it('calculates modulo of two positive integers', function (done) {
request.get('/arithmetic?operation=modulo&operand1=10&operand2=3')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 1 });
done();
});
});
it('calculates modulo with zero remainder', function (done) {
request.get('/arithmetic?operation=modulo&operand1=10&operand2=5')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 0 });
done();
});
});
it('calculates modulo of negative and positive integer', function (done) {
request.get('/arithmetic?operation=modulo&operand1=-10&operand2=3')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: -1 });
done();
});
});
it('calculates modulo with floating point numbers', function (done) {
request.get('/arithmetic?operation=modulo&operand1=5.5&operand2=2')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 1.5 });
done();
});
});
});

describe('Square Root', function () {
it('calculates square root of positive integer', function (done) {
request.get('/arithmetic?operation=sqrt&operand1=9')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 3 });
done();
});
});
it('calculates square root of zero', function (done) {
request.get('/arithmetic?operation=sqrt&operand1=0')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 0 });
done();
});
});
it('calculates square root of floating point number', function (done) {
request.get('/arithmetic?operation=sqrt&operand1=2.25')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 1.5 });
done();
});
});
it('calculates square root of large number', function (done) {
request.get('/arithmetic?operation=sqrt&operand1=100')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 10 });
done();
});
});
});

describe('Power of Two', function () {
it('calculates power of two for positive integer', function (done) {
request.get('/arithmetic?operation=power2&operand1=5')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 25 });
done();
});
});
it('calculates power of two for zero', function (done) {
request.get('/arithmetic?operation=power2&operand1=0')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 0 });
done();
});
});
it('calculates power of two for negative integer', function (done) {
request.get('/arithmetic?operation=power2&operand1=-3')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 9 });
done();
});
});
it('calculates power of two for floating point number', function (done) {
request.get('/arithmetic?operation=power2&operand1=2.5')
.expect(200)
.end(function (err, res) {
expect(res.body).to.eql({ result: 6.25 });
done();
});
});
});

describe('Multiplication', function () {
it('multiplies two positive integers', function (done) {
Expand Down