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) {