diff --git a/.gitignore b/.gitignore index bde36e530..ed63450dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ node_modules .DS_Store .vscode -**/.DS_Store \ No newline at end of file +*package.json +*package-lock.json +**/.DS_Store diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index 95b6ebb7d..8903068f9 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -1,5 +1,40 @@ +/** + * Original file: + * function countChar(stringOfCharacters, findCharacter) { return 5 } module.exports = countChar; +* +* End of file +*/ + +// Implementation: + +/** + * Counts the number of times a character occurs in a string + * @param {string} str - The string to search + * @param {string} char - The single character to search for + * @returns {number} - The count of occurrences + */ +function countChar(str, char) { + // Input validation + if (typeof str !== 'string' || typeof char !== 'string' || char.length !== 1) { + return 0; + } + + let count = 0; + + // Loop through each character in the string + for (let i = 0; i < str.length; i++) { + if (str[i] === char) { + count++; + } + } + + return count; +} + +module.exports = countChar; + diff --git a/Sprint-3/2-practice-tdd/count.test.js b/Sprint-3/2-practice-tdd/count.test.js index 179ea0ddf..691947ccc 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -1,3 +1,6 @@ +/** + * Origignal file: + * // implement a function countChar that counts the number of times a character occurs in a string const countChar = require("./count"); // Given a string `str` and a single character `char` to search for, @@ -22,3 +25,55 @@ test("should count multiple occurrences of a character", () => { // And a character `char` that does not exist within `str`. // When the function is called with these inputs, // Then it should return 0, indicating that no occurrences of `char` were found. +* +* End of file +*/ + +// Implementation: + +const countChar = require("./count"); + +describe("countChar function", () => { + test("should count multiple occurrences of a character", () => { + const str = "aaaaa"; + const char = "a"; + const count = countChar(str, char); + expect(count).toEqual(5); + }); + + test("should return 0 when character does not occur in the string", () => { + const str = "hello world"; + const char = "z"; + const count = countChar(str, char); + expect(count).toEqual(0); + }); + + // Additional test cases to ensure robustness + test("should handle empty string", () => { + const str = ""; + const char = "a"; + const count = countChar(str, char); + expect(count).toEqual(0); + }); + + test("should handle single occurrence", () => { + const str = "hello world"; + const char = "h"; + const count = countChar(str, char); + expect(count).toEqual(1); + }); + + test("should handle case sensitivity", () => { + const str = "Hello World"; + const char = "h"; + const count = countChar(str, char); + expect(count).toEqual(0); // 'H' is different from 'h' + }); + + test("should handle invalid inputs gracefully", () => { + expect(countChar(123, "a")).toEqual(0); // Non-string first argument + expect(countChar("hello", 123)).toEqual(0); // Non-string second argument + expect(countChar("hello", "ab")).toEqual(0); // Multiple characters + }); +}); + diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.js b/Sprint-3/2-practice-tdd/get-ordinal-number.js index f95d71db1..d04b8fd00 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 @@ +/** + * Original file + * function getOrdinalNumber(num) { return "1st"; } module.exports = getOrdinalNumber; +* +* Enf of file +*/ + +function getOrdinalNumber(number) { + if (typeof number !== 'number' || !Number.isInteger(number) || number < 0) { + throw new Error('Input must be a non-negative integer'); + } + + // Special case for numbers ending in 11, 12, 13 + const lastTwoDigits = number % 100; + if (lastTwoDigits >= 11 && lastTwoDigits <= 13) { + return number + "th"; + } + + // Check the last digit + const lastDigit = number % 10; + switch (lastDigit) { + case 1: + return number + "st"; + case 2: + return number + "nd"; + case 3: + return number + "rd"; + default: + return number + "th"; + } +} + +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 adfa58560..3e823d14f 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js @@ -1,3 +1,6 @@ +/** + * Original file + * const getOrdinalNumber = require("./get-ordinal-number"); // In this week's prep, we started implementing getOrdinalNumber. @@ -18,3 +21,107 @@ test("should append 'st' for numbers ending with 1, except those ending with 11" expect(getOrdinalNumber(21)).toEqual("21st"); expect(getOrdinalNumber(131)).toEqual("131st"); }); +* +* End of file +*/ + +// Implementation + +const getOrdinalNumber = require("./get-ordinal-number"); + +describe("getOrdinalNumber", () => { + // Case 1: Numbers ending with 1 (but not 11) + test("should append 'st' for numbers ending with 1, except those ending with 11", () => { + expect(getOrdinalNumber(1)).toEqual("1st"); + expect(getOrdinalNumber(21)).toEqual("21st"); + expect(getOrdinalNumber(101)).toEqual("101st"); + expect(getOrdinalNumber(131)).toEqual("131st"); + expect(getOrdinalNumber(1001)).toEqual("1001st"); + }); + + // Case 2: Numbers ending with 2 (but not 12) + test("should append 'nd' for numbers ending with 2, except those ending with 12", () => { + expect(getOrdinalNumber(2)).toEqual("2nd"); + expect(getOrdinalNumber(22)).toEqual("22nd"); + expect(getOrdinalNumber(102)).toEqual("102nd"); + expect(getOrdinalNumber(132)).toEqual("132nd"); + expect(getOrdinalNumber(1002)).toEqual("1002nd"); + }); + + // Case 3: Numbers ending with 3 (but not 13) + test("should append 'rd' for numbers ending with 3, except those ending with 13", () => { + expect(getOrdinalNumber(3)).toEqual("3rd"); + expect(getOrdinalNumber(23)).toEqual("23rd"); + expect(getOrdinalNumber(103)).toEqual("103rd"); + expect(getOrdinalNumber(133)).toEqual("133rd"); + expect(getOrdinalNumber(1003)).toEqual("1003rd"); + }); + + // Case 4: Numbers ending with 11, 12, or 13 + test("should append 'th' for numbers ending with 11, 12, or 13", () => { + expect(getOrdinalNumber(11)).toEqual("11th"); + expect(getOrdinalNumber(12)).toEqual("12th"); + expect(getOrdinalNumber(13)).toEqual("13th"); + expect(getOrdinalNumber(111)).toEqual("111th"); + expect(getOrdinalNumber(112)).toEqual("112th"); + expect(getOrdinalNumber(113)).toEqual("113th"); + expect(getOrdinalNumber(1011)).toEqual("1011th"); + expect(getOrdinalNumber(1012)).toEqual("1012th"); + expect(getOrdinalNumber(1013)).toEqual("1013th"); + }); + + // Case 5: All other numbers (should get "th") + test("should append 'th' for all other numbers", () => { + // Numbers ending with 0 + expect(getOrdinalNumber(0)).toEqual("0th"); + expect(getOrdinalNumber(10)).toEqual("10th"); + expect(getOrdinalNumber(20)).toEqual("20th"); + expect(getOrdinalNumber(100)).toEqual("100th"); + + // Numbers ending with 4-9 + expect(getOrdinalNumber(4)).toEqual("4th"); + expect(getOrdinalNumber(5)).toEqual("5th"); + expect(getOrdinalNumber(6)).toEqual("6th"); + expect(getOrdinalNumber(7)).toEqual("7th"); + expect(getOrdinalNumber(8)).toEqual("8th"); + expect(getOrdinalNumber(9)).toEqual("9th"); + + // Larger numbers ending with 4-9 + expect(getOrdinalNumber(24)).toEqual("24th"); + expect(getOrdinalNumber(35)).toEqual("35th"); + expect(getOrdinalNumber(46)).toEqual("46th"); + expect(getOrdinalNumber(57)).toEqual("57th"); + expect(getOrdinalNumber(68)).toEqual("68th"); + expect(getOrdinalNumber(79)).toEqual("79th"); + }); + + // Edge cases + describe("edge cases", () => { + test("should handle zero", () => { + expect(getOrdinalNumber(0)).toEqual("0th"); + }); + + test("should handle large numbers", () => { + expect(getOrdinalNumber(1000000)).toEqual("1000000th"); + expect(getOrdinalNumber(1000001)).toEqual("1000001st"); + expect(getOrdinalNumber(1000002)).toEqual("1000002nd"); + expect(getOrdinalNumber(1000003)).toEqual("1000003rd"); + expect(getOrdinalNumber(1000011)).toEqual("1000011th"); + }); + + test("should throw error for negative numbers", () => { + expect(() => getOrdinalNumber(-1)).toThrow("Input must be a non-negative integer"); + }); + + test("should throw error for non-integer numbers", () => { + expect(() => getOrdinalNumber(1.5)).toThrow("Input must be a non-negative integer"); + }); + + test("should throw error for non-number inputs", () => { + expect(() => getOrdinalNumber("1")).toThrow("Input must be a non-negative integer"); + expect(() => getOrdinalNumber(null)).toThrow("Input must be a non-negative integer"); + expect(() => getOrdinalNumber(undefined)).toThrow("Input must be a non-negative integer"); + }); + }); +}); + diff --git a/Sprint-3/2-practice-tdd/repeat-str.js b/Sprint-3/2-practice-tdd/repeat-str.js index 3838c7b00..e55d6619a 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.js +++ b/Sprint-3/2-practice-tdd/repeat-str.js @@ -1,5 +1,44 @@ +/** + * Origina file + * function repeatStr() { return "hellohellohello"; } module.exports = repeatStr; +* +* End of file +*/ + +/** + * @param {string} str - The string to repeat + * @param {number} count - The number of times to repeat the string (must be non-negative) + * @returns {string} The repeated string + * @throws {Error} When count is negative + */ +function repeatStr(str, count) { + // Input validation + if (typeof str !== 'string') { + throw new Error('First argument must be a string'); + } + + if (typeof count !== 'number' || !Number.isInteger(count)) { + throw new Error('Count must be an integer'); + } + + // Handle negative count + if (count < 0) { + throw new Error('Count must be a positive integer'); + } + + // Handle count of 0 + if (count === 0) { + return ""; + } + + // Use built-in repeat method for efficiency + 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 a3fc1196c..26739f112 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.test.js +++ b/Sprint-3/2-practice-tdd/repeat-str.test.js @@ -1,3 +1,6 @@ +/** + * Original file: + * // Implement a function repeatStr const repeatStr = require("./repeat-str"); // Given a target string `str` and a positive integer `count`, @@ -30,3 +33,68 @@ test("should repeat the string count times", () => { // Given a target string `str` and a negative integer `count`, // When the repeatStr function is called with these inputs, // Then it should throw an error, as negative counts are not valid. +* +* Enf of file +*/ + +// Implementation: + +const repeatStr = require("./repeat-str"); + +describe("repeatStr function", () => { + // Test case 1: Multiple repetitions (count > 1) + test("should repeat the string count times when count > 1", () => { + const str = "hello"; + const count = 3; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual("hellohellohello"); + }); + + // Test case 2: Count equal to 1 + test("should return the original string when count is 1", () => { + const str = "hello"; + const count = 1; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual("hello"); + }); + + // Test case 3: Count equal to 0 + test("should return empty string when count is 0", () => { + const str = "hello"; + const count = 0; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual(""); + }); + + // Test case 4: Negative count + test("should throw an error when count is negative", () => { + const str = "hello"; + const count = -1; + expect(() => { + repeatStr(str, count); + }).toThrow("Count must be a positive integer"); + }); + + // Additional test cases for robustness + describe("edge cases", () => { + test("should handle empty string", () => { + expect(repeatStr("", 5)).toEqual(""); + }); + + test("should handle string with spaces", () => { + expect(repeatStr("a b ", 2)).toEqual("a b a b "); + }); + + test("should throw error when count is not an integer", () => { + expect(() => { + repeatStr("hello", 3.5); + }).toThrow("Count must be an integer"); + }); + + test("should throw error when first argument is not a string", () => { + expect(() => { + repeatStr(123, 3); + }).toThrow("First argument must be a string"); + }); + }); +});