diff --git a/.eslintrc.js b/.eslintrc.js index 9e80f9a..8015305 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,7 +3,7 @@ module.exports = { "browser": true, "es2021": true, "mocha": true, - "request": true + "node": true }, "extends": "eslint:recommended", "overrides": [ diff --git a/api/controller.js b/api/controller.js index 949731c..6dea8e0 100644 --- a/api/controller.js +++ b/api/controller.js @@ -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) { @@ -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); } diff --git a/public/client.js b/public/client.js index 1c60f86..e78ff43 100644 --- a/public/client.js +++ b/public/client.js @@ -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; @@ -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() { @@ -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(); diff --git a/public/index.html b/public/index.html index 400c454..ec9bdd9 100644 --- a/public/index.html +++ b/public/index.html @@ -16,9 +16,10 @@
- + + @@ -37,10 +38,10 @@ + - - +
diff --git a/test/arithmetic.test.js b/test/arithmetic.test.js index deded48..1c44521 100644 --- a/test/arithmetic.test.js +++ b/test/arithmetic.test.js @@ -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) {