diff --git a/format-clock-edge-cases/timeConverter.js b/format-clock-edge-cases/timeConverter.js index 310c07bd9..69d225960 100644 --- a/format-clock-edge-cases/timeConverter.js +++ b/format-clock-edge-cases/timeConverter.js @@ -1,11 +1,70 @@ function formatAs12HourClock(time) { + if (typeof time !== "string") { + return "Incorrect timing format"; + } + const correctTimingFormat = time.match(/^(\d{1,2}):(\d{2})$/); + + if (!correctTimingFormat) { + return "Incorrect timing format"; + } + + if (time.length == 4) { + time = time.padStart(5, "0"); + } + + const match = time.match(/^(\d{1,2}):(\d{2})$/); + + if (!match) { + return "Incorrect timing format"; + } const hours = Number(time.slice(0, 2)); + const minutes = Number(time.slice(3, 5)); + + // 00:00 + if (time === "00:00") { + return `12:00 am`; + } + + // 12:00 + if (time === "12:00") { + return `12:00 pm`; + } + + // 00:xx + if (hours === 0) { + return `12:${minutes.toString().padStart(2, "0")} am`; + } + + // 01:xx - 11:xx + if (hours < 12) { + return `${time} am`; + } + + // 12:xx + if (hours === 12) { + return `${time} pm`; + } + + // 13:00 - 21:59 + if (hours > 12 && hours < 22 && minutes < 10) { + return `${(hours - 12).toString().padStart(2, "0")}:${minutes + .toString() + .padStart(2, "0")} pm`; + } + + if (hours > 12 && hours < 22 && minutes >= 10) { + return `${(hours - 12).toString().padStart(2, "0")}:${minutes} pm`; + } + + // 22:00 - 23:59 + if (hours >= 22 && minutes < 10) { + return `${hours - 12}:${minutes.toString().padStart(2, "0")} pm`; + } - if (hours > 12) { - return `${hours - 12}:00 pm`; + if (hours >= 22 && minutes >= 10) { + return `${hours - 12}:${minutes} pm`; } - return `${time} am`; } -export {formatAs12HourClock}; +export { formatAs12HourClock }; diff --git a/format-clock-edge-cases/timeConverter.test.js b/format-clock-edge-cases/timeConverter.test.js index 88f2af094..08f4be8cd 100644 --- a/format-clock-edge-cases/timeConverter.test.js +++ b/format-clock-edge-cases/timeConverter.test.js @@ -1,11 +1,38 @@ -import {formatAs12HourClock} from "./timeConverter.js"; +import { formatAs12HourClock } from "./timeConverter.js"; import assert from "node:assert"; import test from "node:test"; -test("correctly convert time after 12:00", function(){ - assert.equal(formatAs12HourClock("23:00"), "11:00 pm"); +test("correctly convert time after 12:00", function () { + assert.equal(formatAs12HourClock("23:00"), "11:00 pm"); +}); +test("can correctly convert morning time", function () { + assert.equal(formatAs12HourClock("08:00"), "08:00 am"); +}); +test("can corectly convert midnight", () => + assert.equal(formatAs12HourClock("00:00"), "12:00 am")); +test("can corectly convert mid-day", () => + assert.equal(formatAs12HourClock("12:00"), "12:00 pm")); +test("can corectly convert half an hour passed midnight", () => + assert.equal(formatAs12HourClock("00:30"), "12:30 am")); +test("can correctly convert time with missing leading zero", function () { + assert.equal(formatAs12HourClock("9:00"), "09:00 am"); +}); +test("can correctly handel non digit format entries", function () { + assert.equal(formatAs12HourClock("nineOclock"), "Incorrect timing format"); +}); +test("can correctly handel one minute after midnight", function () { + assert.equal(formatAs12HourClock("00:01"), "12:01 am"); +}); +test("can correctly handel one minute before midday", function () { + assert.equal(formatAs12HourClock("11:59"), "11:59 am"); }); -test("can correctly convert morning time", function() { - assert.equal(formatAs12HourClock("08:00"), "08:00 am"); +test("can correctly handel 1 pm", function () { + assert.equal(formatAs12HourClock("13:00"), "01:00 pm"); +}); +test("can correctly handel one minute before midnight", function () { + assert.equal(formatAs12HourClock("23:59"), "11:59 pm"); +}); +test("can correctly handle one minute after midday", function () { + assert.equal(formatAs12HourClock("12:01"), "12:01 pm"); }); diff --git a/practice-tdd/.gitignore b/practice-tdd/.gitignore new file mode 100644 index 000000000..ad5e45ccc --- /dev/null +++ b/practice-tdd/.gitignore @@ -0,0 +1,3 @@ +node_modules +package.json +package-lock.json \ No newline at end of file diff --git a/practice-tdd/count.js b/practice-tdd/count.js index 5518c5712..ae98c6a43 100644 --- a/practice-tdd/count.js +++ b/practice-tdd/count.js @@ -1,3 +1,9 @@ export function countChar(stringOfCharacters, findCharacter) { - return 5 + let count = 0; + for (const character of stringOfCharacters) { + if (character === findCharacter) { + count++; + } + } + return count; } diff --git a/practice-tdd/count.test.js b/practice-tdd/count.test.js index cb3aaae59..e5af59b11 100644 --- a/practice-tdd/count.test.js +++ b/practice-tdd/count.test.js @@ -1,5 +1,8 @@ + // implement a function countChar that counts the number of times a character occurs in a string import { countChar } from "./count.js"; +import { test, expect } from "@jest/globals"; + // Given a string `str` and a single character `char` to search for, // When the countChar function is called with these inputs, // Then it should: @@ -22,3 +25,11 @@ 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. + +test("should indicate no occurrences of a character", () => { + const str = "abcde"; + const char = "f"; + const numberOfOcurrence= countChar(str, char); + expect(numberOfOcurrence).toEqual(0); +}); + diff --git a/practice-tdd/get-ordinal-number.js b/practice-tdd/get-ordinal-number.js index 5c6291f5e..3e82bb441 100644 --- a/practice-tdd/get-ordinal-number.js +++ b/practice-tdd/get-ordinal-number.js @@ -1,3 +1,13 @@ export function getOrdinalNumber(num) { - return "1st"; + if (String(num).match(/\b(?!11\b)\d*1\b/)) { + return `${num}st`; + } + if (String(num).match(/\b(?!12\b)\d*2\b/)) { + return `${num}nd`; + } + if (String(num).match(/\b(?!13\b)\d*3\b/)) { + return `${num}rd`; + } + return `${num}th` + } diff --git a/practice-tdd/get-ordinal-number.test.js b/practice-tdd/get-ordinal-number.test.js index e23174a18..1a8ec6717 100644 --- a/practice-tdd/get-ordinal-number.test.js +++ b/practice-tdd/get-ordinal-number.test.js @@ -18,3 +18,35 @@ test("should append 'st' for numbers ending with 1, except those ending with 11" expect(getOrdinalNumber(21)).toEqual("21st"); expect(getOrdinalNumber(131)).toEqual("131st"); }); + +// Case 2: Numbers ending with 2 (but not 12) +// When the number ends with 2, except those ending with 12, +// Then the function should return a string by appending "nd" to the number. +test("should append 'nd' for numbers ending with 2, except those ending with 12", () => { + expect(getOrdinalNumber(2)).toEqual("2nd"); + expect(getOrdinalNumber(32)).toEqual("32nd"); + expect(getOrdinalNumber(452)).toEqual("452nd"); +}); + +// Case 3: Numbers ending with 3 (but not 13) +// When the number ends with 3, except those ending with 13, +// Then the function should return a string by appending "rd" to the number. +test("should append 'rd' for numbers ending with 3, except those ending with 13", () => { + expect(getOrdinalNumber(3)).toEqual("3rd"); + expect(getOrdinalNumber(43)).toEqual("43rd"); + expect(getOrdinalNumber(823)).toEqual("823rd"); +}); + +// Case 4: Numbers ending with any other number (but not 1,2 or 3) +// When the number ends with 4,5,6 ,7 ,8 or 9 , +// Then the function should return a string by appending "th" to the number. +test("should append 'th' for numbers ending with 4,5,6 ,7 ,8 or 9 ", () => { + expect(getOrdinalNumber(4)).toEqual("4th"); + expect(getOrdinalNumber(25)).toEqual("25th"); + expect(getOrdinalNumber(656)).toEqual("656th"); + expect(getOrdinalNumber(1007)).toEqual("1007th"); + expect(getOrdinalNumber(638398)).toEqual("638398th"); + expect(getOrdinalNumber(34454559)).toEqual("34454559th"); +}); + + diff --git a/practice-tdd/repeat-str.js b/practice-tdd/repeat-str.js index af273f3b0..4351f2e82 100644 --- a/practice-tdd/repeat-str.js +++ b/practice-tdd/repeat-str.js @@ -1,5 +1,15 @@ -export function repeatStr() { +export function repeatStr(str, count) { // Your implementation of this function must *not* call String.prototype.repeat (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat). // The goal is to re-implement that function, not to use it. - return "hellohellohello"; + if (count < 0) { + return "Error! negative counts are not valid" + } + let result = ""; + let counter = count + while (counter > 0) { + result += str + counter--; + } + return result; + } diff --git a/practice-tdd/repeat-str.test.js b/practice-tdd/repeat-str.test.js index 8a7036102..247ebe846 100644 --- a/practice-tdd/repeat-str.test.js +++ b/practice-tdd/repeat-str.test.js @@ -21,12 +21,37 @@ test("should repeat the string count times", () => { // When the repeatStr function is called with these inputs, // Then it should return the original `str` without repetition. +test("should return the original `str` without repetition", () => { + const str = "hello"; + const count = 1; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).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, // Then it should return an empty string. +test("should return an empty string", () => { + const str = "hello"; + const count = 0; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual(""); +}); + + // Case: Handle negative count: // 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. + +test("should throw an error, as negative counts are not valid.", () => { + const str = "hello"; + const count = -3; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual("Error! negative counts are not valid"); +}); +