From 4a099f893af01648b7dbed6b6c092a42c05cf42c Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Mon, 5 Jan 2026 12:49:34 +0100 Subject: [PATCH 01/18] add jest test --- challenges/unit-testing/package-lock.json | 175 +++++----------------- 1 file changed, 41 insertions(+), 134 deletions(-) diff --git a/challenges/unit-testing/package-lock.json b/challenges/unit-testing/package-lock.json index 55d5bc6c..2008dd37 100644 --- a/challenges/unit-testing/package-lock.json +++ b/challenges/unit-testing/package-lock.json @@ -27,14 +27,15 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.9.tgz", - "integrity": "sha512-z88xeGxnzehn2sqZ8UdGQEvYErF1odv2CftxInpSYJt6uHuPe9YjahKZITGs3l5LeI9d2ROG+obuDAoSlqbNfQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.25.9", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" @@ -172,9 +173,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { @@ -182,9 +183,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -202,121 +203,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.9.tgz", - "integrity": "sha512-oKWp3+usOJSzDZOucZUAMayhPz/xVjzymyDzUN8dk0Wd3RWMlGLXi07UCQ/CgQVb8LvXx3XBajJH4XGgkt7H7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", - "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.9.tgz", - "integrity": "sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.25.9" + "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" @@ -565,15 +472,15 @@ } }, "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -599,14 +506,14 @@ } }, "node_modules/@babel/types": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.9.tgz", - "integrity": "sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -1324,9 +1231,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -1578,9 +1485,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -2784,9 +2691,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { From 308c299a7f7b31ad6d4e68b719b78c72812860d7 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Mon, 5 Jan 2026 12:50:06 +0100 Subject: [PATCH 02/18] implement function add and exports file --- .../katas-tdd/calculator/script.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 challenges/unit-testing/katas-tdd/calculator/script.js diff --git a/challenges/unit-testing/katas-tdd/calculator/script.js b/challenges/unit-testing/katas-tdd/calculator/script.js new file mode 100644 index 00000000..6159796f --- /dev/null +++ b/challenges/unit-testing/katas-tdd/calculator/script.js @@ -0,0 +1,22 @@ +function add(numbers) { + if (numbers === "") { + return 0; + } + const negatives = []; + const sum = numbers.split(',').reduce((sum, num) => { + const number = parseInt(num); + if (number < 0) { + negatives.push(number); + } else if (number <= 1000) { + sum += number; + } + return sum; + }, 0); + + if (negatives.length > 0) { + throw new Error(`negatives not allowed: ${negatives.join(", ")}`); + } + + return sum; +} +module.exports = add; From 972e283583544a9d966f7ee58a833a796d151086 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Mon, 5 Jan 2026 12:50:22 +0100 Subject: [PATCH 03/18] implement test cases and export file --- .../unit-testing/katas-tdd/calculator/test.js | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 challenges/unit-testing/katas-tdd/calculator/test.js diff --git a/challenges/unit-testing/katas-tdd/calculator/test.js b/challenges/unit-testing/katas-tdd/calculator/test.js new file mode 100644 index 00000000..8477c08b --- /dev/null +++ b/challenges/unit-testing/katas-tdd/calculator/test.js @@ -0,0 +1,27 @@ +const add = require('./script'); + +test("empty string returns 0", () => { + expect(add("")).toBe(0); +}); + +test("single number returns the number", () => { + expect(add("5")).toBe(5); +}); + +test("two numbers return their sum", () => { + expect(add("3,6")).toBe(9); +}); + +test("multiple numbers return their sum", () => { + expect(add("1,2,3,4")).toBe(10); // 1+2+3+4 = 10 +}); + +test("numbers greater than 1000 are ignored", () => { + expect(add("2,1001")).toBe(2); // 1001 is ignored + expect(add("1000,1001")).toBe(1000); // 1001 is ignored +}); + +test("negative numbers throw an error", () => { + expect(() => add("1,4,-1")).toThrow("negatives not allowed: -1"); + expect(() => add("-1,-2,-3")).toThrow("negatives not allowed: -1, -2, -3"); +}); From 462f5978d43859bebb77072392ac14ed02514595 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Mon, 5 Jan 2026 12:51:44 +0100 Subject: [PATCH 04/18] rename test file --- .../katas-tdd/calculator/add.test.js | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 challenges/unit-testing/katas-tdd/calculator/add.test.js diff --git a/challenges/unit-testing/katas-tdd/calculator/add.test.js b/challenges/unit-testing/katas-tdd/calculator/add.test.js new file mode 100644 index 00000000..8477c08b --- /dev/null +++ b/challenges/unit-testing/katas-tdd/calculator/add.test.js @@ -0,0 +1,27 @@ +const add = require('./script'); + +test("empty string returns 0", () => { + expect(add("")).toBe(0); +}); + +test("single number returns the number", () => { + expect(add("5")).toBe(5); +}); + +test("two numbers return their sum", () => { + expect(add("3,6")).toBe(9); +}); + +test("multiple numbers return their sum", () => { + expect(add("1,2,3,4")).toBe(10); // 1+2+3+4 = 10 +}); + +test("numbers greater than 1000 are ignored", () => { + expect(add("2,1001")).toBe(2); // 1001 is ignored + expect(add("1000,1001")).toBe(1000); // 1001 is ignored +}); + +test("negative numbers throw an error", () => { + expect(() => add("1,4,-1")).toThrow("negatives not allowed: -1"); + expect(() => add("-1,-2,-3")).toThrow("negatives not allowed: -1, -2, -3"); +}); From c4b6fe30102ad58f968da76146bca7a8664cf7e7 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Mon, 5 Jan 2026 13:39:12 +0100 Subject: [PATCH 05/18] create Test --- .../password-verifier/passverifier.test.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 challenges/unit-testing/katas-tdd/password-verifier/passverifier.test.js diff --git a/challenges/unit-testing/katas-tdd/password-verifier/passverifier.test.js b/challenges/unit-testing/katas-tdd/password-verifier/passverifier.test.js new file mode 100644 index 00000000..0891a3e1 --- /dev/null +++ b/challenges/unit-testing/katas-tdd/password-verifier/passverifier.test.js @@ -0,0 +1,20 @@ +const verify = require('./script'); +test('password should be rejected if it is less than 8 characters', () => { + expect(verify('short')).toBe('Password rejected'); +}); + +test('password should be rejected if it is null', () => { + expect(verify(null)).toBe('Password rejected'); +}); + +test('password should be rejected if it has no uppercase letter', () => { + expect(verify('password1')).toBe('Password rejected'); +}); + +test('password should be rejected if it has no number', () => { + expect(verify('Password')).toBe('Password rejected'); +}); + +test('password should be accepted if it has at least 8 characters, 1 uppercase letter, and 1 number', () => { + expect(verify('Password1')).toBe('Password accepted'); +}); From 7a0d14d78d11e8571072ad7efe6b1719a68840ce Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Mon, 5 Jan 2026 13:39:56 +0100 Subject: [PATCH 06/18] implement a function verify --- .../katas-tdd/password-verifier/script.js | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 challenges/unit-testing/katas-tdd/password-verifier/script.js diff --git a/challenges/unit-testing/katas-tdd/password-verifier/script.js b/challenges/unit-testing/katas-tdd/password-verifier/script.js new file mode 100644 index 00000000..24ec4359 --- /dev/null +++ b/challenges/unit-testing/katas-tdd/password-verifier/script.js @@ -0,0 +1,37 @@ +function verify(password) { + + if (password === null || password.length < 8) { + return 'Password rejected'; + } + + + let hasUppercase = false; + for (let i = 0; i < password.length; i++) { + if (password[i] === password[i].toUpperCase() && /[A-Za-z]/.test(password[i])) { + hasUppercase = true; + break; + } + } + + if (!hasUppercase) { + return 'Password rejected'; + } + + + let hasNumber = false; + for (let i = 0; i < password.length; i++) { + if (/[0-9]/.test(password[i])) { + hasNumber = true; + break; + } + } + + if (!hasNumber) { + return 'Password rejected'; + } + + + return 'Password accepted'; +} + +module.exports = verify; From 6339de9c7d2b9b71347fb16831d18a2b90fa21f3 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Mon, 5 Jan 2026 17:25:25 +0100 Subject: [PATCH 07/18] add function for newroman numerals --- .../roman-numerals/convert-to-new-roman.js | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-new-roman.js b/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-new-roman.js index 0f2fe4b5..5173800b 100644 --- a/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-new-roman.js +++ b/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-new-roman.js @@ -1,3 +1,31 @@ -function convertToNewRoman(n) {} +function convertToNewRoman(n) { + let result = ""; + + + const romanNumerals = [ + { value: 1000, symbol: "M" }, + { value: 900, symbol: "CM" }, + { value: 500, symbol: "D" }, + { value: 400, symbol: "CD" }, + { value: 100, symbol: "C" }, + { value: 90, symbol: "XC" }, + { value: 50, symbol: "L" }, + { value: 40, symbol: "XL" }, + { value: 10, symbol: "X" }, + { value: 9, symbol: "IX" }, + { value: 5, symbol: "V" }, + { value: 4, symbol: "IV" }, + { value: 1, symbol: "I" } + ]; + + for (let i = 0; i < romanNumerals.length; i++) { + while (n >= romanNumerals[i].value) { + result += romanNumerals[i].symbol; + n -= romanNumerals[i].value; + } + } + + return result; +} module.exports = convertToNewRoman; From d580313dbd69e4f871c3f458526009d1b422d2fd Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Mon, 5 Jan 2026 17:25:54 +0100 Subject: [PATCH 08/18] add test cases for new roman numerals --- .../convert-to-new-roman.test.js | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-new-roman.test.js b/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-new-roman.test.js index ae49f737..f3b2f19a 100644 --- a/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-new-roman.test.js +++ b/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-new-roman.test.js @@ -1,7 +1,29 @@ let convertToNewRoman = require("./convert-to-new-roman"); test("returns I if passed 1 as an argument", function () { - // Arrange - // Act - // Assert + expect(convertToNewRoman(1)).toBe("I"); +}); + +test("returns IV if passed 4 as an argument", function () { + expect(convertToNewRoman(4)).toBe("IV"); +}); + +test("returns IX if passed 9 as an argument", function () { + expect(convertToNewRoman(9)).toBe("IX"); +}); + +test("returns XIV if passed 14 as an argument", function () { + expect(convertToNewRoman(14)).toBe("XIV"); +}); + +test("returns XLIV if passed 44 as an argument", function () { + expect(convertToNewRoman(44)).toBe("XLIV"); +}); + +test("returns XCIX if passed 99 as an argument", function () { + expect(convertToNewRoman(99)).toBe("XCIX"); +}); + +test("returns CMXLIV if passed 944 as an argument", function () { + expect(convertToNewRoman(944)).toBe("CMXLIV"); }); From 442c7a0958ace0067ac9a444faaf336948ddcc6e Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Mon, 5 Jan 2026 17:26:08 +0100 Subject: [PATCH 09/18] add function for old roman numerals --- .../roman-numerals/convert-to-old-roman.js | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-old-roman.js b/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-old-roman.js index f7f0d06d..eb462a8b 100644 --- a/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-old-roman.js +++ b/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-old-roman.js @@ -1,3 +1,26 @@ -function convertToOldRoman(n) {} +function convertToOldRoman(n) { + let result = ""; + + + const romanNumerals = [ + { value: 1000, symbol: "M" }, + { value: 500, symbol: "D" }, + { value: 100, symbol: "C" }, + { value: 50, symbol: "L" }, + { value: 10, symbol: "X" }, + { value: 5, symbol: "V" }, + { value: 1, symbol: "I" } + ]; + + + for (let i = 0; i < romanNumerals.length; i++) { + while (n >= romanNumerals[i].value) { + result += romanNumerals[i].symbol; + n -= romanNumerals[i].value; + } + } + + return result; +} module.exports = convertToOldRoman; From 7f5456f59f659783aaa3bc329a8eee55994de61d Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Mon, 5 Jan 2026 17:26:21 +0100 Subject: [PATCH 10/18] add test cases for old roman numeral --- .../convert-to-old-roman.test.js | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-old-roman.test.js b/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-old-roman.test.js index b9a43869..eb189829 100644 --- a/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-old-roman.test.js +++ b/challenges/unit-testing/katas-tdd/roman-numerals/convert-to-old-roman.test.js @@ -1,7 +1,26 @@ let convertToOldRoman = require("./convert-to-old-roman"); test("returns I if passed 1 as an argument", function () { - // Arrange - // Act - // Assert + expect(convertToOldRoman(1)).toBe("I"); +}); + +test("returns III if passed 3 as an argument", function () { + expect(convertToOldRoman(3)).toBe("III"); +}); + +test("returns VII if passed 7 as an argument", function () { + expect(convertToOldRoman(7)).toBe("VII"); +}); + +test("returns XV if passed 15 as an argument", function () { + expect(convertToOldRoman(15)).toBe("XV"); +}); + +test("returns XVIII if passed 18 as an argument", function () { + expect(convertToOldRoman(18)).toBe("XVIII"); +}); + + +test("returns XXII if passed 22 as an argument", function () { + expect(convertToOldRoman(22)).toBe("XXII"); }); From f51a7f742df5d219e0e7325d5e9132938efa7854 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Fri, 9 Jan 2026 19:27:54 +0100 Subject: [PATCH 11/18] populate function --- .../passing-tests/car-sales/car-sales.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/challenges/unit-testing/passing-tests/car-sales/car-sales.js b/challenges/unit-testing/passing-tests/car-sales/car-sales.js index e8bb8511..ff5f552a 100644 --- a/challenges/unit-testing/passing-tests/car-sales/car-sales.js +++ b/challenges/unit-testing/passing-tests/car-sales/car-sales.js @@ -1,3 +1,19 @@ -function sales(carsSold) {} +function sales(carsSold) { + + let totals = {}; + + carsSold.forEach(car => { + + if (totals[car.make]) { + totals[car.make] += car.price; + } else { + + totals[car.make] = car.price; + } + }); + + return totals; +} + module.exports = sales; From 9755d3f326e9ce3106f0827d1a790db2c2e49334 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Fri, 9 Jan 2026 19:28:29 +0100 Subject: [PATCH 12/18] populate the funtion --- .../passing-tests/factorial/factorial.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/challenges/unit-testing/passing-tests/factorial/factorial.js b/challenges/unit-testing/passing-tests/factorial/factorial.js index fefa4368..49ff5a2c 100644 --- a/challenges/unit-testing/passing-tests/factorial/factorial.js +++ b/challenges/unit-testing/passing-tests/factorial/factorial.js @@ -8,6 +8,18 @@ // calculate and return the factorial of int // note: factorial of 0 is 1 -function factorial(int) {} +function factorial(int) { + if (int === 0) { + return 1; + } + + let result = 1; + for (let i = 1; i <= int; i++) { + result *= i; + } + + return result; +} + module.exports = factorial; From 571e819681165dd93166e02566637af1c2beaa2b Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Fri, 9 Jan 2026 19:29:03 +0100 Subject: [PATCH 13/18] populate the function --- .../passing-tests/get-average/get-average.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/challenges/unit-testing/passing-tests/get-average/get-average.js b/challenges/unit-testing/passing-tests/get-average/get-average.js index b5588a57..d1aff6d8 100644 --- a/challenges/unit-testing/passing-tests/get-average/get-average.js +++ b/challenges/unit-testing/passing-tests/get-average/get-average.js @@ -2,6 +2,18 @@ // return the average of all the numbers // be sure to exclude the strings -function average(numbers) {} +function average(numbers) { + + const numericValues = numbers.filter(item => typeof item === 'number'); + + if (numericValues.length === 0) return 0; + + + const sum = numericValues.reduce((total, num) => total + num, 0); + + return sum / numericValues.length; +} + + module.exports = average; From 9e8cbb4c205dcfd86928910b5b659dc91e6fb3d2 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Fri, 9 Jan 2026 19:29:18 +0100 Subject: [PATCH 14/18] implement test cases --- .../writing-tests/largest-number/largest-number.test.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/challenges/unit-testing/writing-tests/largest-number/largest-number.test.js b/challenges/unit-testing/writing-tests/largest-number/largest-number.test.js index ce674209..14c165e5 100644 --- a/challenges/unit-testing/writing-tests/largest-number/largest-number.test.js +++ b/challenges/unit-testing/writing-tests/largest-number/largest-number.test.js @@ -1,9 +1,16 @@ let getLargestNumber = require("./largest-number"); -test("returns largest number in array", function () { +test("returns largest number in array and checks original array is unchanged", function () { // Arrange + const numbers = [3, 21, 88, 4, 36]; + const expected = 88; + const originalArray = [...numbers]; // Act + const result = getLargestNumber(numbers); + // Assert + expect(result).toEqual(expected); + expect(numbers).toEqual(originalArray); }); // example From 16c452fe92f01751f01edbb84b3660a2fc657c75 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Fri, 9 Jan 2026 19:30:33 +0100 Subject: [PATCH 15/18] import the function --- .../writing-tests/remove-vowels/remove-vowels-in-array.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels-in-array.js b/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels-in-array.js index 6f4e06bf..d42d90c4 100644 --- a/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels-in-array.js +++ b/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels-in-array.js @@ -1,5 +1,4 @@ -let removeVowels = require("./remove-vowels"); - +let removeVowels = require("./remove-vowels"); function removeVowelsFromWords(words) { let result = words.map(function (word) { return removeVowels(word); From ea17ea879efc16c669a5a8f31a4517bb8d677272 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Fri, 9 Jan 2026 19:30:56 +0100 Subject: [PATCH 16/18] implement test cases --- .../remove-vowels-in-array.test.js | 81 ++++++++++++++++++- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels-in-array.test.js b/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels-in-array.test.js index ee739e22..d5cd1ff8 100644 --- a/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels-in-array.test.js +++ b/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels-in-array.test.js @@ -1,11 +1,84 @@ let removeVowelsFromWords = require("./remove-vowels-in-array"); +let removeVowels = require("./remove-vowels"); -test("remove vowels from all words in array", function () { - // Arrange - // Act - // Assert +describe("removeVowels function", () => { + test("removes vowels from a single word", () => { + // Arrange + const input = "samuel"; + const expectedOutput = "sml"; + + // Act + const result = removeVowels(input); + + // Assert + expect(result).toBe(expectedOutput); + }); + + test("returns an empty string when input contains only vowels", () => { + // Arrange + const input = "aeiou"; + const expectedOutput = ""; + + // Act + const result = removeVowels(input); + + // Assert + expect(result).toBe(expectedOutput); + }); + + test("returns the same string if no vowels are present", () => { + // Arrange + const input = "rhythm"; + const expectedOutput = "rhythm"; + + // Act + const result = removeVowels(input); + + // Assert + expect(result).toBe(expectedOutput); + }); +}); + +describe("removeVowelsFromWords function", () => { + test("removes vowels from each word in an array", () => { + // Arrange + const input = ["Irina", "Etza", "Daniel"]; + const expectedOutput = ["rn", "tz", "Dnl"]; + + // Act + const result = removeVowelsFromWords(input); + + // Assert + expect(result).toEqual(expectedOutput); + }); + + test("returns empty strings for words with only vowels", () => { + // Arrange + const input = ["aeiou", "IOU", "OIE"]; + const expectedOutput = ["", "", ""]; + + // Act + const result = removeVowelsFromWords(input); + + // Assert + expect(result).toEqual(expectedOutput); + }); + + test("returns the same array if no vowels are present in the words", () => { + // Arrange + const input = ["rhythm", "myth"]; + const expectedOutput = ["rhythm", "myth"]; + + // Act + const result = removeVowelsFromWords(input); + + // Assert + expect(result).toEqual(expectedOutput); + }); }); + + // example // input: ["Irina", "Etza", "Daniel"] // expected output: ["rn", "tz", "Dnl"] From d75c2745a99503727e6d75b13a5b3c639c4f2568 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Fri, 9 Jan 2026 19:32:04 +0100 Subject: [PATCH 17/18] mmodify the function --- .../writing-tests/remove-vowels/remove-vowels.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels.js b/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels.js index e5bb67ba..c7c3ab7f 100644 --- a/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels.js +++ b/challenges/unit-testing/writing-tests/remove-vowels/remove-vowels.js @@ -4,12 +4,9 @@ function removeVowels(word) { let result = []; characters.forEach(function (character) { + // Convert character to lowercase for uniformity if ( - character !== "a" && - character !== "o" && - character !== "i" && - character !== "e" && - character !== "u" + !["a", "o", "i", "e", "u"].includes(character.toLowerCase()) ) { result.push(character); } @@ -18,6 +15,7 @@ function removeVowels(word) { return result.join(""); } + module.exports = removeVowels; /* From 021bcff27fac1301422c2cfbb4c2e119f98529c5 Mon Sep 17 00:00:00 2001 From: Pinx-pinx Date: Fri, 9 Jan 2026 20:33:08 +0100 Subject: [PATCH 18/18] answer questions --- debugging/code-reading/readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/debugging/code-reading/readme.md b/debugging/code-reading/readme.md index 4090c14c..482a47db 100644 --- a/debugging/code-reading/readme.md +++ b/debugging/code-reading/readme.md @@ -16,6 +16,7 @@ Take a look at the following code: ``` Explain why line 5 and line 8 output different numbers. +Answer : Line 5 logs 2 because inside the function f1(), there's a local x with a value of 2. Line 8 logs 1 because the x outside the function is still 1. The two x variables are separate, one inside the function and one outside. ## Question 2 @@ -34,7 +35,7 @@ console.log(y); ``` What will be the output of this code. Explain your answer in 50 words or less. - +Answer : f1() logs x, which is 10. The y inside f1() is local to the function, so console.log(y) outside the function will throw an error because y is not defined outside the function. ## Question 3 Take a look at the following code: @@ -62,3 +63,4 @@ console.log(y); ``` What will be the output of this code. Explain your answer in 50 words or less. +Answer : f1(x) does not change x because x is a primitive value (number). In f2(y), y is an object, and the function modifies its x property directly. So y.x becomes 10, but x remains 9 because it’s not modified. \ No newline at end of file