diff --git a/Sprint-3/1-implement-and-rewrite-tests/implement/1-get-angle-type.js b/Sprint-3/1-implement-and-rewrite-tests/implement/1-get-angle-type.js index 9e05a871e2..14d5b6c916 100644 --- a/Sprint-3/1-implement-and-rewrite-tests/implement/1-get-angle-type.js +++ b/Sprint-3/1-implement-and-rewrite-tests/implement/1-get-angle-type.js @@ -15,7 +15,20 @@ // execute the code to ensure all tests pass. function getAngleType(angle) { - // TODO: Implement this function + switch (true) { + case angle == 90: + return "Right angle"; + case 0 < angle && angle < 90: + return "Acute angle"; + case 90 < angle && angle < 180: + return "Obtuse angle"; + case angle == 180: + return "Straight angle"; + case 180 < angle && angle < 360: + return "Reflex angle"; + case angle > 360 || angle < 0 || angle == 0: + return "Invalid angle"; + } } // The line below allows us to load the getAngleType function into tests in other files. @@ -33,5 +46,45 @@ function assertEquals(actualOutput, targetOutput) { // TODO: Write tests to cover all cases, including boundary and invalid cases. // Example: Identify Right Angles + +const acute1 = getAngleType(1); +assertEquals(acute1, "Acute angle"); + +const acute45 = getAngleType(45); +assertEquals(acute45, "Acute angle"); + +const acute89 = getAngleType(89); +assertEquals(acute89, "Acute angle"); + const right = getAngleType(90); assertEquals(right, "Right angle"); + +const obtuse91 = getAngleType(91); +assertEquals(obtuse91, "Obtuse angle"); + +const obtuse140 = getAngleType(140); +assertEquals(obtuse140, "Obtuse angle"); + +const obtuse179 = getAngleType(179); +assertEquals(obtuse179, "Obtuse angle"); + +const straight = getAngleType(180); +assertEquals(straight, "Straight angle"); + +const reflex181 = getAngleType(181); +assertEquals(reflex181, "Reflex angle"); + +const reflex250 = getAngleType(250); +assertEquals(reflex250, "Reflex angle"); + +const reflex359 = getAngleType(359); +assertEquals(reflex359, "Reflex angle"); + +const zero = getAngleType(0); +assertEquals(zero, "Invalid angle"); + +const invalid = getAngleType(400); +assertEquals(invalid, "Invalid angle"); + +const negative = getAngleType(-4); +assertEquals(zero, "Invalid angle"); diff --git a/Sprint-3/1-implement-and-rewrite-tests/implement/2-is-proper-fraction.js b/Sprint-3/1-implement-and-rewrite-tests/implement/2-is-proper-fraction.js index 970cb9b641..cccebff9f3 100644 --- a/Sprint-3/1-implement-and-rewrite-tests/implement/2-is-proper-fraction.js +++ b/Sprint-3/1-implement-and-rewrite-tests/implement/2-is-proper-fraction.js @@ -11,7 +11,13 @@ // execute the code to ensure all tests pass. function isProperFraction(numerator, denominator) { - // TODO: Implement this function + switch (true) { + case Math.abs(numerator / denominator) < 1 && + Math.abs(numerator / denominator) > 0: + return true; + default: + return false; + } } // The line below allows us to load the isProperFraction function into tests in other files. @@ -31,3 +37,8 @@ function assertEquals(actualOutput, targetOutput) { // Example: 1/2 is a proper fraction assertEquals(isProperFraction(1, 2), true); +assertEquals(isProperFraction(2, 1), false); +assertEquals(isProperFraction(-2, 1), false); +assertEquals(isProperFraction(1, -2), true); +assertEquals(isProperFraction(-2, -4), true); +assertEquals(isProperFraction(-4, -2), false); diff --git a/Sprint-3/1-implement-and-rewrite-tests/implement/3-get-card-value.js b/Sprint-3/1-implement-and-rewrite-tests/implement/3-get-card-value.js index ff5c532e1d..0c8745a3f9 100644 --- a/Sprint-3/1-implement-and-rewrite-tests/implement/3-get-card-value.js +++ b/Sprint-3/1-implement-and-rewrite-tests/implement/3-get-card-value.js @@ -22,7 +22,46 @@ // execute the code to ensure all tests pass. function getCardValue(card) { - // TODO: Implement this function + const suit = card.replaceAll(/[\w\d\s]/g, ""); + const value = card.replaceAll(/[^\w\d\s]/g, ""); + const face = ["J", "Q", "K"]; + const validSuits = ["♠", "♥", "♦", "♣"]; + const validValue = [ + "A", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "J", + "Q", + "K", + ]; + + if ( + !validSuits.includes(suit) || + !validValue.includes(value) || + card !== value + suit + ) { + throw new Error("Invalid card"); + } + + if (validSuits.includes(suit)) { + switch (true) { + case Number(value) <= 10 && Number(value) >= 2: + return Number(value); + case value === "A": + return 11; + case face.includes(value): + return 10; + } + } + + return "Invalid card"; } // The line below allows us to load the getCardValue function into tests in other files. @@ -39,7 +78,23 @@ function assertEquals(actualOutput, targetOutput) { // TODO: Write tests to cover all outcomes, including throwing errors for invalid cards. // Examples: -assertEquals(getCardValue("9♠"), 9); + +// Test number cards +assertEquals(getCardValue("2♠"), 2); +assertEquals(getCardValue("5♥"), 5); +assertEquals(getCardValue("9♦"), 9); +assertEquals(getCardValue("10♣"), 10); + +// Test aces +assertEquals(getCardValue("A♠"), 11); +assertEquals(getCardValue("A♥"), 11); +assertEquals(getCardValue("A♦"), 11); +assertEquals(getCardValue("A♣"), 11); + +// Test face cards +assertEquals(getCardValue("J♠"), 10); +assertEquals(getCardValue("Q♥"), 10); +assertEquals(getCardValue("K♦"), 10); // Handling invalid cards try { @@ -52,3 +107,43 @@ try { } // What other invalid card cases can you think of? + +function errorThrown(card) { + try { + getCardValue(card); + console.error(`Expected "${card}" to throw an error 😢`); + } catch (error) { + console.log(`"${card}" Error thrown for invalid card 🎉`); + } +} + +// Missing a suit +errorThrown("9"); + +// Missing a rank +errorThrown("♠"); + +// Invalid rank +errorThrown("1♠"); +errorThrown("11♠"); +errorThrown("Z♠"); + +// Invalid suit +errorThrown("9X"); + +// Suit and rank in the wrong order +errorThrown("♠9"); + +// Extra characters +errorThrown("9♠hello"); +errorThrown("A♠♠"); + +// Spaces +errorThrown("9 ♠"); +errorThrown(" 9♠"); +errorThrown("9♠ "); + +// Empty or incorrectly capitalised +errorThrown(""); +errorThrown("a♠"); +errorThrown("j♠"); diff --git a/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/1-get-angle-type.test.js b/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/1-get-angle-type.test.js index d777f348d3..2cb372b562 100644 --- a/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/1-get-angle-type.test.js +++ b/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/1-get-angle-type.test.js @@ -14,7 +14,28 @@ test(`should return "Acute angle" when (0 < angle < 90)`, () => { }); // Case 2: Right angle +test('Should return "Right angle" when (angle ==90)', () => { + expect(getAngleType(90)).toEqual("Right angle"); +}); // Case 3: Obtuse angles +test('Should return "Obtuse angle when (90 { + (expect(getAngleType(91)).toEqual, "Obtuse angle"); + (expect(getAngleType(179)).toEqual, "Obtuse angle"); + (expect(getAngleType(140)).toEqual, "Obtuse angle"); +}); // Case 4: Straight angle +test('should return "Straight angle" when( angle ==180)', () => { + (expect(getAngleType(180)).toEqual, "Right angle"); +}); // Case 5: Reflex angles +test('should return "Reflex angle" when (180< angle < 360);', () => { + (expect(getAngleType(250)).toEqual, "Reflex angle"); + (expect(getAngleType(181)).toEqual, "Reflex angle"); + (expect(getAngleType(359)).toEqual, "Reflex angle"); +}); // Case 6: Invalid angles +test('should return "Invalid angle" when ( 0 < angle >360 || 0 == angle)', () => { + (expect(getAngleType(0)).toEqual, "Invalid angle"); + (expect(getAngleType(400)).toEqual, "Invalid angle"); + (expect(getAngleType(-4)).toEqual, "Invalid. angle"); +}); diff --git a/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/2-is-proper-fraction.test.js b/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/2-is-proper-fraction.test.js index 7f087b2ba1..4f7429afef 100644 --- a/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/2-is-proper-fraction.test.js +++ b/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/2-is-proper-fraction.test.js @@ -5,6 +5,30 @@ const isProperFraction = require("../implement/2-is-proper-fraction"); // TODO: Write tests in Jest syntax to cover all combinations of positives, negatives, zeros, and other categories. // Special case: numerator is zero -test(`should return false when denominator is zero`, () => { +test(`should return FALSE when denominator is zero`, () => { expect(isProperFraction(1, 0)).toEqual(false); }); + +test("should return FALSE when numerator is zero", () => { + expect(isProperFraction(0, 5)).toEqual(false); +}); + +test("should return TRUE when numerator is negative and smaller than denominator", () => { + expect(isProperFraction(-1, 7)).toEqual(true); +}); + +test("should return TRUE when denominator is negative AND bigger than numerator", () => { + expect(isProperFraction(1, -7)).toEqual(true); +}); + +test("should return FALSE when numerator > denominator ", () => { + expect(isProperFraction(9, 7)).toEqual(false); +}); + +test("should return TRUE when numerator < denominator ", () => { + expect(isProperFraction(4, 7)).toEqual(true); +}); + +test("should return TRUE when numerator AND denominator are negative values and the denominator is bigger than numerator", () => { + expect(isProperFraction(-4, -7)).toEqual(true); +}); diff --git a/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/3-get-card-value.test.js b/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/3-get-card-value.test.js index cf7f9dae2e..284d4b012a 100644 --- a/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/3-get-card-value.test.js +++ b/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/3-get-card-value.test.js @@ -6,15 +6,40 @@ const getCardValue = require("../implement/3-get-card-value"); // Case 1: Ace (A) test(`Should return 11 when given an ace card`, () => { + expect(getCardValue("A♣")).toEqual(11); expect(getCardValue("A♠")).toEqual(11); + expect(getCardValue("A♥")).toEqual(11); + expect(getCardValue("A♦")).toEqual(11); }); -// Suggestion: Group the remaining test data into these categories: -// Number Cards (2-10) -// Face Cards (J, Q, K) -// Invalid Cards +// Case 2: Number Cards (2-10) +test(`Should return a value equal to the number on the card`, () => { + expect(getCardValue("2♠")).toEqual(2); + expect(getCardValue("5♥")).toEqual(5); + expect(getCardValue("9♦")).toEqual(9); + expect(getCardValue("10♣")).toEqual(10); +}); + +// Case 3: Face Cards (J, Q, K) +test(`Should return 10 when given a face card`, () => { + expect(getCardValue("K♥")).toEqual(10); + expect(getCardValue("J♠")).toEqual(10); + expect(getCardValue("Q♦")).toEqual(10); +}); +// Case 4: Invalid Cards +test(`All invalid cards should throw an Invalid error`, () => { + expect(() => getCardValue("9")).toThrow(/Invalid/); // missing suit + expect(() => getCardValue("♥")).toThrow(/Invalid/); // missing rank + expect(() => getCardValue("1♠")).toThrow(/Invalid/); // invalid rank + expect(() => getCardValue("11♠")).toThrow(/Invalid/); // rank too high + expect(() => getCardValue("9X")).toThrow(/Invalid/); // invalid suit + expect(() => getCardValue("♠9")).toThrow(/Invalid/); // wrong order + expect(() => getCardValue("9 ♠")).toThrow(/Invalid/); // space inside + expect(() => getCardValue("9♠ ")).toThrow(/Invalid/); // space after + expect(() => getCardValue("")).toThrow(/Invalid/); // empty string + expect(() => getCardValue("j♠")).toThrow(/Invalid/); // lowercase +}); // To learn how to test whether a function throws an error as expected in Jest, // please refer to the Jest documentation: // https://jestjs.io/docs/expect#tothrowerror - diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index 95b6ebb7d4..3250f4e6d2 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -1,5 +1,9 @@ function countChar(stringOfCharacters, findCharacter) { - return 5 + const regEx = new RegExp(`[^${findCharacter}]`, "g"); + const numOfMatchedChar = stringOfCharacters.replaceAll(regEx, "").length; + return numOfMatchedChar; } +console.log(countChar("dafsadf", "a")); + module.exports = countChar; diff --git a/Sprint-3/2-practice-tdd/count.test.js b/Sprint-3/2-practice-tdd/count.test.js index 179ea0ddf7..4837fe913a 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -22,3 +22,37 @@ 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 return 0 when no occurrence of 'char' is found in 'str'", () => { + const str = "cde"; + const char = "a"; + const count = countChar(str, char); + expect(count).toEqual(0); +}); + +// Scenario: Empty string +// Given an empty string `str` +// And a single character `char` +// When countChar is called +// Then it should return 0 +test("should return 0 when the string is empty", () => { + const str = ""; + const char = "a"; + + const count = countChar(str, char); + + expect(count).toEqual(0); +}); + +// Scenario: One Occurrence +// Given a string `str` +// And a single character `char` that occurs once in `str` +// When countChar is called +// Then it should return 1 +test("should count one occurrence of a character", () => { + const str = "abcde"; + const char = "a"; + + const count = countChar(str, char); + + expect(count).toEqual(1); +}); diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.js b/Sprint-3/2-practice-tdd/get-ordinal-number.js index f95d71db13..1a4629dff3 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.js @@ -1,5 +1,19 @@ function getOrdinalNumber(num) { - return "1st"; + const dictionary = { + 1: "st", + 2: "nd", + 3: "rd", + }; + + const lastTwoDigit = num % 100; + const lastDigit = num % 10; + + if (lastTwoDigit == 11 || lastTwoDigit == 12 || lastTwoDigit == 13) { + return `${num}` + `th`; + } + + const ending = dictionary[lastDigit] || "th"; + return `${num}${ending}`; } 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 adfa58560f..dd815a2208 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js @@ -18,3 +18,41 @@ 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, except numbers ending with 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(132)).toEqual("132nd"); +}); + +// Case 3: Numbers ending with 3, except numbers ending with 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(133)).toEqual("133rd"); +}); + +// Case 4: Numbers ending with 11, 12, or 13 should use "th" +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"); +}); + +// Case 5: All other endings should use "th" +test("should append 'th' for numbers that do not end in 1, 2, or 3", () => { + 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"); + expect(getOrdinalNumber(10)).toEqual("10th"); + expect(getOrdinalNumber(20)).toEqual("20th"); + expect(getOrdinalNumber(100)).toEqual("100th"); +}); diff --git a/Sprint-3/2-practice-tdd/repeat-str.js b/Sprint-3/2-practice-tdd/repeat-str.js index 2af0a2cea7..0a8809701d 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.js +++ b/Sprint-3/2-practice-tdd/repeat-str.js @@ -1,7 +1,19 @@ -function repeatStr() { +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 "Invalid count"; + } + + let new_String = ""; + + for (let counter = 0; counter < count; counter++) { + new_String = str + new_String; + } + + return new_String; } +console.log(repeatStr("hell", -1)); + 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 a3fc1196c4..261139cc7a 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.test.js +++ b/Sprint-3/2-practice-tdd/repeat-str.test.js @@ -21,12 +21,33 @@ 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 string 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('When count negative should return "Invalid count"', () => { + const str = "hello"; + const count = -1; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual("Invalid count"); +}); diff --git a/Sprint-3/3-dead-code/exercise-1.js b/Sprint-3/3-dead-code/exercise-1.js index 4d09f15fa9..209fadc9b8 100644 --- a/Sprint-3/3-dead-code/exercise-1.js +++ b/Sprint-3/3-dead-code/exercise-1.js @@ -1,17 +1,13 @@ // Find the instances of unreachable and redundant code - remove them! // The sayHello function should continue to work for any reasonable input it's given. -let testName = "Jerry"; +let testName = "Aman"; const greeting = "hello"; function sayHello(greeting, name) { - const greetingStr = greeting + ", " + name + "!"; return `${greeting}, ${name}!`; - console.log(greetingStr); } -testName = "Aman"; - const greetingMessage = sayHello(greeting, testName); console.log(greetingMessage); // 'hello, Aman!' diff --git a/Sprint-3/3-dead-code/exercise-2.js b/Sprint-3/3-dead-code/exercise-2.js index 56d7887c4c..3f54850b3f 100644 --- a/Sprint-3/3-dead-code/exercise-2.js +++ b/Sprint-3/3-dead-code/exercise-2.js @@ -2,7 +2,6 @@ // The countAndCapitalisePets function should continue to work for any reasonable input it's given, and you shouldn't modify the pets variable. const pets = ["parrot", "hamster", "horse", "dog", "hamster", "cat", "hamster"]; -const capitalisedPets = pets.map((pet) => pet.toUpperCase()); const petsStartingWithH = pets.filter((pet) => pet[0] === "h"); function logPets(petsArr) {