diff --git a/Sprint-3/1-key-implement/1-get-angle-type.js b/Sprint-3/1-key-implement/1-get-angle-type.js index 08d1f0cbaf..062d43e019 100644 --- a/Sprint-3/1-key-implement/1-get-angle-type.js +++ b/Sprint-3/1-key-implement/1-get-angle-type.js @@ -8,8 +8,21 @@ // Then, write the next test! :) Go through this process until all the cases are implemented function getAngleType(angle) { - if (angle === 90) return "Right angle"; - // read to the end, complete line 36, then pass your test here + if (angle === 90) { + return "Right angle"; + } + if (angle === 180) { + return "Straight angle"; + } + if (angle < 90) { + return "Acute angle"; + } + if (angle < 180) { + return "Obtuse angle"; + } + if (angle < 360) { + return "Reflex angle"; + } } // we're going to use this helper function to make our assertions easier to read @@ -44,13 +57,18 @@ assertEquals(acute, "Acute angle"); // Then the function should return "Obtuse angle" const obtuse = getAngleType(120); // ====> write your test here, and then add a line to pass the test in the function above +assertEquals(obtuse, "Obtuse angle"); // Case 4: Identify Straight Angles: // When the angle is exactly 180 degrees, // Then the function should return "Straight angle" // ====> write your test here, and then add a line to pass the test in the function above +const straight = getAngleType(180); +assertEquals(straight, "Straight angle"); // Case 5: Identify Reflex Angles: // When the angle is greater than 180 degrees and less than 360 degrees, // Then the function should return "Reflex angle" -// ====> write your test here, and then add a line to pass the test in the function above \ No newline at end of file +// ====> write your test here, and then add a line to pass the test in the function above +const reflex = getAngleType(210); +assertEquals(reflex, "Reflex angle"); \ No newline at end of file diff --git a/Sprint-3/1-key-implement/2-is-proper-fraction.js b/Sprint-3/1-key-implement/2-is-proper-fraction.js index 91583e9413..ed8536f1a1 100644 --- a/Sprint-3/1-key-implement/2-is-proper-fraction.js +++ b/Sprint-3/1-key-implement/2-is-proper-fraction.js @@ -8,7 +8,7 @@ // write one test at a time, and make it pass, build your solution up methodically function isProperFraction(numerator, denominator) { - if (numerator < denominator) return true; + return Math.abs(numerator / denominator) < 1; } // here's our helper again @@ -41,6 +41,7 @@ assertEquals(improperFraction, false); // Explanation: The fraction -4/7 is a proper fraction because the absolute value of the numerator (4) is less than the denominator (7). The function should return true. const negativeFraction = isProperFraction(-4, 7); // ====> complete with your assertion +assertEquals(negativeFraction, true); // Equal Numerator and Denominator check: // Input: numerator = 3, denominator = 3 @@ -48,6 +49,63 @@ const negativeFraction = isProperFraction(-4, 7); // Explanation: The fraction 3/3 is not a proper fraction because the numerator is equal to the denominator. The function should return false. const equalFraction = isProperFraction(3, 3); // ====> complete with your assertion +assertEquals(equalFraction, false); // Stretch: // What other scenarios could you test for? + +// Negative numerator with absolute value greater than denominator +// Input: numerator = -5 denominator = 2 +// Target output: false +// Explanation: The fraction -5/2 is a improper fraction because the absolute value of the numerator (-5) is greater than the denominator (2). The function should return false. +const negativeGreaterNumerator = isProperFraction(-5, 2); +assertEquals(negativeGreaterNumerator, false); + +// Negative denominator with absolute value greater than numerator +// Input: numerator = 2 denominator = -5 +// Target output: true +// Explanation: The fraction 2/-5 is a proper fraction because the numerator (2) is greater than the absolute value of the denominator (-5). The function should return true. +const negativeGreaterDenominator = isProperFraction(2, -5); +assertEquals(negativeGreaterDenominator, true); + +// Negative denominator with absolute value less than numerator +// Input: numerator = 5 denominator = -2 +// Target output: false +// Explanation: The fraction 5/-2 is a improper fraction because the numerator (5) is greater than the absolute value of the denominator (-2). The function should return true. +const negativeLessDenominator = isProperFraction(5, -2); +assertEquals(negativeLessDenominator, false); + +// Both negative with numerator less in absolute value +// Input: numerator = -2 denominator = -5 +// Target output: true +// Explanation: the fraction -2/-5 is a proper fraction because the absolute value of the numerator (-2) less than the absolute value of the denominator (-5). +const bothNegativeNumeratorLess = isProperFraction(-2, -5); +assertEquals(bothNegativeNumeratorLess, true); + +// Both negative with numerator greater in absolute value +// Input: numerator = -5 denominator = -2 +// Target output: false +// Explanation: the fraction -5/-2 is a improper fraction because the absolute value of the numerator(-5) greater than the absolute value of the denominator (-2). +const bothNegativeNumeratorGreater = isProperFraction(-5, -2); +assertEquals(bothNegativeNumeratorGreater, false); + +// Both negative with equal values +// Input: numerator = -2 denominator = -2 +// Target output: false +// Explanation: the fraction -2/-2 is a improper fraction because the numerator(-2) equal to the the denominator (-2). +const bothNegativeEqual = isProperFraction(-2, -2); +assertEquals(bothNegativeEqual, false); + +// Numerator is zero +// Input: numerator = 0 denominator = 2 +// Target output: true +// Explanation: the fraction 0/2 is a proper fraction because the numerator (0) less than the absolute value of the denominator (2). +const zeroNumerator = isProperFraction(0, 2); +assertEquals(zeroNumerator, true); + +// Denominator is zero +// Input: numerator = 2 denominator = 0 +// Target output: false +// Explanation: the fraction 2/0 is a improper fraction because the absolute value of the numerator (2) greater than the denominator (0). +const zeroDenominator = isProperFraction(2, 0); +assertEquals(zeroDenominator, false); \ No newline at end of file diff --git a/Sprint-3/1-key-implement/3-get-card-value.js b/Sprint-3/1-key-implement/3-get-card-value.js index aa1cc9f90b..9ad6a5e0a1 100644 --- a/Sprint-3/1-key-implement/3-get-card-value.js +++ b/Sprint-3/1-key-implement/3-get-card-value.js @@ -8,7 +8,27 @@ // write one test at a time, and make it pass, build your solution up methodically // just make one change at a time -- don't rush -- programmers are deep and careful thinkers function getCardValue(card) { - if (rank === "A") return 11; + const rank = card.slice(0, card.length - 1); + switch (rank) { + case "2": + case "3": + case "4": + case "5": + case "6": + case "7": + case "8": + case "9": + return Number(rank); + case "10": + case "J": + case "Q": + case "K": + return 10; + case "A": + return 11; + default: + throw new Error("Invalid card rank"); + } } // You need to write assertions for your function to check it works in different cases @@ -25,27 +45,60 @@ function assertEquals(actualOutput, targetOutput) { // Given a card string in the format "A♠" (representing a card in blackjack - the last character will always be an emoji for a suit, and all characters before will be a number 2-10, or one letter of J, Q, K, A), // When the function getCardValue is called with this card string as input, // Then it should return the numerical card value -const aceofSpades = getCardValue("A♠"); -assertEquals(aceofSpades, 11); // Handle Number Cards (2-10): // Given a card with a rank between "2" and "9", // When the function is called with such a card, // Then it should return the numeric value corresponding to the rank (e.g., "5" should return 5). -const fiveofHearts = getCardValue("5♥"); +const fiveOfHearts = getCardValue("5♥"); +const twoOfHearts = getCardValue("2♥"); +const threeOfHearts = getCardValue("3♥"); +const fourOfHearts = getCardValue("4♥"); +const sixOfHearts = getCardValue("6♥"); +const sevenOfHearts = getCardValue("7♥"); +const eightOfHearts = getCardValue("8♥"); +const nineOfHearts = getCardValue("9♥"); // ====> write your test here, and then add a line to pass the test in the function above +assertEquals(fiveOfHearts, 5); +assertEquals(twoOfHearts, 2); +assertEquals(threeOfHearts, 3); +assertEquals(fourOfHearts, 4); +assertEquals(sixOfHearts, 6); +assertEquals(sevenOfHearts, 7); +assertEquals(eightOfHearts, 8); +assertEquals(nineOfHearts, 9); // Handle Face Cards (J, Q, K): // Given a card with a rank of "10," "J," "Q," or "K", // When the function is called with such a card, // Then it should return the value 10, as these cards are worth 10 points each in blackjack. +const tenOfClubs = getCardValue("10♣"); +const jackOfClubs = getCardValue("J♣"); +const queenOfClubs = getCardValue("Q♣"); +const kingOfClubs = getCardValue("K♣"); +assertEquals(tenOfClubs, 10); +assertEquals(jackOfClubs, 10); +assertEquals(queenOfClubs, 10); +assertEquals(kingOfClubs, 10); // Handle Ace (A): // Given a card with a rank of "A", // When the function is called with an Ace, // Then it should, by default, assume the Ace is worth 11 points, which is a common rule in blackjack. +const aceOfSpades = getCardValue("A♠"); +assertEquals(aceOfSpades, 11); // Handle Invalid Cards: // Given a card with an invalid rank (neither a number nor a recognized face card), // When the function is called with such a card, // Then it should throw an error indicating "Invalid card rank." + +const oneOfDiamonds = "1♦"; +const twentyUnoOfDiamonds = "21♦"; +const hundredOfDiamonds = "100♦"; +const catOfDiamonds = "C♦"; + +getCardValue(oneOfDiamonds); +getCardValue(twentyUnoOfDiamonds); +getCardValue(hundredOfDiamonds); +getCardValue(catOfDiamonds); \ No newline at end of file diff --git a/Sprint-3/2-mandatory-rewrite/1-get-angle-type.js b/Sprint-3/2-mandatory-rewrite/1-get-angle-type.js index d61254bd73..5c0033dcc9 100644 --- a/Sprint-3/2-mandatory-rewrite/1-get-angle-type.js +++ b/Sprint-3/2-mandatory-rewrite/1-get-angle-type.js @@ -1,7 +1,20 @@ function getAngleType(angle) { if (angle === 90) return "Right angle"; - // replace with your completed function from key-implement - + if (angle === 90) { + return "Right angle"; + } + if (angle === 180) { + return "Straight angle"; + } + if (angle < 90) { + return "Acute angle"; + } + if (angle < 180) { + return "Obtuse angle"; + } + if (angle < 360) { + return "Reflex angle"; + } } diff --git a/Sprint-3/2-mandatory-rewrite/1-get-angle-type.test.js b/Sprint-3/2-mandatory-rewrite/1-get-angle-type.test.js index b62827b7c8..65def21dc0 100644 --- a/Sprint-3/2-mandatory-rewrite/1-get-angle-type.test.js +++ b/Sprint-3/2-mandatory-rewrite/1-get-angle-type.test.js @@ -1,24 +1,24 @@ const getAngleType = require("./1-get-angle-type"); -test("should identify right angle (90°)", () => { +test("should identify right angle (angle = 90°)", () => { expect(getAngleType(90)).toEqual("Right angle"); }); // REPLACE the comments with the tests // make your test descriptions as clear and readable as possible -// Case 2: Identify Acute Angles: -// When the angle is less than 90 degrees, -// Then the function should return "Acute angle" +test("Should identify acute angles (angle < 90°)", () => { + expect(getAngleType(45)).toEqual("Acute angle"); +}); -// Case 3: Identify Obtuse Angles: -// When the angle is greater than 90 degrees and less than 180 degrees, -// Then the function should return "Obtuse angle" +test("Should identify obtuse angles (90° < angle < 180°)", () => { + expect(getAngleType(120)).toEqual("Obtuse angle"); +}); -// Case 4: Identify Straight Angles: -// When the angle is exactly 180 degrees, -// Then the function should return "Straight angle" +test("Should identify straight angle (angle = 180°)", () => { + expect(getAngleType(180)).toEqual("Straight angle"); +}); -// Case 5: Identify Reflex Angles: -// When the angle is greater than 180 degrees and less than 360 degrees, -// Then the function should return "Reflex angle" +test("Should identify reflex angle (180° < angle < 360°)", () => { + expect(getAngleType(210)).toEqual("Reflex angle"); +}); \ No newline at end of file diff --git a/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.js b/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.js index 9836fe3985..cf91e9d441 100644 --- a/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.js +++ b/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.js @@ -1,6 +1,5 @@ function isProperFraction(numerator, denominator) { - if (numerator < denominator) return true; - // add your completed function from key-implement here + return Math.abs(numerator / denominator) < 1; } module.exports = isProperFraction; \ No newline at end of file diff --git a/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.test.js b/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.test.js index ff1cc8173c..3ef1fb2cb6 100644 --- a/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.test.js +++ b/Sprint-3/2-mandatory-rewrite/2-is-proper-fraction.test.js @@ -4,8 +4,46 @@ test("should return true for a proper fraction", () => { expect(isProperFraction(2, 3)).toEqual(true); }); -// Case 2: Identify Improper Fractions: +test("Should return false for improper fraction", () => { + expect(isProperFraction(3, 2)).toEqual(false); +}); + +test("Should return true for a proper negative fraction", () => { + expect(isProperFraction(-2, 3)).toEqual(true); +}); + +test("Should return false for equal positive numerator and denominator", () => { + expect(isProperFraction(2, 2)).toEqual(false); +}); + +test("Should return false for a negative improper fraction", () => { + expect(isProperFraction(-3, 2)).toEqual(false); +}); + +test("Should return true for a proper fraction with negative denominator", () => { + expect(isProperFraction(2, -3)).toEqual(true); +}); -// Case 3: Identify Negative Fractions: +test("Should return false for an improper fraction with negative denominator", () => { + expect(isProperFraction(3, -2)).toEqual(false); +}); + +test("Should return true for a proper fraction with both negative parts", () => { + expect(isProperFraction(-2, -3)).toEqual(true); +}); + +test("Should return false false for an improper fraction with both negative parts", () => { + expect(isProperFraction(-3, -2)).toEqual(false); +}); + +test("Should return false for negative equal numerator and denominator", () => { + expect(isProperFraction(-2, -2)).toEqual(false); +}); + +test("Should return true for a fraction with zero numerator", () => { + expect(isProperFraction(0, 2)).toEqual(true); +}); -// Case 4: Identify Equal Numerator and Denominator: +test("Should return false for a fraction with zero denominator", () => { + expect(isProperFraction(2, 0)).toEqual(false); +}); \ No newline at end of file diff --git a/Sprint-3/2-mandatory-rewrite/3-get-card-value.js b/Sprint-3/2-mandatory-rewrite/3-get-card-value.js index 0d95d3736f..703becb2c4 100644 --- a/Sprint-3/2-mandatory-rewrite/3-get-card-value.js +++ b/Sprint-3/2-mandatory-rewrite/3-get-card-value.js @@ -1,5 +1,24 @@ function getCardValue(card) { - // replace with your code from key-implement - return 11; + const rank = card.slice(0, card.length - 1); + switch (rank) { + case "2": + case "3": + case "4": + case "5": + case "6": + case "7": + case "8": + case "9": + case "10": + return Number(rank); + case "J": + case "Q": + case "K": + return 10; + case "A": + return 11; + default: + throw new Error("Invalid card rank"); + } } module.exports = getCardValue; \ No newline at end of file diff --git a/Sprint-3/2-mandatory-rewrite/3-get-card-value.test.js b/Sprint-3/2-mandatory-rewrite/3-get-card-value.test.js index 03a8e2f341..9d5cf6e974 100644 --- a/Sprint-3/2-mandatory-rewrite/3-get-card-value.test.js +++ b/Sprint-3/2-mandatory-rewrite/3-get-card-value.test.js @@ -1,11 +1,90 @@ const getCardValue = require("./3-get-card-value"); -test("should return 11 for Ace of Spades", () => { - const aceofSpades = getCardValue("A♠"); - expect(aceofSpades).toEqual(11); - }); - // Case 2: Handle Number Cards (2-10): +test("Should return 2 for Two of Hearts", () => { + const twoOfHearts = "2♥"; + expect(getCardValue(twoOfHearts)).toEqual(2); +}); + +test("Should return 3 for Three of Hearts", () => { + const threeOfHearts = "3♥"; + expect(getCardValue(threeOfHearts)).toEqual(3); +}); + +test("Should return 4 for Four of Hearts", () => { + const fourOfHearts = "4♥"; + expect(getCardValue(fourOfHearts)).toEqual(4); +}); + +test("Should return 5 for Five of Hearts", () => { + const fiveOfHearts = "5♥"; + expect(getCardValue(fiveOfHearts)).toEqual(5); +}); + +test("Should return 6 for Six of Hearts", () => { + const sixOfHearts = "6♥"; + expect(getCardValue(sixOfHearts)).toEqual(6); +}); + +test("Should return 7 for Seven of Hearts", () => { + const sevenOfHearts = "7♥"; + expect(getCardValue(sevenOfHearts)).toEqual(7); +}); + +test("Should return 8 for Eight of Hearts", () => { + const eightOfHearts = "8♥"; + expect(getCardValue(eightOfHearts)).toEqual(8); +}); + +test("Should return 9 for Nine of Hearts", () => { + const nineOfHearts = "9♥"; + expect(getCardValue(nineOfHearts)).toEqual(9); +}); + +test("Should return 10 for Ten of Hearts", () => { + const tenOfClubs = "10♥"; + expect(getCardValue(tenOfClubs)).toEqual(10); +}); + // Case 3: Handle Face Cards (J, Q, K): +test("Should return 10 for Jack of Clubs", () => { + const jackOfClubs = "J♣"; + expect(getCardValue(jackOfClubs)).toEqual(10); +}); + +test("Should return 10 for Queen of Clubs", () => { + const queenOfClubs = "Q♣"; + expect(getCardValue(queenOfClubs)).toEqual(10); +}); + +test("Should return 10 for King of Clubs", () => { + const kingOfClubs = "K♣"; + expect(getCardValue(kingOfClubs)).toEqual(10); +}); + // Case 4: Handle Ace (A): +test("Should return 11 for Ace of Spades", () => { + const aceOfSpades = getCardValue("A♠"); + expect(aceOfSpades).toEqual(11); +}); + // Case 5: Handle Invalid Cards: +test("Should throw the 'Invalid card rank' error for One of Diamonds", () => { + const oneOfDiamonds = "1♦"; + expect(() => getCardValue(oneOfDiamonds)).toThrowError("Invalid card rank"); +}); + +test("Should throw the 'Invalid card rank' error for One of Diamonds", () => { + const twentyOneOfDiamonds = "21♦"; + expect(() => getCardValue(twentyOneOfDiamonds)).toThrowError("Invalid card rank"); +}); + +test("Should throw the 'Invalid card rank' error for One of Diamonds", () => { + const oneHundredOfDiamonds = "100♦"; + expect(() => getCardValue(oneHundredOfDiamonds)).toThrowError("Invalid card rank"); +}); + +test("Should throw the 'Invalid card rank' error for One of Diamonds", () => { + const catOfDiamonds = "C♦"; + expect(() => getCardValue(catOfDiamonds)).toThrowError("Invalid card rank"); +}); \ No newline at end of file diff --git a/Sprint-3/3-mandatory-practice/implement/count.js b/Sprint-3/3-mandatory-practice/implement/count.js index fce2496501..3c371d4ed4 100644 --- a/Sprint-3/3-mandatory-practice/implement/count.js +++ b/Sprint-3/3-mandatory-practice/implement/count.js @@ -1,5 +1,11 @@ function countChar(stringOfCharacters, findCharacter) { - return 5 + let count = 0; + for (let char of stringOfCharacters) { + if (char === findCharacter) { + count++; + } + } + return count; } module.exports = countChar; \ No newline at end of file diff --git a/Sprint-3/3-mandatory-practice/implement/count.test.js b/Sprint-3/3-mandatory-practice/implement/count.test.js index 42baf4b4b0..2c1c032e2c 100644 --- a/Sprint-3/3-mandatory-practice/implement/count.test.js +++ b/Sprint-3/3-mandatory-practice/implement/count.test.js @@ -22,3 +22,10 @@ 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 for string without the searching character", () => { + const str = "AAAAA"; + const char = "a"; + const count = countChar(str, char); + expect(count).toEqual(0); +}); diff --git a/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.js b/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.js index 24f528b0d3..1cfb230c19 100644 --- a/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.js +++ b/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.js @@ -1,5 +1,42 @@ function getOrdinalNumber(num) { - return "1st"; + if (typeof num !== "number") { + throw new TypeError(`'${num}' is not a number.`); + } + + if (!Number.isInteger(num)) { + throw new RangeError(`'${num}' is float`); + } + + if (num < 1) { + throw new RangeError(`'${num}' is not natural number`); + } + + const lastDigit = num % 10; + const last2Digits = num % 100; + + console.log(`${num} ${lastDigit} ${last2Digits}`); + if (lastDigit === 1) { + if (last2Digits === 11) { + return num + "th"; + } + return num + "st"; + } + + if (lastDigit === 2) { + if (last2Digits === 12) { + return num + "th"; + } + return num + "nd"; + } + + if (lastDigit === 3) { + if (last2Digits === 13) { + return num + "th"; + } + return num + "rd"; + } + + return num + "th"; } module.exports = getOrdinalNumber; \ No newline at end of file diff --git a/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.test.js b/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.test.js index 6d55dfbb40..700f2546e6 100644 --- a/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.test.js +++ b/Sprint-3/3-mandatory-practice/implement/get-ordinal-number.test.js @@ -4,10 +4,131 @@ const getOrdinalNumber = require("./get-ordinal-number"); // continue testing and implementing getOrdinalNumber for additional cases // Write your tests using Jest - remember to run your tests often for continual feedback -// Case 1: Identify the ordinal number for 1 -// When the number is 1, -// Then the function should return "1st" +// Case 1: Identify the ordinal for numbers ending in 1. Should return ordinals ending in '1st' +// except numbers ending in 11 for which should return ordinals ending in '11th' -test("should return '1st' for 1", () => { - expect(getOrdinalNumber(1)).toEqual("1st"); - }); +test("Should return '1st' for 1", () => { + expect(getOrdinalNumber(1)).toEqual("1st"); +}); + +test("Should return '11th' for 11", () => { + expect(getOrdinalNumber(11)).toEqual("11th"); +}) + +test("Should return '21st' for 21", () => { + expect(getOrdinalNumber(21)).toEqual("21st"); +}); + +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 '121st' for 121", () => { + expect(getOrdinalNumber(121)).toEqual("121st"); +}); + +// Case 2: Identify the ordinal for numbers ending in 2. Should return ordinals ending in '2nd' +// except numbers ending in 12 for which should return ordinals ending in '12th' + +test("Should return '2nd' for 2", () => { + expect(getOrdinalNumber(2)).toEqual("2nd"); +}); + +test("Should return '12th' for 12", () => { + expect(getOrdinalNumber(12)).toEqual("12th"); +}); + +test("Should return '22nd' for 22", () => { + expect(getOrdinalNumber(22)).toEqual("22nd"); +}); + +test("Should return '102nd' for 102", () => { + expect(getOrdinalNumber(102)).toEqual("102nd"); +}); + +test("Should return '112th' for 112", () => { + expect(getOrdinalNumber(112)).toEqual("112th"); +}); + +test("Should return '122nd' for 122", () => { + expect(getOrdinalNumber(122)).toEqual("122nd"); +}); + +// Case 3: Identify the ordinal for numbers ending in 3. Should return ordinals ending in '3rd' +// except numbers ending in 13 for which should return ordinals ending in '13th' + +test("Should return '3rd' for 3", () => { + expect(getOrdinalNumber(3)).toEqual("3rd"); +}); + +test("Should return '13th' for 13", () => { + expect(getOrdinalNumber(13)).toEqual("13th"); +}); + +test("Should return '23rd' for 23", () => { + expect(getOrdinalNumber(23)).toEqual("23rd"); +}); + +test("Should return '103rd' for 103", () => { + expect(getOrdinalNumber(103)).toEqual("103rd"); +}); + +test("Should return '113th' for 113", () => { + expect(getOrdinalNumber(113)).toEqual("113th"); +}); + +test("Should return '123rd' for 123", () => { + expect(getOrdinalNumber(123)).toEqual("123rd"); +}); + +// Case 3: Identify the ordinal for numbers ending in 4 to 0. Should return ordinals ending in 'th'. + +test("Should return '4th' for 4", () => { + expect(getOrdinalNumber(4)).toEqual("4th"); +}); + +test("Should return '15th' for 15", () => { + expect(getOrdinalNumber(15)).toEqual("15th"); +}); + +test("Should return '26th' for 26", () => { + expect(getOrdinalNumber(26)).toEqual("26th"); +}); + +test("Should return '107th' for 107", () => { + expect(getOrdinalNumber(107)).toEqual("107th"); +}); + +test("Should return '288th' for 288", () => { + expect(getOrdinalNumber(288)).toEqual("288th"); +}); + +test("Should return '1039th' for 1039", () => { + expect(getOrdinalNumber(1039)).toEqual("1039th"); +}); + +//Case 4: Identify invalid type of argument. + +test("Should throw TypeError if num is not Number", () => { + expect(() => {getOrdinalNumber("10")}).toThrow(); +}); + +//Case 5: Identify float argument. + +test("Should throw RangeError if num is float", () => { + expect(() => {getOrdinalNumber(2.71)}).toThrow(); +}); + +//Case 6: Identify non natural argument + +test("Should throw Range error for 0", () => { + expect(() => {getOrdinalNumber(0)}).toThrow(); +}); + +test("Should throw Range error for negative num", () => { + expect(() => {getOrdinalNumber(-1);}).toThrow(); +}); \ No newline at end of file diff --git a/Sprint-3/3-mandatory-practice/implement/repeat.js b/Sprint-3/3-mandatory-practice/implement/repeat.js index 621f9bd35b..28e67af671 100644 --- a/Sprint-3/3-mandatory-practice/implement/repeat.js +++ b/Sprint-3/3-mandatory-practice/implement/repeat.js @@ -1,5 +1,5 @@ -function repeat() { - return "hellohellohello"; +function repeat(stringToRepeat, repeatCount) { + return stringToRepeat.repeat(repeatCount); } module.exports = repeat; \ No newline at end of file diff --git a/Sprint-3/3-mandatory-practice/implement/repeat.test.js b/Sprint-3/3-mandatory-practice/implement/repeat.test.js index 8a4ab42efc..822bb93a00 100644 --- a/Sprint-3/3-mandatory-practice/implement/repeat.test.js +++ b/Sprint-3/3-mandatory-practice/implement/repeat.test.js @@ -21,12 +21,32 @@ 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 the original string for count = 1", () => { + const str = "hello"; + const count = 1; + const repeatedString = repeat(str, count); + expect(repeatedString).toEqual(str); +}); + // 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 for count = 0", () => { + const str = "hello"; + const count = 0; + const repeatedString = repeat(str, count); + expect(repeatedString).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 throw a Range error for a negative count", () => { + const str = "hello"; + const count = -1; + expect(() => {repeat(str, count)}).toThrow(); +}); \ No newline at end of file diff --git a/Sprint-3/4-stretch-investigate/card-validator.js b/Sprint-3/4-stretch-investigate/card-validator.js new file mode 100644 index 0000000000..507ac5e92d --- /dev/null +++ b/Sprint-3/4-stretch-investigate/card-validator.js @@ -0,0 +1,35 @@ +function cardValidator(cardNumber) { + //checking the card number length + if (cardNumber.length !== 16) { + return false; + } + + const digitsRegEx = /\d/; + const lastChar = cardNumber[cardNumber.length - 1]; + + //checking the card number last character is even digit + if (digitsRegEx.test(lastChar) && Number(lastChar) % 2 != 0) { + return false; + } + + let digitsSum = 0; + + for (let i = 0; i < cardNumber.length; i++) { + const currentChar = cardNumber[i]; + //checking all the card number characters are digits + if (!digitsRegEx.test(currentChar)) { + return false; + } + //summing digits of the card number + digitsSum += Number(currentChar); + } + //checking sum of digits of the card number + if (digitsSum < 16) { + return false; + } + //returning true if all checks passed + return true; +} + + +module.exports = cardValidator; \ No newline at end of file diff --git a/Sprint-3/4-stretch-investigate/card-validator.test.js b/Sprint-3/4-stretch-investigate/card-validator.test.js new file mode 100644 index 0000000000..42318c1037 --- /dev/null +++ b/Sprint-3/4-stretch-investigate/card-validator.test.js @@ -0,0 +1,29 @@ +const isValidCard = require("./card-validator"); + +test("Card number should be 16 characters length.", () => { + const cardNumber = "000044440000222"; + const targetOutput = isValidCard(cardNumber); + + expect(targetOutput).toBe(false); +}) + +test("Card number should not contains non-digit characters", () => { + const cardNumber = "000044440000a222"; + const targetOutput = isValidCard(cardNumber); + + expect(targetOutput).toBe(false); +}); + +test("Sum of the card number digits should not be less than 16", () => { + const cardNumber = "0000111100002222"; + const targetOutput = isValidCard(cardNumber); + + expect(targetOutput).toBe(false); +}) + +test("Card number should ends in even digit", () => { + const cardNumber = "0000444400002221"; + const targetOutput = isValidCard(cardNumber); + + expect(targetOutput).toBe(false); +}) \ No newline at end of file diff --git a/Sprint-3/4-stretch-investigate/find.js b/Sprint-3/4-stretch-investigate/find.js index c7e79a2f21..4b7e7ab87f 100644 --- a/Sprint-3/4-stretch-investigate/find.js +++ b/Sprint-3/4-stretch-investigate/find.js @@ -20,6 +20,14 @@ console.log(find("code your future", "z")); // Pay particular attention to the following: // a) How the index variable updates during the call to find +// In the begin of function after the declaration the index variable initialize with value 0. +// Then in the end of the every iteration of the while loop it increased by 1. + // b) What is the if statement used to check +// The if statement checks the value of the index variable exceeds the string last character iindex. + // c) Why is index++ being used? +// Because we the while loop without a counter instead of a for loop with the known count of iteration. + // d) What is the condition index < str.length used for? +// This condition indicate reaching of the end of the given string and exiting from the while loop. diff --git a/Sprint-3/4-stretch-investigate/password-validator.js b/Sprint-3/4-stretch-investigate/password-validator.js index b55d527dba..9932fbb917 100644 --- a/Sprint-3/4-stretch-investigate/password-validator.js +++ b/Sprint-3/4-stretch-investigate/password-validator.js @@ -1,6 +1,42 @@ -function passwordValidator(password) { - return password.length < 5 ? false : true -} +function passwordValidator(password, previousPasswords) { + for (let i = 0; i < previousPasswords.length; i++) { + const currentPreviousPassword = previousPasswords[i]; + + if (password === currentPreviousPassword) { + return false + } + } + if (password.length < 5) { + return false; + } + + const uppercaseLettersRegEx = /[A-Z]/; + const lowercaseLettersRegEx = /[a-z]/; + const digitsRegEx = /[0-9]/; + const nonAlphanumericSymbolsRegEx = /[!#\$%\.\*&]/; + let hasUppercaseLetter = false; + let hasLowercaseLetter = false + let hasDigit = false; + let hasNonAlphanumericSymbol = false; + + for (let i = 0; i < password.length; i++) { + const currentSymbol = password[i]; + if (uppercaseLettersRegEx.test(currentSymbol)) { + hasUppercaseLetter = true; + } + if (lowercaseLettersRegEx.test(currentSymbol)) { + hasLowercaseLetter = true; + } + if (digitsRegEx.test(currentSymbol)) { + hasDigit = true; + } + if (nonAlphanumericSymbolsRegEx.test(currentSymbol)) { + hasNonAlphanumericSymbol = true; + } + } + return hasUppercaseLetter && hasLowercaseLetter && hasDigit && hasNonAlphanumericSymbol; +} +passwordValidator("Bcd1$", ["Bcd1$"]); module.exports = passwordValidator; \ No newline at end of file diff --git a/Sprint-3/4-stretch-investigate/password-validator.test.js b/Sprint-3/4-stretch-investigate/password-validator.test.js index 8fa3089d6b..aaa1dce379 100644 --- a/Sprint-3/4-stretch-investigate/password-validator.test.js +++ b/Sprint-3/4-stretch-investigate/password-validator.test.js @@ -15,12 +15,48 @@ To be valid, a password must: You must breakdown this problem in order to solve it. Find one test case first and get that working */ const isValidPassword = require("./password-validator"); -test("password has at least 5 characters", () => { - // Arrange - const password = "12345"; - // Act - const result = isValidPassword(password); - // Assert - expect(result).toEqual(true); -} -); \ No newline at end of file +const previousPasswords = ["Bcd1$"]; + +test("Password should have at least 5 characters", () => { + // Arrange + const password = "Ab1$"; + // Act + const targetOutput = isValidPassword(password, previousPasswords); + // Assert + expect(targetOutput).toBe(false); +}); + +test("Password should have at least 1 English uppercase letter", () => { + const password = "abc1#"; + const targetOutput = isValidPassword(password, previousPasswords); + + expect(targetOutput).toBe(false); +}); + +test("Password should have at least 1 English lowercase letter", () => { + const password = "ABC1&"; + const targetOutput = isValidPassword(password, previousPasswords); + + expect(targetOutput).toBe(false); +}); + +test("Password should have at least 1 digit", () => { + const password = "Abcd*"; + const targetOutput = isValidPassword(password, previousPasswords); + + expect(targetOutput).toBe(false); +}) + +test("Password should have at least 1 non-alphanumeric symbol ('!', '#', '$', '%', '.', '*', '&')", () => { + const password = "Abcd1"; + const targetOutput = isValidPassword(password, previousPasswords); + + expect(targetOutput).toBe(false); +}) + +test("Password should not be in previous passwords array", () => { + const password = "Bcd1$"; + const targetOutput = isValidPassword(password, previousPasswords); + + expect(targetOutput).toBe(false); +}); \ No newline at end of file