Skip to content
This repository was archived by the owner on Feb 10, 2024. It is now read-only.
Open
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
26 changes: 26 additions & 0 deletions __tests__/script.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const { describe, test, expect } = require("@jest/globals");
const { isNullOrEmptyInput, countOperators, checkConsecutive } = require("../scripts/validator");

describe("check input", () => {
test("check for empty or null input", () => {
const input = "";

expect(isNullOrEmptyInput(input)).toBe(true);
});

test("check number of math operators", () => {
const inputs = ["50+10+20"];

expect(countOperators(inputs[0])).toBe(2);
});

test("check consecutive math operators", () => {
const inputs = ["--50", "50--", "50***", "//50", "1+50"];

expect(checkConsecutive(inputs[0])).toBe(2);
expect(checkConsecutive(inputs[1])).toBe(2);
expect(checkConsecutive(inputs[2])).toBe(3);
expect(checkConsecutive(inputs[3])).toBe(2);
expect(checkConsecutive(inputs[4])).toBe(1);
});
});
16 changes: 16 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "Calculator",
"version": "1.0.0",
"description": "Calculator app",
"main": "index.js",
"repository": "https://github.com/zxcodes/Calculator.git",
"author": "Mohammed Farmaan <farmaanghouse6@gmail.com>",
"license": "MIT",
"dependencies": {},
"devDependencies": {
"jest": "^29.7.0"
},
"scripts": {
"test": "jest tests"
}
}
214 changes: 131 additions & 83 deletions scripts/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,102 +7,150 @@ const res = document.getElementById("result");
const toast = document.getElementById("toast");

function calculate(value) {
const calculatedValue = eval(value || null);
if (isNaN(calculatedValue)) {
res.value = "Can't divide 0 with 0";
setTimeout(() => {
res.value = "";
}, 1300);
} else {
res.value = calculatedValue;
}
if (checkConsecutive(value) > 1) {
alert("invalid expression");
return;
}

const calculatedValue = eval(value || null);
if (isNaN(calculatedValue)) {
res.value = "Can't divide 0 with 0";
setTimeout(() => {
res.value = "";
}, 1300);
} else {
res.value = calculatedValue;
}
}

// Swaps the stylesheet to achieve dark mode.
function changeTheme() {
const theme = document.getElementById("theme");
setTimeout(() => {
toast.innerHTML = "Calculator";
}, 1500);
if (theme.getAttribute("href") === lightTheme) {
theme.setAttribute("href", darkTheme);
themeIcon.setAttribute("src", sunIcon);
toast.innerHTML = "Dark Mode 🌙";
} else {
theme.setAttribute("href", lightTheme);
themeIcon.setAttribute("src", moonIcon);
toast.innerHTML = "Light Mode ☀️";
}
const theme = document.getElementById("theme");
setTimeout(() => {
toast.innerHTML = "Calculator";
}, 1500);
if (theme.getAttribute("href") === lightTheme) {
theme.setAttribute("href", darkTheme);
themeIcon.setAttribute("src", sunIcon);
toast.innerHTML = "Dark Mode 🌙";
} else {
theme.setAttribute("href", lightTheme);
themeIcon.setAttribute("src", moonIcon);
toast.innerHTML = "Light Mode ☀️";
}
}

// Displays entered value on screen.
function liveScreen(enteredValue) {
if (!res.value) {
res.value = "";
}
res.value += enteredValue;
if (!res.value) {
res.value = "";
}
res.value += enteredValue;
}

//adding event handler on the document to handle keyboard inputs
document.addEventListener("keydown", keyboardInputHandler);

//function to handle keyboard inputs
function keyboardInputHandler(e) {
// to fix the default behavior of browser,
// enter and backspace were causing undesired behavior when some key was already in focus.
e.preventDefault();
//grabbing the liveScreen

//numbers
if (e.key === "0") {
res.value += "0";
} else if (e.key === "1") {
res.value += "1";
} else if (e.key === "2") {
res.value += "2";
} else if (e.key === "3") {
res.value += "3";
} else if (e.key === "4") {
res.value += "4";
} else if (e.key === "5") {
res.value += "5";
} else if (e.key === "6") {
res.value += "6";
} else if (e.key === "7") {
res.value += "7";
} else if (e.key === "7") {
res.value += "7";
} else if (e.key === "8") {
res.value += "8";
} else if (e.key === "9") {
res.value += "9";
}

//operators
if (e.key === "+") {
res.value += "+";
} else if (e.key === "-") {
res.value += "-";
} else if (e.key === "*") {
res.value += "*";
} else if (e.key === "/") {
res.value += "/";
}

//decimal key
if (e.key === ".") {
res.value += ".";
}

//press enter to see result
if (e.key === "Enter") {
calculate(result.value);
}

//backspace for removing the last input
if (e.key === "Backspace") {
const resultInput = res.value;
//remove the last element in the string
res.value = resultInput.substring(0, res.value.length - 1);
}
// to fix the default behavior of browser,
// enter and backspace were causing undesired behavior when some key was already in focus.
e.preventDefault();
//grabbing the liveScreen

//numbers
if (e.key === "0") {
res.value += "0";
} else if (e.key === "1") {
res.value += "1";
} else if (e.key === "2") {
res.value += "2";
} else if (e.key === "3") {
res.value += "3";
} else if (e.key === "4") {
res.value += "4";
} else if (e.key === "5") {
res.value += "5";
} else if (e.key === "6") {
res.value += "6";
} else if (e.key === "7") {
res.value += "7";
} else if (e.key === "7") {
res.value += "7";
} else if (e.key === "8") {
res.value += "8";
} else if (e.key === "9") {
res.value += "9";
}

//operators
if (e.key === "+") {
res.value += "+";
} else if (e.key === "-") {
res.value += "-";
} else if (e.key === "*") {
res.value += "*";
} else if (e.key === "/") {
res.value += "/";
}

//decimal key
if (e.key === ".") {
res.value += ".";
}

//press enter to see result
if (e.key === "Enter") {
calculate(result.value);
}

//backspace for removing the last input
if (e.key === "Backspace") {
const resultInput = res.value;
//remove the last element in the string
res.value = resultInput.substring(0, res.value.length - 1);
}
}

function isNullOrEmptyInput(input) {
if (input.length == 0 || input == null) {
return true;
}

return false;
}

function countOperators(input) {
let count = 0;
let operator = "+";

for (let i = 0; i < input.length; i++) {
if (input[i] == operator) {
count++;
}
}

return count;
}

function checkConsecutive(input) {
let operators = ["+", "-", "*", "/"];
let count = 0;
let countCurrent = 0;
let counts = [];

operators.forEach((element) => {
for (let i = 0; i < input.length; i++) {
if (input[i] === element) {
countCurrent++;
count = Math.max(count, countCurrent);
} else {
countCurrent = 0;
}
}

counts.push(count);
});

return Math.max(...counts);
}
44 changes: 44 additions & 0 deletions scripts/validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
function isNullOrEmptyInput(input) {
if (input.length == 0 || input == null) {
return true;
}

return false;
}

function countOperators(input) {
let count = 0;
let operator = "+";

for (let i = 0; i < input.length; i++) {
if (input[i] == operator) {
count++;
}
}

return count;
}

function checkConsecutive(input) {
let operators = ["+", "-", "*", "/"];
let count = 0;
let countCurrent = 0;
let counts = [];

operators.forEach((element) => {
for (let i = 0; i < input.length; i++) {
if (input[i] === element) {
countCurrent++;
count = Math.max(count, countCurrent);
} else {
countCurrent = 0;
}
}

counts.push(count);
});

return Math.max(...counts);
}

module.exports = { isNullOrEmptyInput, countOperators, checkConsecutive };
Loading