From 2cd8d1808a7610999cfb9501533ea69680ef108d Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Wed, 22 Oct 2025 23:19:34 +0100 Subject: [PATCH 01/13] implement countChar function and associated tests --- Sprint-3/2-practice-tdd/count.js | 5 ++++- Sprint-3/2-practice-tdd/count.test.js | 31 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index 95b6ebb7d..5e97a2f53 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -1,5 +1,8 @@ function countChar(stringOfCharacters, findCharacter) { - return 5 + return stringOfCharacters.split("").reduce((count, char) => { + if (char === findCharacter) count++; + return count; + }, 0); } module.exports = countChar; diff --git a/Sprint-3/2-practice-tdd/count.test.js b/Sprint-3/2-practice-tdd/count.test.js index 42baf4b4b..e4ede0654 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -22,3 +22,34 @@ test("should count multiple occurrences of a character", () => { // And a character char that does not exist within the case-sensitive str, // When the function is called with these inputs, // Then it should return 0, indicating that no occurrences of the char were found in the case-sensitive str. +test("should return 0 if no occurrences of a character", () => { + const str = "bbbbbb"; + const char = "a"; + const count = countChar(str, char); + expect(count).toEqual(0); +}); + +// Scenario: Single Occurrence +test("should return 1 for a single occurrence of a character", () => { + const str = "hello"; + const char = "e"; + const count = countChar(str, char); + expect(count).toEqual(1); +}); + +// Scenario: Case Sensitivity +test("should be case sensitive when counting characters", () => { + const str = "Hello World"; + const char = "h"; + const count = countChar(str, char); + expect(count).toEqual(0); +}); + +// Scenario: Empty String +test("should return 0 when the input string is empty", () => { + const str = ""; + const char = "a"; + const count = countChar(str, char); + expect(count).toEqual(0); +}); + From abcb28628a6e857521f7c5e28fb1e31d1a53d3a0 Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Wed, 22 Oct 2025 23:35:02 +0100 Subject: [PATCH 02/13] implemented getOrdinalNumber function and associated tests --- Sprint-3/2-practice-tdd/get-ordinal-number.js | 22 ++++++++- .../2-practice-tdd/get-ordinal-number.test.js | 48 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.js b/Sprint-3/2-practice-tdd/get-ordinal-number.js index f95d71db1..1892757e0 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.js @@ -1,5 +1,25 @@ function getOrdinalNumber(num) { - return "1st"; + switch (num % 100) { + case 11: + case 12: + case 13: + return num + "th"; + break; + } + switch (num % 10) { + case 1: + return num + "st"; + break; + case 2: + return num + "nd"; + break; + case 3: + return num + "rd"; + break; + default: + return num + "th"; + break; + } } module.exports = getOrdinalNumber; diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js index dfe4b6091..84cec4d14 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js @@ -11,3 +11,51 @@ const getOrdinalNumber = require("./get-ordinal-number"); test("should return '1st' for 1", () => { expect(getOrdinalNumber(1)).toEqual("1st"); }); + +test("should return '2nd' for 2", () => { + expect(getOrdinalNumber(2)).toEqual("2nd"); +}); + +test("should return '3rd' for 3", () => { + expect(getOrdinalNumber(3)).toEqual("3rd"); +}); + +test("should return '4th' for 4", () => { + expect(getOrdinalNumber(4)).toEqual("4th"); +}); + +test("should return '11th' for 11", () => { + expect(getOrdinalNumber(11)).toEqual("11th"); +}); + +test("should return '12th' for 12", () => { + expect(getOrdinalNumber(12)).toEqual("12th"); +}); + +test("should return '13th' for 13", () => { + expect(getOrdinalNumber(13)).toEqual("13th"); +}); + +test("should return '21st' for 21", () => { + expect(getOrdinalNumber(21)).toEqual("21st"); +}); + +test("should return '22nd' for 22", () => { + expect(getOrdinalNumber(22)).toEqual("22nd"); +}); + +test("should return '23rd' for 23", () => { + expect(getOrdinalNumber(23)).toEqual("23rd"); +}); + +test("should return '101st' for 101", () => { + expect(getOrdinalNumber(101)).toEqual("101st"); +}); + +test("should return '111th' for 111", () => { + expect(getOrdinalNumber(111)).toEqual("111th"); +}); + +test("should return '0th' for 0", () => { + expect(getOrdinalNumber(0)).toEqual("0th"); +}); \ No newline at end of file From 8a60a1626548a1463a02c2df8a9fd58a677314e7 Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Wed, 22 Oct 2025 23:46:44 +0100 Subject: [PATCH 03/13] implemented repeat function and associated tests --- Sprint-3/2-practice-tdd/repeat.js | 7 +++++-- Sprint-3/2-practice-tdd/repeat.test.js | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Sprint-3/2-practice-tdd/repeat.js b/Sprint-3/2-practice-tdd/repeat.js index 00e60d7f3..e43898290 100644 --- a/Sprint-3/2-practice-tdd/repeat.js +++ b/Sprint-3/2-practice-tdd/repeat.js @@ -1,5 +1,8 @@ -function repeat() { - return "hellohellohello"; +function repeat(str, count) { + if (count < 0) { + return "Count must be a non-negative integer" + } + return str.repeat(count); } module.exports = repeat; diff --git a/Sprint-3/2-practice-tdd/repeat.test.js b/Sprint-3/2-practice-tdd/repeat.test.js index 34097b09c..64ebab1fa 100644 --- a/Sprint-3/2-practice-tdd/repeat.test.js +++ b/Sprint-3/2-practice-tdd/repeat.test.js @@ -21,12 +21,30 @@ test("should repeat the string count times", () => { // When the repeat function is called with these inputs, // Then it should return the original str without repetition, ensuring that a count of 1 results in no repetition. +test("should return original string if count is 1", () => { + const str = "hello"; + const count = 1; + expect(repeat(str, count)).toEqual("hello"); +}); + // case: Handle Count of 0: // Given a target string str and a count equal to 0, // When the repeat function is called with these inputs, // Then it should return an empty string, ensuring that a count of 0 results in an empty output. +test("should return empty string if count is 0", () => { + const str = "hello"; + const count = 0; + expect(repeat(str, count)).toEqual(""); +}); + // case: Negative Count: // Given a target string str and a negative integer count, // When the repeat function is called with these inputs, // Then it should throw an error or return an appropriate error message, as negative counts are not valid. + +test("should return error message for negative count", () => { + const str = "hello"; + const count = -2; + expect(repeat(str, count)).toEqual("Count must be a non-negative integer"); +}); \ No newline at end of file From 295893993000cdb7dc5260bac6438b51a7711056 Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Tue, 28 Oct 2025 23:40:00 +0000 Subject: [PATCH 04/13] updated count char function and tests to include edge/corner cases and invalid inputs --- Sprint-3/2-practice-tdd/count.js | 19 +++++++--- Sprint-3/2-practice-tdd/count.test.js | 50 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index 5e97a2f53..f8d86515a 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -1,8 +1,19 @@ function countChar(stringOfCharacters, findCharacter) { - return stringOfCharacters.split("").reduce((count, char) => { - if (char === findCharacter) count++; - return count; - }, 0); + if (typeof stringOfCharacters !== 'string'){ + throw new Error("First argument must be a string."); + } + if (typeof findCharacter !== "string") { + throw new Error("Second argument must be a string."); + } + if (findCharacter.length !== 1) { + throw new Error("Character to find must be a single character."); + } + if (stringOfCharacters.length === 0) { + return 0; + } + console.log(Array.from(stringOfCharacters)); + + return Array.from(stringOfCharacters).filter(char => char === findCharacter).length; } module.exports = countChar; diff --git a/Sprint-3/2-practice-tdd/count.test.js b/Sprint-3/2-practice-tdd/count.test.js index e4ede0654..b24d310f5 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -53,3 +53,53 @@ test("should return 0 when the input string is empty", () => { expect(count).toEqual(0); }); +// Scenario: Numeric Characters +test("should count numeric characters in the string", () => { + const str = "123123123"; + const char = "2"; + const count = countChar(str, char); + expect(count).toEqual(3); +}); + +// Scenario: Whitespace Characters +test("should count whitespace characters in the string", () => { + const str = "a b c d e f "; + const char = " "; + const count = countChar(str, char); + expect(count).toEqual(6); +}); + +// Scenario: Edge Case - Character Not a Single Character +test('should throw error if char is not a single character', () => { + const str = 'hello'; + const char = 'll'; + expect(() => { + countChar(str, char); + }).toThrow('Character to find must be a single character'); + }) + +// Scenario: Special Case - Special Characters +test.each([ + { str: "!!!@@@###", char: "!", expected: 3 }, + { str: "$$$%%%^^^", char: "%", expected: 3 }, + { str: "&&&***(((", char: "(", expected: 3 }, +])( + "should count special characters correctly in '$str'", + ({ str, char, expected }) => { + const count = countChar(str, char); + expect(count).toEqual(expected); + } +); +//Scenario: Invalid Input Types +test.each([ + { str: 12345, char: "a", error: "First argument must be a string." }, + { str: "hello", char: 5, error: "Second argument must be a string." }, + { str: [], char: "a", error: "First argument must be a string." }, + { str: "hello", char: {}, error: "Second argument must be a string." }, + { str: null, char: "a", error: "First argument must be a string." }, + {str: "hi", char: undefined, error: "Second argument must be a string." }, +])("should throw error for invalid inputs", ({ str, char, error }) => { + expect(() => { + countChar(str, char); + }).toThrow(error); +}); From b290716f67fa8cd0488161778a813bffb9697f00 Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Tue, 28 Oct 2025 23:47:44 +0000 Subject: [PATCH 05/13] added test for correct amount of arguments and amended function to reflect this --- Sprint-3/2-practice-tdd/count.js | 5 +++++ Sprint-3/2-practice-tdd/count.test.js | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index f8d86515a..b1c009486 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -1,4 +1,9 @@ function countChar(stringOfCharacters, findCharacter) { + if (arguments.length !== 2) { + throw new Error( + "Function requires exactly two arguments: a string and a character to find." + ); + } if (typeof stringOfCharacters !== 'string'){ throw new Error("First argument must be a string."); } diff --git a/Sprint-3/2-practice-tdd/count.test.js b/Sprint-3/2-practice-tdd/count.test.js index b24d310f5..0973dfc07 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -103,3 +103,14 @@ test.each([ countChar(str, char); }).toThrow(error); }); +//test for 2 arguments +test("should throw error if more/less than 2 arguments are provided", () => { + expect(() => { + countChar("hello"); + }).toThrow("Function requires exactly two arguments: a string and a character to find."); + expect(() => { + countChar("hello", "h", "extra"); + }).toThrow( + "Function requires exactly two arguments: a string and a character to find." + ); +}); From 5e7feb27097d9f6da9bd5a0cdaea64edd24ca21b Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Tue, 28 Oct 2025 23:59:31 +0000 Subject: [PATCH 06/13] added edge/corner case and invalid input tests and associated code for get ordinal number --- Sprint-3/2-practice-tdd/get-ordinal-number.js | 14 ++++++ .../2-practice-tdd/get-ordinal-number.test.js | 48 ++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.js b/Sprint-3/2-practice-tdd/get-ordinal-number.js index 1892757e0..b71db67f3 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.js @@ -1,4 +1,18 @@ function getOrdinalNumber(num) { + if (arguments.length !== 1) { + throw new Error("Function requires exactly one argument"); + } + if (typeof num !== "number" || isNaN(num)) { + throw new Error("Input must be a number"); + } + if (!Number.isFinite(num)){ + throw new Error("Input must be a finite number"); + } + if (!Number.isInteger(num) || num < 0) { + throw new Error("Input must be a non-negative integer"); + } + + switch (num % 100) { case 11: case 12: diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js index 84cec4d14..dbcf3f810 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js @@ -58,4 +58,50 @@ test("should return '111th' for 111", () => { test("should return '0th' for 0", () => { expect(getOrdinalNumber(0)).toEqual("0th"); -}); \ No newline at end of file +}); + +// Extra test to check for correct number of arguments +test("should throw an error if no arguments are provided", () => { + expect(() => getOrdinalNumber()).toThrow("Function requires exactly one argument"); +}); + +test("should throw an error if more than one argument is provided", () => { + expect(() => getOrdinalNumber(1, 2)).toThrow("Function requires exactly one argument"); +}); + +//Invalid input tests +test("should throw an error if the argument is not a number", () => { + expect(() => getOrdinalNumber("a")).toThrow("Input must be a number"); +}); + +test("should throw an error if the argument is a negative number", () => { + expect(() => getOrdinalNumber(-1)).toThrow("Input must be a non-negative integer"); +}); + +test("should throw an error if the argument is a decimal", () => { + expect(() => getOrdinalNumber(1.5)).toThrow("Input must be a non-negative integer"); +}); + +test("should throw an error if the argument is NaN", () => { + expect(() => getOrdinalNumber(NaN)).toThrow("Input must be a number"); +}); + +test("should throw an error if the argument is Infinity", () => { + expect(() => getOrdinalNumber(Infinity)).toThrow("Input must be a finite number"); +}); + +test("should throw an error if the argument is -Infinity", () => { + expect(() => getOrdinalNumber(-Infinity)).toThrow("Input must be a finite number"); +}); +test("should throw an error if the argument is an object", () => { + expect(() => getOrdinalNumber({})).toThrow("Input must be a number"); +}); +test("should throw an error if the argument is an array", () => { + expect(() => getOrdinalNumber([])).toThrow("Input must be a number"); +}); +test("should throw an error if the argument is null", () => { + expect(() => getOrdinalNumber(null)).toThrow("Input must be a number"); +}); +test("should throw an error if the argument is undefined", () => { + expect(() => getOrdinalNumber(undefined)).toThrow("Input must be a number"); +}); \ No newline at end of file From 2beffba975d0afaa1fa22cf73fbfaffb4474acf8 Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Wed, 29 Oct 2025 09:04:27 +0000 Subject: [PATCH 07/13] Added edge case and invalid input tests and updated function to pass --- Sprint-3/2-practice-tdd/repeat.js | 10 ++++- Sprint-3/2-practice-tdd/repeat.test.js | 55 +++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Sprint-3/2-practice-tdd/repeat.js b/Sprint-3/2-practice-tdd/repeat.js index e43898290..a799f20b2 100644 --- a/Sprint-3/2-practice-tdd/repeat.js +++ b/Sprint-3/2-practice-tdd/repeat.js @@ -1,6 +1,12 @@ function repeat(str, count) { - if (count < 0) { - return "Count must be a non-negative integer" + if ( arguments.length !== 2) { + return "Function requires exactly 2 arguments"; + } + if (typeof str !== "string") { + return "First argument must be a string"; + } + if (!Number.isInteger(count) || count < 0) { + return "Second argument must be a non-negative integer"; } return str.repeat(count); } diff --git a/Sprint-3/2-practice-tdd/repeat.test.js b/Sprint-3/2-practice-tdd/repeat.test.js index 64ebab1fa..f7e47e98e 100644 --- a/Sprint-3/2-practice-tdd/repeat.test.js +++ b/Sprint-3/2-practice-tdd/repeat.test.js @@ -46,5 +46,56 @@ test("should return empty string if count is 0", () => { test("should return error message for negative count", () => { const str = "hello"; const count = -2; - expect(repeat(str, count)).toEqual("Count must be a non-negative integer"); -}); \ No newline at end of file + expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); +}); + +// invalid input tests +test("should return error message for non-integer count", () => { + const str = "hello"; + const count = 2.5; + expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); +}); + +test("should return error message for non-string input", () => { + const str = 123; + const count = 3; + expect(repeat(str, count)).toEqual("First argument must be a string"); +}); + +test("should return error message for non-string input with invalid count", () => { + const str = { text: "hello" }; + const count = -2; + expect(repeat(str, count)).toEqual("First argument must be a string"); +}); + +test("should return error message for string input with non number count", () => { + const str = "hello"; + const count = "3"; + const count2 = []; + expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); + expect(repeat(str, count2)).toEqual("Second argument must be a non-negative integer"); +}); + +test("should return error message for string input with NaN count", () => { + const str = "hello"; + const count = NaN; + expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); +}); + +test("should return error message for string input with null count", () => { + const str = "hello"; + const count = null; + expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); +}); + +test("should return error message for string input with undefined count", () => { + const str = "hello"; + const count = undefined; + expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); +}); + +test('should have the correct amount of arguments', () => { + expect(repeat('hello')).toEqual("Function requires exactly 2 arguments"); + expect(repeat("hello", 3, 3)).toEqual("Function requires exactly 2 arguments"); + }) + From d933572ac76612ba45d18d6fa3659c99fe308461 Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Sat, 1 Nov 2025 11:16:03 +0000 Subject: [PATCH 08/13] removed console logs from count.js --- Sprint-3/2-practice-tdd/count.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index b1c009486..2a1a3974c 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -15,9 +15,7 @@ function countChar(stringOfCharacters, findCharacter) { } if (stringOfCharacters.length === 0) { return 0; - } - console.log(Array.from(stringOfCharacters)); - + } return Array.from(stringOfCharacters).filter(char => char === findCharacter).length; } From 7fabb608d7b1dd5549e3c7277c67958917b90d2e Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Sat, 1 Nov 2025 12:17:45 +0000 Subject: [PATCH 09/13] applied changes to ordinal and repeat functions and tests --- Sprint-3/2-practice-tdd/get-ordinal-number.js | 4 ++-- .../2-practice-tdd/get-ordinal-number.test.js | 2 +- Sprint-3/2-practice-tdd/repeat.js | 7 +++--- Sprint-3/2-practice-tdd/repeat.test.js | 22 +++++++++---------- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.js b/Sprint-3/2-practice-tdd/get-ordinal-number.js index b71db67f3..97282d58e 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.js @@ -2,10 +2,10 @@ function getOrdinalNumber(num) { if (arguments.length !== 1) { throw new Error("Function requires exactly one argument"); } - if (typeof num !== "number" || isNaN(num)) { + if (typeof num !== "number") { throw new Error("Input must be a number"); } - if (!Number.isFinite(num)){ + if (!isFinite(num)) { throw new Error("Input must be a finite number"); } if (!Number.isInteger(num) || num < 0) { diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js index dbcf3f810..635fa2ae5 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js @@ -83,7 +83,7 @@ test("should throw an error if the argument is a decimal", () => { }); test("should throw an error if the argument is NaN", () => { - expect(() => getOrdinalNumber(NaN)).toThrow("Input must be a number"); + expect(() => getOrdinalNumber(NaN)).toThrow("Input must be a finite number"); }); test("should throw an error if the argument is Infinity", () => { diff --git a/Sprint-3/2-practice-tdd/repeat.js b/Sprint-3/2-practice-tdd/repeat.js index a799f20b2..23fe0c12f 100644 --- a/Sprint-3/2-practice-tdd/repeat.js +++ b/Sprint-3/2-practice-tdd/repeat.js @@ -1,12 +1,13 @@ function repeat(str, count) { if ( arguments.length !== 2) { - return "Function requires exactly 2 arguments"; + throw new Error(`Function requires exactly two arguments: a string and a count. Received ${arguments.length} arguments`); + } if (typeof str !== "string") { - return "First argument must be a string"; + throw new Error("First argument must be a string. Received type " + typeof str); } if (!Number.isInteger(count) || count < 0) { - return "Second argument must be a non-negative integer"; + throw new Error("Second argument must be a non-negative integer. Received " + count ); } return str.repeat(count); } diff --git a/Sprint-3/2-practice-tdd/repeat.test.js b/Sprint-3/2-practice-tdd/repeat.test.js index f7e47e98e..78ec132a5 100644 --- a/Sprint-3/2-practice-tdd/repeat.test.js +++ b/Sprint-3/2-practice-tdd/repeat.test.js @@ -46,56 +46,56 @@ test("should return empty string if count is 0", () => { test("should return error message for negative count", () => { const str = "hello"; const count = -2; - expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); + expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer"); }); // invalid input tests test("should return error message for non-integer count", () => { const str = "hello"; const count = 2.5; - expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); + expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer"); }); test("should return error message for non-string input", () => { const str = 123; const count = 3; - expect(repeat(str, count)).toEqual("First argument must be a string"); + expect(() => repeat(str, count)).toThrow("First argument must be a string"); }); test("should return error message for non-string input with invalid count", () => { const str = { text: "hello" }; const count = -2; - expect(repeat(str, count)).toEqual("First argument must be a string"); + expect(() => repeat(str, count)).toThrow("First argument must be a string"); }); test("should return error message for string input with non number count", () => { const str = "hello"; const count = "3"; const count2 = []; - expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); - expect(repeat(str, count2)).toEqual("Second argument must be a non-negative integer"); + expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer"); + expect(() => repeat(str, count2)).toThrow("Second argument must be a non-negative integer"); }); test("should return error message for string input with NaN count", () => { const str = "hello"; const count = NaN; - expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); + expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer"); }); test("should return error message for string input with null count", () => { const str = "hello"; const count = null; - expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); + expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer"); }); test("should return error message for string input with undefined count", () => { const str = "hello"; const count = undefined; - expect(repeat(str, count)).toEqual("Second argument must be a non-negative integer"); + expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer. Received undefined"); }); test('should have the correct amount of arguments', () => { - expect(repeat('hello')).toEqual("Function requires exactly 2 arguments"); - expect(repeat("hello", 3, 3)).toEqual("Function requires exactly 2 arguments"); + expect(() => repeat('hello')).toThrow(new Error("Function requires exactly two arguments: a string and a count. Received 1 arguments")); + expect(() => repeat("hello", 3, 3)).toThrow(new Error("Function requires exactly two arguments: a string and a count. Received 3 arguments")); }) From dad2134a1a0cec2f0767ead4da9d6c7d9d2bf7f9 Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Sat, 15 Nov 2025 16:02:19 +0000 Subject: [PATCH 10/13] refactor countChar function to validate arguments and update tests for error handling --- Sprint-3/2-practice-tdd/count.js | 4 ++-- Sprint-3/2-practice-tdd/count.test.js | 8 +------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index 2a1a3974c..aaf99d018 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -1,5 +1,5 @@ function countChar(stringOfCharacters, findCharacter) { - if (arguments.length !== 2) { + if (stringOfCharacters === undefined || findCharacter === undefined) { throw new Error( "Function requires exactly two arguments: a string and a character to find." ); @@ -13,7 +13,7 @@ function countChar(stringOfCharacters, findCharacter) { if (findCharacter.length !== 1) { throw new Error("Character to find must be a single character."); } - if (stringOfCharacters.length === 0) { + if (!stringOfCharacters.length) { return 0; } return Array.from(stringOfCharacters).filter(char => char === findCharacter).length; diff --git a/Sprint-3/2-practice-tdd/count.test.js b/Sprint-3/2-practice-tdd/count.test.js index 0973dfc07..a7d033609 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -97,20 +97,14 @@ test.each([ { str: [], char: "a", error: "First argument must be a string." }, { str: "hello", char: {}, error: "Second argument must be a string." }, { str: null, char: "a", error: "First argument must be a string." }, - {str: "hi", char: undefined, error: "Second argument must be a string." }, ])("should throw error for invalid inputs", ({ str, char, error }) => { expect(() => { countChar(str, char); }).toThrow(error); }); //test for 2 arguments -test("should throw error if more/less than 2 arguments are provided", () => { +test("should throw error if less than 2 arguments are provided", () => { expect(() => { countChar("hello"); }).toThrow("Function requires exactly two arguments: a string and a character to find."); - expect(() => { - countChar("hello", "h", "extra"); - }).toThrow( - "Function requires exactly two arguments: a string and a character to find." - ); }); From 5233e20d42cf938e537c89ea8dbf263a0a7b9efe Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Tue, 18 Nov 2025 15:38:10 +0000 Subject: [PATCH 11/13] refactor countChar and repeat functions to improve argument validation and error handling --- Sprint-3/2-practice-tdd/count.js | 10 ++++++++-- Sprint-3/2-practice-tdd/repeat.js | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index aaf99d018..164d15de3 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -1,22 +1,28 @@ function countChar(stringOfCharacters, findCharacter) { + if (stringOfCharacters === undefined || findCharacter === undefined) { throw new Error( "Function requires exactly two arguments: a string and a character to find." ); } + if (typeof stringOfCharacters !== 'string'){ throw new Error("First argument must be a string."); } + if (typeof findCharacter !== "string") { throw new Error("Second argument must be a string."); } + if (findCharacter.length !== 1) { throw new Error("Character to find must be a single character."); } + if (!stringOfCharacters.length) { return 0; - } - return Array.from(stringOfCharacters).filter(char => char === findCharacter).length; + } + + return [...stringOfCharacters].filter(char => char === findCharacter).length; } module.exports = countChar; diff --git a/Sprint-3/2-practice-tdd/repeat.js b/Sprint-3/2-practice-tdd/repeat.js index 23fe0c12f..2366094f4 100644 --- a/Sprint-3/2-practice-tdd/repeat.js +++ b/Sprint-3/2-practice-tdd/repeat.js @@ -1,14 +1,18 @@ function repeat(str, count) { + if ( arguments.length !== 2) { throw new Error(`Function requires exactly two arguments: a string and a count. Received ${arguments.length} arguments`); } + if (typeof str !== "string") { throw new Error("First argument must be a string. Received type " + typeof str); } + if (!Number.isInteger(count) || count < 0) { throw new Error("Second argument must be a non-negative integer. Received " + count ); } + return str.repeat(count); } From 86d69fb02e2cea4201d023e4a646d62591380dd9 Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Tue, 18 Nov 2025 16:32:27 +0000 Subject: [PATCH 12/13] add repeatStr function and comprehensive tests for argument validation and error handling in newly files to reflect upstream changes --- .../{repeat.js => repeat-str.js} | 4 +-- .../{repeat.test.js => repeat-str.test.js} | 30 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) rename Sprint-3/2-practice-tdd/{repeat.js => repeat-str.js} (88%) rename Sprint-3/2-practice-tdd/{repeat.test.js => repeat-str.test.js} (66%) diff --git a/Sprint-3/2-practice-tdd/repeat.js b/Sprint-3/2-practice-tdd/repeat-str.js similarity index 88% rename from Sprint-3/2-practice-tdd/repeat.js rename to Sprint-3/2-practice-tdd/repeat-str.js index 2366094f4..a06610ea2 100644 --- a/Sprint-3/2-practice-tdd/repeat.js +++ b/Sprint-3/2-practice-tdd/repeat-str.js @@ -1,4 +1,4 @@ -function repeat(str, count) { +function repeatStr(str, count) { if ( arguments.length !== 2) { throw new Error(`Function requires exactly two arguments: a string and a count. Received ${arguments.length} arguments`); @@ -16,4 +16,4 @@ function repeat(str, count) { return str.repeat(count); } -module.exports = repeat; +module.exports = repeatStr; diff --git a/Sprint-3/2-practice-tdd/repeat.test.js b/Sprint-3/2-practice-tdd/repeat-str.test.js similarity index 66% rename from Sprint-3/2-practice-tdd/repeat.test.js rename to Sprint-3/2-practice-tdd/repeat-str.test.js index 78ec132a5..2309e4a92 100644 --- a/Sprint-3/2-practice-tdd/repeat.test.js +++ b/Sprint-3/2-practice-tdd/repeat-str.test.js @@ -1,5 +1,5 @@ // Implement a function repeat -const repeat = require("./repeat"); +const repeatStr = require("./repeat-str"); // Given a target string str and a positive integer count, // When the repeat function is called with these inputs, // Then it should: @@ -12,7 +12,7 @@ const repeat = require("./repeat"); test("should repeat the string count times", () => { const str = "hello"; const count = 3; - const repeatedStr = repeat(str, count); + const repeatedStr = repeatStr(str, count); expect(repeatedStr).toEqual("hellohellohello"); }); @@ -24,7 +24,7 @@ test("should repeat the string count times", () => { test("should return original string if count is 1", () => { const str = "hello"; const count = 1; - expect(repeat(str, count)).toEqual("hello"); + expect(repeatStr(str, count)).toEqual("hello"); }); // case: Handle Count of 0: @@ -35,7 +35,7 @@ test("should return original string if count is 1", () => { test("should return empty string if count is 0", () => { const str = "hello"; const count = 0; - expect(repeat(str, count)).toEqual(""); + expect(repeatStr(str, count)).toEqual(""); }); // case: Negative Count: @@ -46,56 +46,56 @@ test("should return empty string if count is 0", () => { test("should return error message for negative count", () => { const str = "hello"; const count = -2; - expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer"); + expect(() => repeatStr(str, count)).toThrow("Second argument must be a non-negative integer"); }); // invalid input tests test("should return error message for non-integer count", () => { const str = "hello"; const count = 2.5; - expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer"); + expect(() => repeatStr(str, count)).toThrow("Second argument must be a non-negative integer"); }); test("should return error message for non-string input", () => { const str = 123; const count = 3; - expect(() => repeat(str, count)).toThrow("First argument must be a string"); + expect(() => repeatStr(str, count)).toThrow("First argument must be a string"); }); test("should return error message for non-string input with invalid count", () => { const str = { text: "hello" }; const count = -2; - expect(() => repeat(str, count)).toThrow("First argument must be a string"); + expect(() => repeatStr(str, count)).toThrow("First argument must be a string"); }); test("should return error message for string input with non number count", () => { const str = "hello"; const count = "3"; const count2 = []; - expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer"); - expect(() => repeat(str, count2)).toThrow("Second argument must be a non-negative integer"); + expect(() => repeatStr(str, count)).toThrow("Second argument must be a non-negative integer"); + expect(() => repeatStr(str, count2)).toThrow("Second argument must be a non-negative integer"); }); test("should return error message for string input with NaN count", () => { const str = "hello"; const count = NaN; - expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer"); + expect(() => repeatStr(str, count)).toThrow("Second argument must be a non-negative integer"); }); test("should return error message for string input with null count", () => { const str = "hello"; const count = null; - expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer"); + expect(() => repeatStr(str, count)).toThrow("Second argument must be a non-negative integer"); }); test("should return error message for string input with undefined count", () => { const str = "hello"; const count = undefined; - expect(() => repeat(str, count)).toThrow("Second argument must be a non-negative integer. Received undefined"); + expect(() => repeatStr(str, count)).toThrow("Second argument must be a non-negative integer. Received undefined"); }); test('should have the correct amount of arguments', () => { - expect(() => repeat('hello')).toThrow(new Error("Function requires exactly two arguments: a string and a count. Received 1 arguments")); - expect(() => repeat("hello", 3, 3)).toThrow(new Error("Function requires exactly two arguments: a string and a count. Received 3 arguments")); + expect(() => repeatStr('hello')).toThrow(new Error("Function requires exactly two arguments: a string and a count. Received 1 arguments")); + expect(() => repeatStr("hello", 3, 3)).toThrow(new Error("Function requires exactly two arguments: a string and a count. Received 3 arguments")); }) From 245f2855e41288dec5a21f7de350aaf36979eb9a Mon Sep 17 00:00:00 2001 From: Imran Mohamed Date: Tue, 18 Nov 2025 17:54:07 +0000 Subject: [PATCH 13/13] removed test for more than 2 arguments --- Sprint-3/2-practice-tdd/repeat-str.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Sprint-3/2-practice-tdd/repeat-str.test.js b/Sprint-3/2-practice-tdd/repeat-str.test.js index fde7fa594..ae32e993d 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.test.js +++ b/Sprint-3/2-practice-tdd/repeat-str.test.js @@ -96,6 +96,5 @@ test("should return error message for string input with undefined count", () => test('should have the correct amount of arguments', () => { expect(() => repeatStr('hello')).toThrow(new Error("Function requires exactly two arguments: a string and a count. Received 1 arguments")); - expect(() => repeatStr("hello", 3, 3)).toThrow(new Error("Function requires exactly two arguments: a string and a count. Received 3 arguments")); })