diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index 95b6ebb7d..164d15de3 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -1,5 +1,28 @@ function countChar(stringOfCharacters, findCharacter) { - return 5 + + 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 [...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 42baf4b4b..a7d033609 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -22,3 +22,89 @@ 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); +}); + +// 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." }, +])("should throw error for invalid inputs", ({ str, char, error }) => { + expect(() => { + countChar(str, char); + }).toThrow(error); +}); +//test for 2 arguments +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."); +}); diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.js b/Sprint-3/2-practice-tdd/get-ordinal-number.js index f95d71db1..97282d58e 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.js @@ -1,5 +1,39 @@ function getOrdinalNumber(num) { - return "1st"; + if (arguments.length !== 1) { + throw new Error("Function requires exactly one argument"); + } + if (typeof num !== "number") { + throw new Error("Input must be a number"); + } + if (!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: + 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..635fa2ae5 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,97 @@ 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"); +}); + +// 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 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 -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 diff --git a/Sprint-3/2-practice-tdd/repeat-str.js b/Sprint-3/2-practice-tdd/repeat-str.js index 3838c7b00..a06610ea2 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.js +++ b/Sprint-3/2-practice-tdd/repeat-str.js @@ -1,5 +1,19 @@ -function repeatStr() { - return "hellohellohello"; +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`); + + } + + 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); } module.exports = repeatStr; diff --git a/Sprint-3/2-practice-tdd/repeat-str.test.js b/Sprint-3/2-practice-tdd/repeat-str.test.js index fc59d019e..ae32e993d 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.test.js +++ b/Sprint-3/2-practice-tdd/repeat-str.test.js @@ -18,15 +18,83 @@ test("should repeat the string count times", () => { // case: handle Count of 1: // Given a target string str and a count equal to 1, -// When the repeatStr function is called with these inputs, +// 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(repeatStr(str, count)).toEqual("hello"); +}); + // case: Handle Count of 0: // Given a target string str and a count equal to 0, -// When the repeatStr function is called with these inputs, +// 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(repeatStr(str, count)).toEqual(""); +}); + // case: Negative Count: // Given a target string str and a negative integer count, -// When the repeatStr function is called with these inputs, +// 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(() => 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(() => 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(() => 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(() => 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(() => 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(() => 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(() => 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(() => repeatStr(str, count)).toThrow("Second argument must be a non-negative integer. Received undefined"); +}); + +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")); + }) +