diff --git a/.gitignore b/.gitignore index bde36e530..a34d061c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,11 @@ node_modules +package*.json .DS_Store .vscode -**/.DS_Store \ No newline at end of file +**/.DS_Store +.github/FUNDING.yml +.github/workflows/validate-pr-metadata.yml +.npmrc +.prettierrc +.vscode/extensions.json + 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 9e05a871e..471f25f99 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 @@ -1,3 +1,195 @@ +/** +// Implement a function getAngleType +// +// When given an angle in degrees, it should return a string indicating the type of angle: +// - "Acute angle" for angles greater than 0° and less than 90° +// - "Right angle" for exactly 90° +// - "Obtuse angle" for angles greater than 90° and less than 180° +// - "Straight angle" for exactly 180° +// - "Reflex angle" for angles greater than 180° and less than 360° +// - "Invalid angle" for angles outside the valid range. + +// Assumption: The parameter is a valid number. (You do not need to handle non-numeric inputs.) + +// Acceptance criteria: +// After you have implemented the function, write tests to cover all the cases, and +// execute the code to ensure all tests pass. + +/** + * function getAngleType(angle) { + * // TODO: Implement this function + *} +*/ + +// The line below allows us to load the getAngleType function into tests in other files. +// This will be useful in the "rewrite tests with jest" step. + +/** + * module.exports = getAngleType; + */ + +// This helper function is written to make our assertions easier to read. +// If the actual output matches the target output, the test will pass + +/** + *function assertEquals(actualOutput, targetOutput) { + * console.assert( + * actualOutput === targetOutput, + * `Expected ${actualOutput} to equal ${targetOutput}` + * ); + *} + */ + +// TODO: Write tests to cover all cases, including boundary and invalid cases. +// Example: Identify Right Angles + +/** + * const right = getAngleType(90); + * assertEquals(right, "Right angle"); + */ + +// Solution: +// Implement a function getAngleType +// +// When given an angle in degrees, it should return a string indicating the type of angle: +// - "Acute angle" for angles greater than 0° and less than 90° +// - "Right angle" for exactly 90° +// - "Obtuse angle" for angles greater than 90° and less than 180° +// - "Straight angle" for exactly 180° +// - "Reflex angle" for angles greater than 180° and less than 360° +// - "Invalid angle" for angles outside the valid range. + +// Assumption: The parameter is a valid number. (You do not need to handle non-numeric inputs.) + +// Acceptance criteria: +// After you have implemented the function, write tests to cover all the cases, and +// execute the code to ensure all tests pass. + +/** + * function getAngleType(angle) { + // Check for invalid angles (outside 0-360 range) + if (angle <= 0 || angle >= 360) { + return "Invalid angle"; + } + + // Check for specific angle types + if (angle > 0 && angle < 90) { + return "Acute angle"; + } else if (angle === 90) { + return "Right angle"; + } else if (angle > 90 && angle < 180) { + return "Obtuse angle"; + } else if (angle === 180) { + return "Straight angle"; + } else if (angle > 180 && angle < 360) { + return "Reflex angle"; + } + + // This line should theoretically never be reached given our conditions, + // but included as a safety net + return "Invalid angle"; + *} + */ + +// The line below allows us to load the getAngleType function into tests in other files. +// This will be useful in the "rewrite tests with jest" step. +module.exports = getAngleType; + +// This helper function is written to make our assertions easier to read. +// If the actual output matches the target output, the test will pass + +/** + function assertEquals(actualOutput, targetOutput) { + console.assert( + actualOutput === targetOutput, + `Expected ${actualOutput} to equal ${targetOutput}` + ); + } + */ + +// Write tests to cover all cases, including boundary and invalid cases. +console.log("Running tests for getAngleType function...\n"); + +/** +// Test 1: Acute angles +console.log("Testing Acute angles:"); +const acute1 = getAngleType(45); +assertEquals(acute1, "Acute angle"); + +const acute2 = getAngleType(89); +assertEquals(acute2, "Acute angle"); + +const acute3 = getAngleType(1); +assertEquals(acute3, "Acute angle"); + +// Test 2: Right angle +console.log("\nTesting Right angle:"); +const right = getAngleType(90); +assertEquals(right, "Right angle"); + +// Test 3: Obtuse angles +console.log("\nTesting Obtuse angles:"); +const obtuse1 = getAngleType(95); +assertEquals(obtuse1, "Obtuse angle"); + +const obtuse2 = getAngleType(135); +assertEquals(obtuse2, "Obtuse angle"); + +const obtuse3 = getAngleType(179); +assertEquals(obtuse3, "Obtuse angle"); + +// Test 4: Straight angle +console.log("\nTesting Straight angle:"); +const straight = getAngleType(180); +assertEquals(straight, "Straight angle"); + +// Test 5: Reflex angles +console.log("\nTesting Reflex angles:"); +const reflex1 = getAngleType(185); +assertEquals(reflex1, "Reflex angle"); + +const reflex2 = getAngleType(270); +assertEquals(reflex2, "Reflex angle"); + +const reflex3 = getAngleType(359); +assertEquals(reflex3, "Reflex angle"); + +// Test 6: Invalid angles (boundary cases and outside range) +console.log("\nTesting Invalid angles:"); + +// Boundary cases at 0 and 360 +const invalid1 = getAngleType(0); +assertEquals(invalid1, "Invalid angle"); + +const invalid2 = getAngleType(360); +assertEquals(invalid2, "Invalid angle"); + +// Negative angles +const invalid3 = getAngleType(-45); +assertEquals(invalid3, "Invalid angle"); + +const invalid4 = getAngleType(-90); +assertEquals(invalid4, "Invalid angle"); + +const invalid5 = getAngleType(-180); +assertEquals(invalid5, "Invalid angle"); + +// Angles greater than 360 +const invalid6 = getAngleType(365); +assertEquals(invalid6, "Invalid angle"); + +const invalid7 = getAngleType(400); +assertEquals(invalid7, "Invalid angle"); + +const invalid8 = getAngleType(720); +assertEquals(invalid8, "Invalid angle"); + +console.log("\nAll tests completed!"); +* +*/ + +// Writing by me @Carlos Abreu + // Implement a function getAngleType // // When given an angle in degrees, it should return a string indicating the type of angle: @@ -15,7 +207,27 @@ // execute the code to ensure all tests pass. function getAngleType(angle) { - // TODO: Implement this function + // Check for invalid angles (outside 0-360 range) + if (angle <= 0 || angle >= 360) { + return "Invalid angle"; + } + + // Check for specific angle types + if (angle > 0 && angle < 90) { + return "Acute angle"; + } else if (angle === 90) { + return "Right angle"; + } else if (angle > 90 && angle < 180) { + return "Obtuse angle"; + } else if (angle === 180) { + return "Straight angle"; + } else if (angle > 180 && angle < 360) { + return "Reflex angle"; + } + + // This line should theoretically never be reached given our conditions, + // but included as a safety net + return "Invalid angle"; } // The line below allows us to load the getAngleType function into tests in other files. @@ -31,7 +243,81 @@ function assertEquals(actualOutput, targetOutput) { ); } -// TODO: Write tests to cover all cases, including boundary and invalid cases. -// Example: Identify Right Angles +// Write tests to cover all cases, including boundary and invalid cases. +console.log("Running tests for getAngleType function...\n"); + +// Test 1: Acute angles +console.log("Testing Acute angles:"); +const acute1 = getAngleType(45); +assertEquals(acute1, "Acute angle"); + +const acute2 = getAngleType(89); +assertEquals(acute2, "Acute angle"); + +const acute3 = getAngleType(1); +assertEquals(acute3, "Acute angle"); + +// Test 2: Right angle +console.log("\nTesting Right angle:"); const right = getAngleType(90); assertEquals(right, "Right angle"); + +// Test 3: Obtuse angles +console.log("\nTesting Obtuse angles:"); +const obtuse1 = getAngleType(95); +assertEquals(obtuse1, "Obtuse angle"); + +const obtuse2 = getAngleType(135); +assertEquals(obtuse2, "Obtuse angle"); + +const obtuse3 = getAngleType(179); +assertEquals(obtuse3, "Obtuse angle"); + +// Test 4: Straight angle +console.log("\nTesting Straight angle:"); +const straight = getAngleType(180); +assertEquals(straight, "Straight angle"); + +// Test 5: Reflex angles +console.log("\nTesting Reflex angles:"); +const reflex1 = getAngleType(185); +assertEquals(reflex1, "Reflex angle"); + +const reflex2 = getAngleType(270); +assertEquals(reflex2, "Reflex angle"); + +const reflex3 = getAngleType(359); +assertEquals(reflex3, "Reflex angle"); + +// Test 6: Invalid angles (boundary cases and outside range) +console.log("\nTesting Invalid angles:"); + +// Boundary cases at 0 and 360 +const invalid1 = getAngleType(0); +assertEquals(invalid1, "Invalid angle"); + +const invalid2 = getAngleType(360); +assertEquals(invalid2, "Invalid angle"); + +// Negative angles +const invalid3 = getAngleType(-45); +assertEquals(invalid3, "Invalid angle"); + +const invalid4 = getAngleType(-90); +assertEquals(invalid4, "Invalid angle"); + +const invalid5 = getAngleType(-180); +assertEquals(invalid5, "Invalid angle"); + +// Angles greater than 360 +const invalid6 = getAngleType(365); +assertEquals(invalid6, "Invalid angle"); + +const invalid7 = getAngleType(400); +assertEquals(invalid7, "Invalid angle"); + +const invalid8 = getAngleType(720); +assertEquals(invalid8, "Invalid angle"); + +console.log("\nAll tests completed!"); + 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 970cb9b64..7f6647e7b 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 @@ -1,3 +1,5 @@ +/** + * // Implement a function isProperFraction, // when given two numbers, a numerator and a denominator, it should return true if // the given numbers form a proper fraction, and false otherwise. @@ -31,3 +33,90 @@ function assertEquals(actualOutput, targetOutput) { // Example: 1/2 is a proper fraction assertEquals(isProperFraction(1, 2), true); +* +*/ + +/** + * The code below was written by me, Carlos Abreu + */ + +function isProperFraction(numerator, denominator) { + // Handle division by zero - not a valid fraction + if (denominator === 0) { + return false; + } + + // Check if both numbers are integers + if (!Number.isInteger(numerator) || !Number.isInteger(denominator)) { + return false; + } + + // A proper fraction has |numerator| < |denominator| + return Math.abs(numerator) < Math.abs(denominator); +} + +// The line below allows us to load the isProperFraction function into tests in other files. +// This will be useful in the "rewrite tests with jest" step. +module.exports = isProperFraction; + +// Here's our helper again +function assertEquals(actualOutput, targetOutput) { + console.assert( + actualOutput === targetOutput, + `Expected ${actualOutput} to equal ${targetOutput}` + ); +} + +// TODO: Write tests to cover all cases. +console.log("Running tests for isProperFraction..."); + +// Test 1: Proper fractions with positive numbers +assertEquals(isProperFraction(1, 2), true); +assertEquals(isProperFraction(3, 4), true); +assertEquals(isProperFraction(1, 10), true); +assertEquals(isProperFraction(0, 5), true); // 0/5 = 0, which is a proper fraction + +// Test 2: Improper fractions with positive numbers +assertEquals(isProperFraction(2, 1), false); +assertEquals(isProperFraction(5, 3), false); +assertEquals(isProperFraction(10, 10), false); // Equal numbers are not proper + +// Test 3: Proper fractions with negative numbers +assertEquals(isProperFraction(-1, 2), true); +assertEquals(isProperFraction(1, -2), true); +assertEquals(isProperFraction(-3, -4), true); + +// Test 4: Improper fractions with negative numbers +assertEquals(isProperFraction(-3, 2), false); +assertEquals(isProperFraction(5, -3), false); +assertEquals(isProperFraction(-5, -3), false); + +// Test 5: Fractions equal to 1 or -1 +assertEquals(isProperFraction(1, 1), false); +assertEquals(isProperFraction(-1, 1), false); +assertEquals(isProperFraction(1, -1), false); + +// Test 6: Zero numerator +assertEquals(isProperFraction(0, 1), true); +assertEquals(isProperFraction(0, -5), true); +assertEquals(isProperFraction(0, 0), false); // Denominator zero - invalid + +// Test 7: Denominator zero +assertEquals(isProperFraction(5, 0), false); +assertEquals(isProperFraction(-3, 0), false); + +// Test 8: Non-integer inputs +assertEquals(isProperFraction(1.5, 2), false); +assertEquals(isProperFraction(1, 2.5), false); +assertEquals(isProperFraction(1.5, 2.5), false); + +// Test 9: Large numbers +assertEquals(isProperFraction(1000000, 2000000), true); +assertEquals(isProperFraction(2000000, 1000000), false); + +// Test 10: Edge cases with very small/large differences +assertEquals(isProperFraction(999999, 1000000), true); +assertEquals(isProperFraction(1000000, 999999), false); + +console.log("All tests completed!"); + 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 c7559e787..6605a643d 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 @@ -1,3 +1,4 @@ +/** // This problem involves playing cards: https://en.wikipedia.org/wiki/Standard_52-card_deck // Implement a function getCardValue, when given a string representing a playing card, @@ -50,3 +51,220 @@ try { } catch (e) {} // What other invalid card cases can you think of? +* +*/ + +// This problem involves playing cards: https://en.wikipedia.org/wiki/Standard_52-card_deck + +// Implement a function getCardValue, when given a string representing a playing card, +// should return the numerical value of the card. + +// A valid card string will contain a rank followed by the suit. +// The rank can be one of the following strings: +// "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" +// The suit can be one of the following emojis: +// "♠", "♥", "♦", "♣" +// For example: "A♠", "2♥", "10♥", "J♣", "Q♦", "K♦". + +// When the card is an ace ("A"), the function should return 11. +// When the card is a face card ("J", "Q", "K"), the function should return 10. +// When the card is a number card ("2" to "10"), the function should return its numeric value. + +// When the card string is invalid (not following the above format), the function should +// throw an error. + +// Acceptance criteria: +// After you have implemented the function, write tests to cover all the cases, and +// execute the code to ensure all tests pass. + +function getCardValue(card) { + // Check if card is a string + if (typeof card !== 'string') { + throw new Error('Invalid card: card must be a string'); + } + + // Define valid ranks and suits + const validRanks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']; + const validSuits = ['♠', '♥', '♦', '♣']; + + // Handle 10 separately as it's the only rank with 2 characters + if (card.length < 2 || card.length > 3) { + throw new Error('Invalid card: incorrect length'); + } + + let rank, suit; + + if (card.length === 3) { + // Only "10" can be a 3-character card + if (card.substring(0, 2) !== '10') { + throw new Error('Invalid card: invalid rank'); + } + rank = '10'; + suit = card[2]; + } else { + // length === 2 + rank = card[0]; + suit = card[1]; + } + + // Validate rank + if (!validRanks.includes(rank)) { + throw new Error('Invalid card: invalid rank'); + } + + // Validate suit + if (!validSuits.includes(suit)) { + throw new Error('Invalid card: invalid suit'); + } + + // Return the value based on rank + if (rank === 'A') { + return 11; + } else if (rank === 'J' || rank === 'Q' || rank === 'K') { + return 10; + } else { + // For number cards "2" through "10" + return parseInt(rank, 10); + } +} + +// The line below allows us to load the getCardValue function into tests in other files. +// This will be useful in the "rewrite tests with jest" step. +module.exports = getCardValue; + +// Helper functions to make our assertions easier to read. +function assertEquals(actualOutput, targetOutput) { + console.assert( + actualOutput === targetOutput, + `Expected ${actualOutput} to equal ${targetOutput}` + ); +} + +// TODO: Write tests to cover all outcomes, including throwing errors for invalid cards. +// Examples: +assertEquals(getCardValue("9♠"), 9); + +// Comprehensive test suite +console.log("Running tests for getCardValue function...\n"); + +// Test valid number cards (2-10) +console.log("Testing number cards:"); +assertEquals(getCardValue("2♠"), 2); +assertEquals(getCardValue("3♥"), 3); +assertEquals(getCardValue("4♦"), 4); +assertEquals(getCardValue("5♣"), 5); +assertEquals(getCardValue("6♠"), 6); +assertEquals(getCardValue("7♥"), 7); +assertEquals(getCardValue("8♦"), 8); +assertEquals(getCardValue("9♣"), 9); +assertEquals(getCardValue("10♠"), 10); +console.log("✓ Number cards tests completed\n"); + +// Test face cards +console.log("Testing face cards:"); +assertEquals(getCardValue("J♥"), 10); +assertEquals(getCardValue("Q♦"), 10); +assertEquals(getCardValue("K♣"), 10); +console.log("✓ Face cards tests completed\n"); + +// Test Ace +console.log("Testing Ace:"); +assertEquals(getCardValue("A♠"), 11); +assertEquals(getCardValue("A♥"), 11); +assertEquals(getCardValue("A♦"), 11); +assertEquals(getCardValue("A♣"), 11); +console.log("✓ Ace tests completed\n"); + +// Test all suits with one rank +console.log("Testing all suits:"); +assertEquals(getCardValue("5♠"), 5); +assertEquals(getCardValue("5♥"), 5); +assertEquals(getCardValue("5♦"), 5); +assertEquals(getCardValue("5♣"), 5); +console.log("✓ All suits tests completed\n"); + +// Test invalid cards +console.log("Testing invalid cards:"); + +// Test invalid format +try { + getCardValue("invalid"); + console.error("✗ Error was not thrown for completely invalid card"); +} catch (e) { + console.log("✓ Correctly threw error for completely invalid card:", e.message); +} + +// Test invalid rank +try { + getCardValue("Z♠"); + console.error("✗ Error was not thrown for invalid rank"); +} catch (e) { + console.log("✓ Correctly threw error for invalid rank:", e.message); +} + +// Test invalid suit +try { + getCardValue("A⭐"); + console.error("✗ Error was not thrown for invalid suit"); +} catch (e) { + console.log("✓ Correctly threw error for invalid suit:", e.message); +} + +// Test empty string +try { + getCardValue(""); + console.error("✗ Error was not thrown for empty string"); +} catch (e) { + console.log("✓ Correctly threw error for empty string:", e.message); +} + +// Test too short +try { + getCardValue("A"); + console.error("✗ Error was not thrown for too short card"); +} catch (e) { + console.log("✓ Correctly threw error for too short card:", e.message); +} + +// Test too long +try { + getCardValue("10♥♠"); + console.error("✗ Error was not thrown for too long card"); +} catch (e) { + console.log("✓ Correctly threw error for too long card:", e.message); +} + +// Test invalid 3-character card that's not "10" +try { + getCardValue("11♠"); + console.error("✗ Error was not thrown for invalid 3-character card"); +} catch (e) { + console.log("✓ Correctly threw error for invalid 3-character card:", e.message); +} + +// Test non-string input +try { + getCardValue(123); + console.error("✗ Error was not thrown for non-string input"); +} catch (e) { + console.log("✓ Correctly threw error for non-string input:", e.message); +} + +// Test null input +try { + getCardValue(null); + console.error("✗ Error was not thrown for null input"); +} catch (e) { + console.log("✓ Correctly threw error for null input:", e.message); +} + +// Test undefined input +try { + getCardValue(undefined); + console.error("✗ Error was not thrown for undefined input"); +} catch (e) { + console.log("✓ Correctly threw error for undefined input:", e.message); +} + +console.log("\nAll tests completed!"); + 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 d777f348d..4eab22f07 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 @@ -1,3 +1,4 @@ +/** // This statement loads the getAngleType function you wrote in the implement directory. // We will use the same function, but write tests for it using Jest in this file. const getAngleType = require("../implement/1-get-angle-type"); @@ -18,3 +19,65 @@ test(`should return "Acute angle" when (0 < angle < 90)`, () => { // Case 4: Straight angle // Case 5: Reflex angles // Case 6: Invalid angles +* +*/ + +// Written by me @Carlos Abreu + +const getAngleType = require("../implement/1-get-angle-type"); +describe('getAngleType function', () => { + + describe('Acute angles', () => { + test('should return "Acute angle" for angles between 0 and 90 degrees', () => { + expect(getAngleType(45)).toBe("Acute angle"); + expect(getAngleType(1)).toBe("Acute angle"); + expect(getAngleType(89)).toBe("Acute angle"); + }); + }); + + describe('Right angle', () => { + test('should return "Right angle" for exactly 90 degrees', () => { + expect(getAngleType(90)).toBe("Right angle"); + }); + }); + + describe('Obtuse angles', () => { + test('should return "Obtuse angle" for angles between 90 and 180 degrees', () => { + expect(getAngleType(95)).toBe("Obtuse angle"); + expect(getAngleType(135)).toBe("Obtuse angle"); + expect(getAngleType(179)).toBe("Obtuse angle"); + }); + }); + + describe('Straight angle', () => { + test('should return "Straight angle" for exactly 180 degrees', () => { + expect(getAngleType(180)).toBe("Straight angle"); + }); + }); + + describe('Reflex angles', () => { + test('should return "Reflex angle" for angles between 180 and 360 degrees', () => { + expect(getAngleType(185)).toBe("Reflex angle"); + expect(getAngleType(270)).toBe("Reflex angle"); + expect(getAngleType(359)).toBe("Reflex angle"); + }); + }); + + describe('Invalid angles', () => { + test('should return "Invalid angle" for angles less than or equal to 0', () => { + expect(getAngleType(0)).toBe("Invalid angle"); + expect(getAngleType(-45)).toBe("Invalid angle"); + expect(getAngleType(-90)).toBe("Invalid angle"); + expect(getAngleType(-180)).toBe("Invalid angle"); + }); + + test('should return "Invalid angle" for angles greater than or equal to 360', () => { + expect(getAngleType(360)).toBe("Invalid angle"); + expect(getAngleType(365)).toBe("Invalid angle"); + expect(getAngleType(400)).toBe("Invalid angle"); + expect(getAngleType(720)).toBe("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 7f087b2ba..4cfcfedcb 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 @@ -1,3 +1,4 @@ +/** // This statement loads the isProperFraction function you wrote in the implement directory. // We will use the same function, but write tests for it using Jest in this file. const isProperFraction = require("../implement/2-is-proper-fraction"); @@ -8,3 +9,200 @@ const isProperFraction = require("../implement/2-is-proper-fraction"); test(`should return false when denominator is zero`, () => { expect(isProperFraction(1, 0)).toEqual(false); }); + +// Implement a function isProperFraction, +// when given two numbers, a numerator and a denominator, it should return true if +// the given numbers form a proper fraction, and false otherwise. + +// Assumption: The parameters are valid numbers (not NaN or Infinity). + +// Note: If you are unfamiliar with proper fractions, please look up its mathematical definition. + +// Acceptance criteria: +// After you have implemented the function, write tests to cover all the cases, and +// execute the code to ensure all tests pass. + +function isProperFraction(numerator, denominator) { + // A proper fraction is defined as a fraction where the absolute value of the numerator + // is less than the absolute value of the denominator, and the denominator is not zero. + // Additionally, both numerator and denominator must be non-zero (zero numerator is acceptable + // as 0/5 = 0, which is less than 1, but we need to check definition) + + // Check for invalid denominator (zero) + if (denominator === 0) { + return false; + } + + // Get absolute values for comparison + const absNumerator = Math.abs(numerator); + const absDenominator = Math.abs(denominator); + + // A proper fraction has |numerator| < |denominator| + // Note: 0/5 is considered a proper fraction as 0 < 5 + // Negative numbers are also considered: -2/3 is proper because |-2| < |3| + return absNumerator < absDenominator; +} + +// The line below allows us to load the isProperFraction function into tests in other files. +// This will be useful in the "rewrite tests with jest" step. +module.exports = isProperFraction; + +// Here's our helper again +function assertEquals(actualOutput, targetOutput) { + console.assert( + actualOutput === targetOutput, + `Expected ${actualOutput} to equal ${targetOutput}` + ); +} + +// Write tests to cover all cases. +console.log("Running tests for isProperFraction function...\n"); + +// Test 1: Basic proper fractions with positive numbers +console.log("Testing proper fractions with positive numbers:"); +assertEquals(isProperFraction(1, 2), true); // 1/2 is proper +assertEquals(isProperFraction(3, 4), true); // 3/4 is proper +assertEquals(isProperFraction(5, 8), true); // 5/8 is proper +assertEquals(isProperFraction(1, 100), true); // 1/100 is proper + +// Test 2: Fractions that are NOT proper (numerator >= denominator) +console.log("\nTesting improper fractions with positive numbers:"); +assertEquals(isProperFraction(2, 2), false); // 2/2 = 1 (equal) +assertEquals(isProperFraction(3, 2), false); // 3/2 > 1 +assertEquals(isProperFraction(5, 3), false); // 5/3 > 1 +assertEquals(isProperFraction(10, 1), false); // 10/1 > 1 + +// Test 3: Fractions with zero numerator +console.log("\nTesting fractions with zero numerator:"); +assertEquals(isProperFraction(0, 5), true); // 0/5 = 0 (proper) +assertEquals(isProperFraction(0, 1), true); // 0/1 = 0 (proper) +assertEquals(isProperFraction(0, 100), true); // 0/100 = 0 (proper) + +// Test 4: Fractions with negative numerator +console.log("\nTesting fractions with negative numerator:"); +assertEquals(isProperFraction(-1, 2), true); // |-1| < |2| -> proper +assertEquals(isProperFraction(-3, 4), true); // |-3| < |4| -> proper +assertEquals(isProperFraction(-5, 3), false); // |-5| > |3| -> improper +assertEquals(isProperFraction(-2, 2), false); // |-2| = |2| -> improper + +// Test 5: Fractions with negative denominator +console.log("\nTesting fractions with negative denominator:"); +assertEquals(isProperFraction(1, -2), true); // |1| < |-2| -> proper +assertEquals(isProperFraction(3, -4), true); // |3| < |-4| -> proper +assertEquals(isProperFraction(5, -3), false); // |5| > |-3| -> improper +assertEquals(isProperFraction(2, -2), false); // |2| = |-2| -> improper + +// Test 6: Fractions with both numerator and denominator negative +console.log("\nTesting fractions with both numbers negative:"); +assertEquals(isProperFraction(-1, -2), true); // |-1| < |-2| -> proper +assertEquals(isProperFraction(-3, -4), true); // |-3| < |-4| -> proper +assertEquals(isProperFraction(-5, -3), false); // |-5| > |-3| -> improper +assertEquals(isProperFraction(-2, -2), false); // |-2| = |-2| -> improper + +// Test 7: Fractions with numerator zero and negative denominator +console.log("\nTesting fractions with zero numerator and negative denominator:"); +assertEquals(isProperFraction(0, -5), true); // |0| < |-5| -> proper +assertEquals(isProperFraction(0, -1), true); // |0| < |-1| -> proper + +// Test 8: Edge cases with denominator zero +console.log("\nTesting denominator equals zero:"); +assertEquals(isProperFraction(1, 0), false); // Denominator zero -> invalid +assertEquals(isProperFraction(0, 0), false); // Both zero -> invalid +assertEquals(isProperFraction(-5, 0), false); // Denominator zero -> invalid + +// Test 9: Fractions with large numbers +console.log("\nTesting with large numbers:"); +assertEquals(isProperFraction(1000, 1001), true); // 1000/1001 is proper +assertEquals(isProperFraction(1000, 1000), false); // Equal -> improper +assertEquals(isProperFraction(1001, 1000), false); // Numerator larger -> improper + +console.log("\nAll tests completed!"); +* +*/ + +// This statement loads the isProperFraction function you wrote in the implement directory. +// We will use the same function, but write tests for it using Jest in this file. +const isProperFraction = require("../implement/2-is-proper-fraction"); + +// Write tests in Jest syntax to cover all combinations + +describe('isProperFraction function', () => { + + describe('Proper fractions with positive numbers', () => { + test('should return true when numerator < denominator', () => { + expect(isProperFraction(1, 2)).toBe(true); + expect(isProperFraction(3, 4)).toBe(true); + expect(isProperFraction(5, 8)).toBe(true); + expect(isProperFraction(1, 100)).toBe(true); + }); + }); + + describe('Improper fractions with positive numbers', () => { + test('should return false when numerator >= denominator', () => { + expect(isProperFraction(2, 2)).toBe(false); // Equal + expect(isProperFraction(3, 2)).toBe(false); // Numerator larger + expect(isProperFraction(5, 3)).toBe(false); // Numerator larger + expect(isProperFraction(10, 1)).toBe(false); // Numerator larger + }); + }); + + describe('Fractions with zero numerator', () => { + test('should return true when numerator is zero and denominator non-zero', () => { + expect(isProperFraction(0, 5)).toBe(true); + expect(isProperFraction(0, 1)).toBe(true); + expect(isProperFraction(0, 100)).toBe(true); + }); + }); + + describe('Fractions with negative numerator', () => { + test('should compare absolute values when numerator is negative', () => { + expect(isProperFraction(-1, 2)).toBe(true); // |-1| < |2| + expect(isProperFraction(-3, 4)).toBe(true); // |-3| < |4| + expect(isProperFraction(-5, 3)).toBe(false); // |-5| > |3| + expect(isProperFraction(-2, 2)).toBe(false); // |-2| = |2| + }); + }); + + describe('Fractions with negative denominator', () => { + test('should compare absolute values when denominator is negative', () => { + expect(isProperFraction(1, -2)).toBe(true); // |1| < |-2| + expect(isProperFraction(3, -4)).toBe(true); // |3| < |-4| + expect(isProperFraction(5, -3)).toBe(false); // |5| > |-3| + expect(isProperFraction(2, -2)).toBe(false); // |2| = |-2| + }); + }); + + describe('Fractions with both numbers negative', () => { + test('should compare absolute values when both are negative', () => { + expect(isProperFraction(-1, -2)).toBe(true); // |-1| < |-2| + expect(isProperFraction(-3, -4)).toBe(true); // |-3| < |-4| + expect(isProperFraction(-5, -3)).toBe(false); // |-5| > |-3| + expect(isProperFraction(-2, -2)).toBe(false); // |-2| = |-2| + }); + }); + + describe('Fractions with zero numerator and negative denominator', () => { + test('should return true for 0/negative denominator', () => { + expect(isProperFraction(0, -5)).toBe(true); // |0| < |-5| + expect(isProperFraction(0, -1)).toBe(true); // |0| < |-1| + }); + }); + + describe('Denominator equals zero', () => { + test('should return false when denominator is zero', () => { + expect(isProperFraction(1, 0)).toBe(false); // Division by zero + expect(isProperFraction(0, 0)).toBe(false); // Both zero + expect(isProperFraction(-5, 0)).toBe(false); // Denominator zero + }); + }); + + describe('Large numbers', () => { + test('should handle large numbers correctly', () => { + expect(isProperFraction(1000, 1001)).toBe(true); // Proper + expect(isProperFraction(1000, 1000)).toBe(false); // Equal + expect(isProperFraction(1001, 1000)).toBe(false); // Improper + }); + }); + +}); + 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 cf7f9dae2..ee6329b87 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 @@ -1,3 +1,4 @@ +/** // This statement loads the getCardValue function you wrote in the implement directory. // We will use the same function, but write tests for it using Jest in this file. const getCardValue = require("../implement/3-get-card-value"); @@ -17,4 +18,145 @@ test(`Should return 11 when given an ace card`, () => { // 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 +* +*/ + +// This statement loads the getCardValue function you wrote in the implement directory. +// We will use the same function, but write tests for it using Jest in this file. +const getCardValue = require("../implement/3-get-card-value"); + +// Test case 1: Ace cards +describe('Ace cards', () => { + test('should return 11 for Ace of Spades', () => { + expect(getCardValue("A♠")).toBe(11); + }); + + test('should return 11 for Ace of Hearts', () => { + expect(getCardValue("A♥")).toBe(11); + }); + + test('should return 11 for Ace of Diamonds', () => { + expect(getCardValue("A♦")).toBe(11); + }); + + test('should return 11 for Ace of Clubs', () => { + expect(getCardValue("A♣")).toBe(11); + }); +}); + +// Test case 2: Number cards (2-10) +describe('Number cards', () => { + // Test all number cards 2-9 + test.each([ + ['2♠', 2], ['3♥', 3], ['4♦', 4], ['5♣', 5], + ['6♠', 6], ['7♥', 7], ['8♦', 8], ['9♣', 9] + ])('should return %i for card %s', (card, expectedValue) => { + expect(getCardValue(card)).toBe(expectedValue); + }); + + // Test 10 separately as it has different format + test('should return 10 for Ten of Spades', () => { + expect(getCardValue("10♠")).toBe(10); + }); + + test('should return 10 for Ten of Hearts', () => { + expect(getCardValue("10♥")).toBe(10); + }); + + test('should return 10 for Ten of Diamonds', () => { + expect(getCardValue("10♦")).toBe(10); + }); + + test('should return 10 for Ten of Clubs', () => { + expect(getCardValue("10♣")).toBe(10); + }); +}); + +// Test case 3: Face cards (J, Q, K) +describe('Face cards', () => { + test.each([ + ['J♠', 10], ['J♥', 10], ['J♦', 10], ['J♣', 10], + ['Q♠', 10], ['Q♥', 10], ['Q♦', 10], ['Q♣', 10], + ['K♠', 10], ['K♥', 10], ['K♦', 10], ['K♣', 10] + ])('should return 10 for face card %s', (card, expectedValue) => { + expect(getCardValue(card)).toBe(expectedValue); + }); +}); + +// Test case 4: Invalid cards +describe('Invalid cards', () => { + // Test invalid format/input types + test('should throw error for completely invalid card string', () => { + expect(() => getCardValue("invalid")).toThrow(); + }); + + test('should throw error for empty string', () => { + expect(() => getCardValue("")).toThrow(); + }); + + test('should throw error for non-string input (number)', () => { + expect(() => getCardValue(123)).toThrow(); + }); + + test('should throw error for null input', () => { + expect(() => getCardValue(null)).toThrow(); + }); + + test('should throw error for undefined input', () => { + expect(() => getCardValue(undefined)).toThrow(); + }); + + // Test invalid ranks + test('should throw error for invalid rank', () => { + expect(() => getCardValue("Z♠")).toThrow(); + }); + + test('should throw error for rank that doesn\'t exist', () => { + expect(() => getCardValue("1♥")).toThrow(); + }); + + // Test invalid suits + test('should throw error for invalid suit symbol', () => { + expect(() => getCardValue("A⭐")).toThrow(); + }); + + test('should throw error for suit without emoji', () => { + expect(() => getCardValue("AS")).toThrow(); // Using 'S' instead of ♠ + }); + + // Test invalid card format + test('should throw error for card that\'s too short', () => { + expect(() => getCardValue("A")).toThrow(); + }); + + test('should throw error for card that\'s too long', () => { + expect(() => getCardValue("10♥♠")).toThrow(); + }); + + test('should throw error for invalid 3-character card', () => { + expect(() => getCardValue("11♠")).toThrow(); + }); + + test('should throw error when rank and suit are reversed', () => { + expect(() => getCardValue("♠A")).toThrow(); + }); + + // Test edge cases with valid ranks but wrong format + test('should throw error for "10" without suit', () => { + expect(() => getCardValue("10")).toThrow(); + }); + + test('should throw error for valid rank with multiple suits', () => { + expect(() => getCardValue("A♠♥")).toThrow(); + }); +}); + +// Test case 5: Verify all suits work correctly with a representative rank +describe('All suits functionality', () => { + test.each([ + ['5♠', 5], ['5♥', 5], ['5♦', 5], ['5♣', 5] + ])('should work correctly with suit %s', (card, expectedValue) => { + expect(getCardValue(card)).toBe(expectedValue); + }); +}); diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index 95b6ebb7d..a4a383ab7 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -1,5 +1,39 @@ +/** + * function countChar(stringOfCharacters, findCharacter) { return 5 } module.exports = countChar; +* +*/ + +function countChar(stringOfCharacters, findCharacter) { + // Input validation - return 0 for invalid inputs + if (typeof stringOfCharacters !== 'string' || typeof findCharacter !== 'string') { + return 0; + } + + // Return 0 if either parameter is empty + if (stringOfCharacters.length === 0 || findCharacter.length === 0) { + return 0; + } + + // Use only the first character of findCharacter (as per test expectations) + const searchChar = findCharacter[0]; + + let count = 0; + + // Count occurrences of the character + for (let i = 0; i < stringOfCharacters.length; i++) { + // Case-sensitive comparison + if (stringOfCharacters[i] === searchChar) { + 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..168d1c048 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -1,3 +1,5 @@ +/** + * // 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 +24,88 @@ 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. +* +*/ + +// count.test.js + +// implement a function countChar that counts the number of times a character occurs in a string +const countChar = require("./count"); + +// Scenario: Multiple Occurrences +test("should count multiple occurrences of a character", () => { + const str = "aaaaa"; + const char = "a"; + const count = countChar(str, char); + expect(count).toEqual(5); +}); + +// Scenario: No Occurrences +test("should return 0 when character does not exist in string", () => { + const str = "hello world"; + const char = "z"; + const count = countChar(str, char); + expect(count).toEqual(0); +}); + +// Additional test cases to ensure robustness: + +// Scenario: Single Occurrence +test("should count a single occurrence of a character", () => { + const str = "hello"; + const char = "e"; + const count = countChar(str, char); + expect(count).toEqual(1); +}); + +// Scenario: Character appears at the beginning and end +test("should count character at beginning and end of string", () => { + const str = "abracadabra"; + const char = "a"; + const count = countChar(str, char); + expect(count).toEqual(5); +}); + +// 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); // 'H' is uppercase, 'h' is lowercase +}); + +// Scenario: Character is a space +test("should count spaces when searching for space character", () => { + const str = "hello world how are you"; + const char = " "; + const count = countChar(str, char); + expect(count).toEqual(4); +}); + +// Scenario: Character is a number +test("should count numeric characters", () => { + const str = "abc123abc123abc"; + const char = "1"; + const count = countChar(str, char); + expect(count).toEqual(2); +}); + +// Scenario: Empty string +test("should return 0 when string is empty", () => { + const str = ""; + const char = "a"; + const count = countChar(str, char); + expect(count).toEqual(0); +}); + +// Scenario: Character is longer than one character (edge case) +test("should handle when char parameter is longer than one character", () => { + const str = "hello"; + const char = "ll"; + const count = countChar(str, char); + // Depending on requirements, this might count occurrences of the substring + // For this implementation, we'll specify it should count the first character only + expect(count).toEqual(2); // Counting 'l' occurrences +}); + + diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.js b/Sprint-3/2-practice-tdd/get-ordinal-number.js index f95d71db1..3f7d56b03 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.js @@ -1,5 +1,36 @@ +/** function getOrdinalNumber(num) { return "1st"; } module.exports = getOrdinalNumber; +* +*/ + +function getOrdinalNumber(num) { + // Handle negative numbers by preserving the sign + const absoluteNum = Math.abs(num); + const sign = num < 0 ? "-" : ""; + + // Special cases for 11, 12, 13 + const lastTwoDigits = absoluteNum % 100; + if (lastTwoDigits >= 11 && lastTwoDigits <= 13) { + return `${sign}${absoluteNum}th`; + } + + // Check the last digit for other cases + const lastDigit = absoluteNum % 10; + switch (lastDigit) { + case 1: + return `${sign}${absoluteNum}st`; + case 2: + return `${sign}${absoluteNum}nd`; + case 3: + return `${sign}${absoluteNum}rd`; + default: + return `${sign}${absoluteNum}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..fa9319f51 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,4 @@ +/** const getOrdinalNumber = require("./get-ordinal-number"); // In this week's prep, we started implementing getOrdinalNumber. @@ -18,3 +19,66 @@ test("should append 'st' for numbers ending with 1, except those ending with 11" expect(getOrdinalNumber(21)).toEqual("21st"); expect(getOrdinalNumber(131)).toEqual("131st"); }); +* +*/ + +const getOrdinalNumber = require("./get-ordinal-number"); + +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(131)).toEqual("131st"); +}); + +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"); +}); + +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"); +}); + +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"); +}); + +test("should append 'th' for all other numbers", () => { + 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(14)).toEqual("14th"); + expect(getOrdinalNumber(20)).toEqual("20th"); + expect(getOrdinalNumber(24)).toEqual("24th"); + expect(getOrdinalNumber(30)).toEqual("30th"); + expect(getOrdinalNumber(100)).toEqual("100th"); + expect(getOrdinalNumber(114)).toEqual("114th"); +}); + +test("should handle negative numbers correctly", () => { + expect(getOrdinalNumber(-1)).toEqual("-1st"); + expect(getOrdinalNumber(-2)).toEqual("-2nd"); + expect(getOrdinalNumber(-3)).toEqual("-3rd"); + expect(getOrdinalNumber(-4)).toEqual("-4th"); + expect(getOrdinalNumber(-11)).toEqual("-11th"); + expect(getOrdinalNumber(-12)).toEqual("-12th"); + expect(getOrdinalNumber(-13)).toEqual("-13th"); + expect(getOrdinalNumber(-21)).toEqual("-21st"); +}); + +test("should handle zero correctly", () => { + expect(getOrdinalNumber(0)).toEqual("0th"); +}); + diff --git a/Sprint-3/2-practice-tdd/repeat-str.js b/Sprint-3/2-practice-tdd/repeat-str.js index 3838c7b00..7b7f7af89 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.js +++ b/Sprint-3/2-practice-tdd/repeat-str.js @@ -1,5 +1,44 @@ +/** + * function repeatStr() { return "hellohellohello"; } module.exports = repeatStr; +* +*/ + +// repeat-str.js + +function repeatStr(str, count) { + // Convert count to a number + const numCount = Number(count); + + // Check if count is a valid number + if (isNaN(numCount)) { + throw new Error("Count must be a number"); + } + + // Check for negative count + if (numCount < 0) { + throw new Error("Count must be a positive integer"); + } + + // Handle count of 0 + if (numCount === 0) { + return ""; + } + + // Floor the count to handle decimal numbers + const repeatTimes = Math.floor(numCount); + let result = ""; + + // Build the repeated string + for (let i = 0; i < repeatTimes; i++) { + result += str; + } + + return result; +} + +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..abc7e9ea9 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.test.js +++ b/Sprint-3/2-practice-tdd/repeat-str.test.js @@ -1,3 +1,5 @@ +/** + * // Implement a function repeatStr const repeatStr = require("./repeat-str"); // Given a target string `str` and a positive integer `count`, @@ -30,3 +32,74 @@ 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. +* +*/ + +// repeat-str.test.js +const repeatStr = require("./repeat-str"); + +// Case: handle multiple repetitions +test("should repeat the string count times", () => { + const str = "hello"; + const count = 3; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual("hellohellohello"); +}); + +// Case: handle count of 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"); +}); + +// Case: Handle count of 0 +test("should return an empty string when count is 0", () => { + const str = "hello"; + const count = 0; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual(""); +}); + +// Case: Handle 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 edge cases +test("should handle empty string input", () => { + const str = ""; + const count = 5; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual(""); +}); + +test("should handle count as a string number", () => { + const str = "abc"; + const count = "3"; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual("abcabcabc"); +}); + +test("should handle decimal count by flooring", () => { + const str = "xyz"; + const count = 2.7; + const repeatedStr = repeatStr(str, count); + expect(repeatedStr).toEqual("xyzxyz"); +}); + +test("should throw error for non-numeric count", () => { + const str = "hello"; + const count = "abc"; + + expect(() => { + repeatStr(str, count); + }).toThrow("Count must be a number"); +}); + diff --git a/Sprint-3/3-dead-code/exercise-1.js b/Sprint-3/3-dead-code/exercise-1.js index 4d09f15fa..25907e0b2 100644 --- a/Sprint-3/3-dead-code/exercise-1.js +++ b/Sprint-3/3-dead-code/exercise-1.js @@ -1,3 +1,5 @@ +/** + * // Find the instances of unreachable and redundant code - remove them! // The sayHello function should continue to work for any reasonable input it's given. @@ -15,3 +17,22 @@ testName = "Aman"; const greetingMessage = sayHello(greeting, testName); console.log(greetingMessage); // 'hello, Aman!' +* +*/ + +// 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"; +const greeting = "hello"; + +function sayHello(greeting, name) { + return `${greeting}, ${name}!`; +} + +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 56d7887c4..8e870ae8b 100644 --- a/Sprint-3/3-dead-code/exercise-2.js +++ b/Sprint-3/3-dead-code/exercise-2.js @@ -1,3 +1,5 @@ +/** + * // Remove the unused code that does not contribute to the final console log // The countAndCapitalisePets function should continue to work for any reasonable input it's given, and you shouldn't modify the pets variable. @@ -26,3 +28,30 @@ function countAndCapitalisePets(petsArr) { const countedPetsStartingWithH = countAndCapitalisePets(petsStartingWithH); console.log(countedPetsStartingWithH); // { 'HAMSTER': 3, 'HORSE': 1 } <- Final console log +* +*/ + +// Remove the unused code that does not contribute to the final console log +// 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 petsStartingWithH = pets.filter((pet) => pet[0] === "h"); + +function countAndCapitalisePets(petsArr) { + const petCount = {}; + + petsArr.forEach((pet) => { + const capitalisedPet = pet.toUpperCase(); + if (petCount[capitalisedPet]) { + petCount[capitalisedPet] += 1; + } else { + petCount[capitalisedPet] = 1; + } + }); + return petCount; +} + +const countedPetsStartingWithH = countAndCapitalisePets(petsStartingWithH); + +console.log(countedPetsStartingWithH); // { 'HAMSTER': 3, 'HORSE': 1 } <- Final console log +