From 0b65a57f9d1423657764b03fc9a408d28d87ec79 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Wed, 25 Feb 2026 11:26:46 +0200 Subject: [PATCH 01/23] feat: implement countChar function --- .../1-get-angle-type.test.js | 26 ++++++++++++++++++- Sprint-3/2-practice-tdd/count.js | 8 +++++- 2 files changed, 32 insertions(+), 2 deletions(-) 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..181a0d3fa7 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 @@ -7,14 +7,38 @@ const getAngleType = require("../implement/1-get-angle-type"); // Case 1: Acute angles test(`should return "Acute angle" when (0 < angle < 90)`, () => { - // Test various acute angles, including boundary cases expect(getAngleType(1)).toEqual("Acute angle"); expect(getAngleType(45)).toEqual("Acute angle"); expect(getAngleType(89)).toEqual("Acute angle"); }); // Case 2: Right angle +test(`should return "Right angle" when angle is exactly 90`, () => { + expect(getAngleType(90)).toEqual("Right angle"); +}); + // Case 3: Obtuse angles +test(`should return "Obtuse angle" when (90 < angle < 180)`, () => { + expect(getAngleType(91)).toEqual("Obtuse angle"); + expect(getAngleType(135)).toEqual("Obtuse angle"); + expect(getAngleType(179)).toEqual("Obtuse angle"); +}); + // Case 4: Straight angle +test(`should return "Straight angle" when angle is exactly 180`, () => { + expect(getAngleType(180)).toEqual("Straight angle"); +}); + // Case 5: Reflex angles +test(`should return "Reflex angle" when (180 < angle < 360)`, () => { + expect(getAngleType(181)).toEqual("Reflex angle"); + expect(getAngleType(270)).toEqual("Reflex angle"); + expect(getAngleType(359)).toEqual("Reflex angle"); +}); + // Case 6: Invalid angles +test(`should return "Invalid angle" when angle is outside the valid range`, () => { + expect(getAngleType(-1)).toEqual("Invalid angle"); + expect(getAngleType(360)).toEqual("Invalid angle"); + expect(getAngleType(361)).toEqual("Invalid angle"); +}); diff --git a/Sprint-3/2-practice-tdd/count.js b/Sprint-3/2-practice-tdd/count.js index 95b6ebb7d4..d59e425d6b 100644 --- a/Sprint-3/2-practice-tdd/count.js +++ b/Sprint-3/2-practice-tdd/count.js @@ -1,5 +1,11 @@ function countChar(stringOfCharacters, findCharacter) { - return 5 + let count = 0; + for (let i = 0; i < stringOfCharacters.length; i++) { + if (stringOfCharacters[i] === findCharacter) { + count++; + } + } + return count; } module.exports = countChar; From 18ef7563dc387ea24cc5e732cd118f37646d4241 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Wed, 25 Feb 2026 12:46:40 +0200 Subject: [PATCH 02/23] test: add unit tests for countChar function --- Sprint-3/2-practice-tdd/count.test.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Sprint-3/2-practice-tdd/count.test.js b/Sprint-3/2-practice-tdd/count.test.js index 179ea0ddf7..cd6c688c77 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -3,6 +3,10 @@ const countChar = require("./count"); // Given a string `str` and a single character `char` to search for, // When the countChar function is called with these inputs, // Then it should: +// - Iterate through each character in `str`. +// - Compare each character to `char`. +// - Increment a counter each time a match is found. +// - Return the final count of occurrences of `char` in `str`. // Scenario: Multiple Occurrences // Given the input string `str`, @@ -22,3 +26,17 @@ 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 the character does not occur in the string", () => { + const str = "hello world"; + const char = "x"; + const count = countChar(str, char); + expect(count).toEqual(0); +}); + +// Scenario: Case Sensitivity +test("should be case sensitive", () => { + const str = "Hello World"; + const char = "H"; + const count = countChar(str, char); + expect(count).toEqual(1); +}); From 9d908d9cdbdfeabcd16ec35ff635b1a91bec2b08 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Wed, 25 Feb 2026 12:52:49 +0200 Subject: [PATCH 03/23] Implement getOrdinalNumber with correct suffix logic --- Sprint-3/2-practice-tdd/get-ordinal-number.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-3/2-practice-tdd/get-ordinal-number.js b/Sprint-3/2-practice-tdd/get-ordinal-number.js index f95d71db13..2704ed6d82 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.js @@ -1,5 +1,7 @@ function getOrdinalNumber(num) { - return "1st"; + const suffixes = ["th", "st", "nd", "rd"]; + const v = num % 100; + return num + (suffixes[(v - 20) % 10] || suffixes[v] || suffixes[0]); } module.exports = getOrdinalNumber; From 715c649a20081860a1d0285c7270c3880fc3ef63 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Wed, 25 Feb 2026 13:25:35 +0200 Subject: [PATCH 04/23] Add category-based tests for ordinal number suffixes (st, nd, rd, th) including edge cases --- .../2-practice-tdd/get-ordinal-number.test.js | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) 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..69af86024e 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js @@ -1,9 +1,31 @@ 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"); +}); + +// Case 2: Numbers ending with 2 (but not 12) +// When the number ends with 2, except those ending with 12, +// Then the function should return a string by appending "nd" to the number. +test("should append 'nd' for numbers ending with 2, except those ending with 12", () => { + expect(getOrdinalNumber(2)).toEqual("2nd"); + expect(getOrdinalNumber(22)).toEqual("22nd"); + expect(getOrdinalNumber(132)).toEqual("132nd"); +}); + // In this week's prep, we started implementing getOrdinalNumber. +// This function takes a number as input and returns a string with the appropriate ordinal suffix ("st", "nd", "rd", "th"). +// For example: +// - getOrdinalNumber(1) should return "1st" // Continue testing and implementing getOrdinalNumber for additional cases. // Write your tests using Jest — remember to run your tests often for continual feedback. - +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"); +}); // To ensure thorough testing, we need broad scenarios that cover all possible cases. // Listing individual values, however, can quickly lead to an unmanageable number of test cases. // Instead of writing tests for individual numbers, consider grouping all possible input values @@ -13,8 +35,18 @@ const getOrdinalNumber = require("./get-ordinal-number"); // Case 1: Numbers ending with 1 (but not 11) // When the number ends with 1, except those ending with 11, // Then the function should return a string by appending "st" to the 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 'th' for numbers ending with 11, 12, or 13", () => { + expect(getOrdinalNumber(11)).toEqual("11th"); + expect(getOrdinalNumber(12)).toEqual("12th"); + expect(getOrdinalNumber(13)).toEqual("13th"); +}); + +// Case 4: All other numbers +// When the number does not end with 1, 2, or 3 (or ends with 11, 12, or 13), +// Then the function should return a string by appending "th" to the number. +test("should append 'th' for all other numbers", () => { + expect(getOrdinalNumber(4)).toEqual("4th"); + expect(getOrdinalNumber(10)).toEqual("10th"); + expect(getOrdinalNumber(14)).toEqual("14th"); + expect(getOrdinalNumber(100)).toEqual("100th"); }); From 2af6c11e737bc2698345e105d3525c231b626a8b Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Thu, 26 Feb 2026 17:27:32 +0200 Subject: [PATCH 05/23] test: add tests for repeatStr --- Sprint-3/2-practice-tdd/repeat-str.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Sprint-3/2-practice-tdd/repeat-str.js b/Sprint-3/2-practice-tdd/repeat-str.js index 3838c7b003..09b2ed992a 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.js +++ b/Sprint-3/2-practice-tdd/repeat-str.js @@ -1,5 +1,22 @@ -function repeatStr() { - return "hellohellohello"; +function repeatStr(n, str) { + let result = ""; + for (let i = 0; i < n; i++) { + result += str; + } + return result; } module.exports = repeatStr; +const repeatStr = require("./repeat-str"); + +test("repeats a string n times", () => { + expect(repeatStr(3, "hello")).toBe("hellohellohello"); +}); + +test("repeats a different string", () => { + expect(repeatStr(2, "abc")).toBe("abcabc"); +}); + +test("returns empty string when n is 0", () => { + expect(repeatStr(0, "hi")).toBe(""); +}); From 4098eb1c96164ce7041641c0977b5c107abb582f Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Sat, 28 Feb 2026 23:12:12 +0200 Subject: [PATCH 06/23] Co-authored-by: Isaac Abodunrin --- CYF-Workshops | 1 + Sprint-3/2-practice-tdd/count.test.js | 1 - Sprint-3/2-practice-tdd/repeat-str.js | 20 ++-- Sprint-3/2-practice-tdd/repeat-str.test.js | 110 ++++++++++++++++----- 4 files changed, 98 insertions(+), 34 deletions(-) create mode 160000 CYF-Workshops diff --git a/CYF-Workshops b/CYF-Workshops new file mode 160000 index 0000000000..5c89bd2b09 --- /dev/null +++ b/CYF-Workshops @@ -0,0 +1 @@ +Subproject commit 5c89bd2b0949c13eb70950a776b1cfebf87de5a1 diff --git a/Sprint-3/2-practice-tdd/count.test.js b/Sprint-3/2-practice-tdd/count.test.js index cd6c688c77..568afa5fb4 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -32,7 +32,6 @@ test("should return 0 when the character does not occur in the string", () => { const count = countChar(str, char); expect(count).toEqual(0); }); - // Scenario: Case Sensitivity test("should be case sensitive", () => { const str = "Hello World"; diff --git a/Sprint-3/2-practice-tdd/repeat-str.js b/Sprint-3/2-practice-tdd/repeat-str.js index 09b2ed992a..e430728ef7 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.js +++ b/Sprint-3/2-practice-tdd/repeat-str.js @@ -7,16 +7,16 @@ function repeatStr(n, str) { } module.exports = repeatStr; -const repeatStr = require("./repeat-str"); +// const repeatStr = require("./repeat-str"); -test("repeats a string n times", () => { - expect(repeatStr(3, "hello")).toBe("hellohellohello"); -}); +// test("repeats a string n times", () => { +// expect(repeatStr(3, "hello")).toBe("hellohellohello"); +// }); -test("repeats a different string", () => { - expect(repeatStr(2, "abc")).toBe("abcabc"); -}); +// test("repeats a different string", () => { +// expect(repeatStr(2, "abc")).toBe("abcabc"); +// }); -test("returns empty string when n is 0", () => { - expect(repeatStr(0, "hi")).toBe(""); -}); +// test("returns empty string when n is 0", () => { +// expect(repeatStr(0, "hi")).toBe(""); +// }); diff --git a/Sprint-3/2-practice-tdd/repeat-str.test.js b/Sprint-3/2-practice-tdd/repeat-str.test.js index a3fc1196c4..1423573f99 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.test.js +++ b/Sprint-3/2-practice-tdd/repeat-str.test.js @@ -1,32 +1,96 @@ // Implement a function repeatStr const repeatStr = require("./repeat-str"); -// Given a target string `str` and a positive integer `count`, -// When the repeatStr function is called with these inputs, -// Then it should: - -// Case: handle multiple repetitions: -// Given a target string `str` and a positive integer `count` greater than 1, -// When the repeatStr function is called with these inputs, -// Then it should return a string that contains the original `str` repeated `count` times. - test("should repeat the string count times", () => { const str = "hello"; const count = 3; - const repeatedStr = repeatStr(str, count); + const repeatedStr = repeatStr(count, str); expect(repeatedStr).toEqual("hellohellohello"); }); +// test("should return the original string when count is 1", () => { +// const str = "hello"; +// const count = 1; +// const repeatedStr = repeatStr(str, count); +// expect(repeatedStr).toEqual("hello"); +// }); +// test("should return an empty string when count is 0", () => { +// const str = "hello"; +// const count = 0; +// const repeatedStr = repeatStr(str, count); +// expect(repeatedStr).toEqual(""); +// }); +// // Given a target string `str` and a positive integer `count`, +// // When the repeatStr function is called with these inputs, +// // Then it should: +// // - Validate that `count` is a non-negative integer. +// // - If `count` is 0, return an empty string. +// // - If `count` is 1, return the original `str`. +// // - If `count` is greater than 1, concatenate `str` to itself `count` times and return the resulting string. -// Case: handle count of 1: -// Given a target string `str` and a `count` equal to 1, -// When the repeatStr function is called with these inputs, -// Then it should return the original `str` without repetition. - -// 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. +// // Case: handle multiple repetitions: +// // Given a target string `str` and a positive integer `count` greater than 1, +// // When the repeatStr function is called with these inputs, +// // Then it should return a string that contains the original `str` repeated `count` times. +// 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: +// // Given a target string `str` and a `count` equal to 1, +// // When the repeatStr function is called with these inputs, +// test("should repeat the string count times", () => { +// const str = "hello"; +// const count = 3; +// const repeatedStr = repeatStr(str, count); +// expect(repeatedStr).toEqual("hellohellohello"); +// }); -// 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. +// // Case: handle count of 1: +// // Given a target string `str` and a `count` equal to 1, +// // When the repeatStr function is called with these inputs, +// // Then it should return the original `str` without repetition. +// 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: +// // 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 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: +// // 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 when count is 0", () => { +// const str = "hello"; +// const count = 0; +// const repeatedStr = repeatStr(str, count); +// expect(repeatedStr).toEqual(""); +// }); +// // Case: Handle negative count: +// // Given a target string `str` and a negative integer `count`, +// // When the repeatStr function is called with these inputs, +// // Then it should throw an error, as negative counts are not valid. +// test("should throw an error when count is negative", () => { +// const str = "hello"; +// const count = -1; +// expect(() => repeatStr(str, count)).toThrow("Count must be a non-negative integer"); +// }); +// // Case: Handle non-integer count: +// // Given a target string `str` and a non-integer value for `count`, +// // When the repeatStr function is called with these inputs, +// // Then it should throw an error, as non-integer counts are not valid. +// test("should throw an error when count is not an integer", () => { +// const str = "hello"; +// const count = 2.5; +// expect(() => repeatStr(str, count)).toThrow("Count must be a non-negative integer"); +// }); From 77bc6bedac78f57aa2fc55d01921e7c2a3dddb5c Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Mon, 2 Mar 2026 13:35:53 +0200 Subject: [PATCH 07/23] refactor: simplify repeatStr using String.prototype.repeat --- Sprint-3/2-practice-tdd/repeat-str.js | 22 +++++++++++++++++++--- package.json | 5 ++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Sprint-3/2-practice-tdd/repeat-str.js b/Sprint-3/2-practice-tdd/repeat-str.js index e430728ef7..d98581e54c 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.js +++ b/Sprint-3/2-practice-tdd/repeat-str.js @@ -8,15 +8,31 @@ function repeatStr(n, str) { module.exports = repeatStr; // const repeatStr = require("./repeat-str"); - +// Given a target string `str` and a positive integer `count`, +// When the repeatStr function is called with these inputs, +// Then it should: // test("repeats a string n times", () => { // expect(repeatStr(3, "hello")).toBe("hellohellohello"); // }); - +const repeatStr = require("./repeat-str"); +test("repeats a string n times", () => { + expect(repeatStr(3, "hello")).toBe("hellohellohello"); +}); // test("repeats a different string", () => { // expect(repeatStr(2, "abc")).toBe("abcabc"); // }); - +test("repeats a different string", () => { + expect(repeatStr(2, "abc")).toBe("abcabc"); +}); +// test("returns empty string when n is 0", () => { +// expect(repeatStr(0, "hi")).toBe(""); +// }); +test("returns empty string when n is 0", () => { + expect(repeatStr(0, "hi")).toBe(""); +}); // test("returns empty string when n is 0", () => { // expect(repeatStr(0, "hi")).toBe(""); // }); +test("returns empty string when n is 0", () => { + expect(repeatStr(0, "hi")).toBe(""); +}); diff --git a/package.json b/package.json index 0657e22dd8..f96bb856a2 100644 --- a/package.json +++ b/package.json @@ -11,5 +11,8 @@ "license": "ISC", "dependencies": { "jest": "^29.7.0" + }, + "devDependencies": { + "jest-environment-jsdom": "^30.2.0" } -} \ No newline at end of file +} From b7a3a6fcbe8122d3d49581f63ba89c62cfb45c03 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Mon, 2 Mar 2026 18:09:31 +0200 Subject: [PATCH 08/23] Revert to main branch --- .../1-get-angle-type.test.js | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) 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 181a0d3fa7..d777f348d3 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 @@ -7,38 +7,14 @@ const getAngleType = require("../implement/1-get-angle-type"); // Case 1: Acute angles test(`should return "Acute angle" when (0 < angle < 90)`, () => { + // Test various acute angles, including boundary cases expect(getAngleType(1)).toEqual("Acute angle"); expect(getAngleType(45)).toEqual("Acute angle"); expect(getAngleType(89)).toEqual("Acute angle"); }); // Case 2: Right angle -test(`should return "Right angle" when angle is exactly 90`, () => { - expect(getAngleType(90)).toEqual("Right angle"); -}); - // Case 3: Obtuse angles -test(`should return "Obtuse angle" when (90 < angle < 180)`, () => { - expect(getAngleType(91)).toEqual("Obtuse angle"); - expect(getAngleType(135)).toEqual("Obtuse angle"); - expect(getAngleType(179)).toEqual("Obtuse angle"); -}); - // Case 4: Straight angle -test(`should return "Straight angle" when angle is exactly 180`, () => { - expect(getAngleType(180)).toEqual("Straight angle"); -}); - // Case 5: Reflex angles -test(`should return "Reflex angle" when (180 < angle < 360)`, () => { - expect(getAngleType(181)).toEqual("Reflex angle"); - expect(getAngleType(270)).toEqual("Reflex angle"); - expect(getAngleType(359)).toEqual("Reflex angle"); -}); - // Case 6: Invalid angles -test(`should return "Invalid angle" when angle is outside the valid range`, () => { - expect(getAngleType(-1)).toEqual("Invalid angle"); - expect(getAngleType(360)).toEqual("Invalid angle"); - expect(getAngleType(361)).toEqual("Invalid angle"); -}); From 92422ef36780ff75ad39d3a826d104c19be1a78b Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Mon, 2 Mar 2026 18:52:09 +0200 Subject: [PATCH 09/23] Co-authored-by: Isaac Abodunrin reverted to main --- CYF-Workshops | 1 - package.json | 3 --- 2 files changed, 4 deletions(-) delete mode 160000 CYF-Workshops diff --git a/CYF-Workshops b/CYF-Workshops deleted file mode 160000 index 5c89bd2b09..0000000000 --- a/CYF-Workshops +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5c89bd2b0949c13eb70950a776b1cfebf87de5a1 diff --git a/package.json b/package.json index f96bb856a2..e4b32166bb 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,5 @@ "license": "ISC", "dependencies": { "jest": "^29.7.0" - }, - "devDependencies": { - "jest-environment-jsdom": "^30.2.0" } } From 444a5ec1f533642f250bb2d5e54835d07a5ce6a5 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Mon, 2 Mar 2026 19:07:12 +0200 Subject: [PATCH 10/23] revert to main --- package.json => Sprint-3/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename package.json => Sprint-3/package.json (99%) diff --git a/package.json b/Sprint-3/package.json similarity index 99% rename from package.json rename to Sprint-3/package.json index e4b32166bb..0657e22dd8 100644 --- a/package.json +++ b/Sprint-3/package.json @@ -12,4 +12,4 @@ "dependencies": { "jest": "^29.7.0" } -} +} \ No newline at end of file From 5ae7a4668939ac99e1e74e8f969c97c1eb870bf4 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Mon, 2 Mar 2026 19:12:56 +0200 Subject: [PATCH 11/23] revert to main --- Sprint-3/package.json | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 Sprint-3/package.json diff --git a/Sprint-3/package.json b/Sprint-3/package.json deleted file mode 100644 index 0657e22dd8..0000000000 --- a/Sprint-3/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "module-structuring-and-testing-data", - "version": "1.0.0", - "description": "Like learning a musical instrument, programming requires daily practice.", - "main": "index.js", - "scripts": { - "test": "jest" - }, - "keywords": [], - "author": "Code Your Future", - "license": "ISC", - "dependencies": { - "jest": "^29.7.0" - } -} \ No newline at end of file From d7f002f844e696028f4f42d87991fff44e880f9f Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Mon, 2 Mar 2026 19:20:43 +0200 Subject: [PATCH 12/23] revert to main --- package.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000000..0657e22dd8 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "module-structuring-and-testing-data", + "version": "1.0.0", + "description": "Like learning a musical instrument, programming requires daily practice.", + "main": "index.js", + "scripts": { + "test": "jest" + }, + "keywords": [], + "author": "Code Your Future", + "license": "ISC", + "dependencies": { + "jest": "^29.7.0" + } +} \ No newline at end of file From cf348b59853da2d27b30dd4821ead556a9837a4f Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Thu, 12 Mar 2026 05:30:31 +0200 Subject: [PATCH 13/23] test: add unit tests for repeatStr function --- Project-CLI-Treasure-Hunt | 1 + Sprint-3/2-practice-tdd/repeat-str.test.js | 120 ++++++--------------- 2 files changed, 35 insertions(+), 86 deletions(-) create mode 160000 Project-CLI-Treasure-Hunt diff --git a/Project-CLI-Treasure-Hunt b/Project-CLI-Treasure-Hunt new file mode 160000 index 0000000000..2f622599e0 --- /dev/null +++ b/Project-CLI-Treasure-Hunt @@ -0,0 +1 @@ +Subproject commit 2f622599e09fc28147949f59bcb6892ff6721548 diff --git a/Sprint-3/2-practice-tdd/repeat-str.test.js b/Sprint-3/2-practice-tdd/repeat-str.test.js index 1423573f99..fabea2f884 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.test.js +++ b/Sprint-3/2-practice-tdd/repeat-str.test.js @@ -1,96 +1,44 @@ // Implement a function repeatStr const repeatStr = require("./repeat-str"); + +// Case: repeat string multiple times test("should repeat the string count times", () => { const str = "hello"; const count = 3; const repeatedStr = repeatStr(count, str); expect(repeatedStr).toEqual("hellohellohello"); }); -// test("should return the original string when count is 1", () => { -// const str = "hello"; -// const count = 1; -// const repeatedStr = repeatStr(str, count); -// expect(repeatedStr).toEqual("hello"); -// }); -// test("should return an empty string when count is 0", () => { -// const str = "hello"; -// const count = 0; -// const repeatedStr = repeatStr(str, count); -// expect(repeatedStr).toEqual(""); -// }); -// // Given a target string `str` and a positive integer `count`, -// // When the repeatStr function is called with these inputs, -// // Then it should: -// // - Validate that `count` is a non-negative integer. -// // - If `count` is 0, return an empty string. -// // - If `count` is 1, return the original `str`. -// // - If `count` is greater than 1, concatenate `str` to itself `count` times and return the resulting string. -// // Case: handle multiple repetitions: -// // Given a target string `str` and a positive integer `count` greater than 1, -// // When the repeatStr function is called with these inputs, -// // Then it should return a string that contains the original `str` repeated `count` times. -// 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: -// // Given a target string `str` and a `count` equal to 1, -// // When the repeatStr function is called with these inputs, -// test("should repeat the string count times", () => { -// const str = "hello"; -// const count = 3; -// const repeatedStr = repeatStr(str, count); -// expect(repeatedStr).toEqual("hellohellohello"); -// }); +// Case: count = 1 +test("should return the original string when count is 1", () => { + const str = "hello"; + const count = 1; + const repeatedStr = repeatStr(count, str); + expect(repeatedStr).toEqual("hello"); +}); -// // Case: handle count of 1: -// // Given a target string `str` and a `count` equal to 1, -// // When the repeatStr function is called with these inputs, -// // Then it should return the original `str` without repetition. -// 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: -// // 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 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: -// // 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 when count is 0", () => { -// const str = "hello"; -// const count = 0; -// const repeatedStr = repeatStr(str, count); -// expect(repeatedStr).toEqual(""); -// }); -// // Case: Handle negative count: -// // Given a target string `str` and a negative integer `count`, -// // When the repeatStr function is called with these inputs, -// // Then it should throw an error, as negative counts are not valid. -// test("should throw an error when count is negative", () => { -// const str = "hello"; -// const count = -1; -// expect(() => repeatStr(str, count)).toThrow("Count must be a non-negative integer"); -// }); -// // Case: Handle non-integer count: -// // Given a target string `str` and a non-integer value for `count`, -// // When the repeatStr function is called with these inputs, -// // Then it should throw an error, as non-integer counts are not valid. -// test("should throw an error when count is not an integer", () => { -// const str = "hello"; -// const count = 2.5; -// expect(() => repeatStr(str, count)).toThrow("Count must be a non-negative integer"); -// }); +// Case: count = 0 +test("should return an empty string when count is 0", () => { + const str = "hello"; + const count = 0; + const repeatedStr = repeatStr(count, str); + expect(repeatedStr).toEqual(""); +}); + +// Case: negative count +test("should throw an error when count is negative", () => { + const str = "hello"; + const count = -1; + expect(() => repeatStr(count, str)).toThrow( + "Count must be a non-negative integer" + ); +}); + +// Case: non-integer count +test("should throw an error when count is not an integer", () => { + const str = "hello"; + const count = 2.5; + expect(() => repeatStr(count, str)).toThrow( + "Count must be a non-negative integer" + ); +}); From 37b2b72305ffb5c8bb81c6e9837a290b42e6e584 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Thu, 12 Mar 2026 05:36:47 +0200 Subject: [PATCH 14/23] Add test case for non-alphabet characters in countChar --- Sprint-3/2-practice-tdd/count.test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Sprint-3/2-practice-tdd/count.test.js b/Sprint-3/2-practice-tdd/count.test.js index 568afa5fb4..3a88b2b99d 100644 --- a/Sprint-3/2-practice-tdd/count.test.js +++ b/Sprint-3/2-practice-tdd/count.test.js @@ -39,3 +39,10 @@ test("should be case sensitive", () => { const count = countChar(str, char); expect(count).toEqual(1); }); + +test("should count non-alphabet characters", () => { + const str = "hello!!!"; + const char = "!"; + const count = countChar(str, char); + expect(count).toEqual(3); +}); From 5497cfe25df571b8e1416325fdc5288d4e87362f Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Thu, 12 Mar 2026 05:46:31 +0200 Subject: [PATCH 15/23] test: clarify ordinal 'th' test case description --- Sprint-3/2-practice-tdd/get-ordinal-number.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 69af86024e..3c6d5f9019 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js @@ -41,10 +41,10 @@ test("should append 'th' for numbers ending with 11, 12, or 13", () => { expect(getOrdinalNumber(13)).toEqual("13th"); }); -// Case 4: All other numbers -// When the number does not end with 1, 2, or 3 (or ends with 11, 12, or 13), -// Then the function should return a string by appending "th" to the number. -test("should append 'th' for all other numbers", () => { +// Case 4: Numbers ending with 0 or 4–9 +// When the number ends with 0 or digits 4–9, +// Then the function should return a string by appending "th". +test("should append 'th' for numbers ending with 0 or 4–9", () => { expect(getOrdinalNumber(4)).toEqual("4th"); expect(getOrdinalNumber(10)).toEqual("10th"); expect(getOrdinalNumber(14)).toEqual("14th"); From 7217ad7fcebcc690912e80a5b4d7b2c1df567830 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Thu, 12 Mar 2026 07:18:39 +0200 Subject: [PATCH 16/23] fix: remove duplicate getAngleType function and ensure correct implementation --- .../implement/1-get-angle-type.js | 19 ++++++++++++-- .../1-get-angle-type.test.js | 26 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) 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..1447cc2d32 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,5 +1,5 @@ // 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° @@ -15,7 +15,22 @@ // execute the code to ensure all tests pass. function getAngleType(angle) { - // TODO: Implement this function + if (angle <= 0 || angle >= 360) { + return "Invalid angle"; + } + if (angle < 90) { + return "Acute angle"; + } + if (angle === 90) { + return "Right angle"; + } + if (angle < 180) { + return "Obtuse angle"; + } + if (angle === 180) { + return "Straight angle"; + } + return "Reflex angle"; } // The line below allows us to load the getAngleType function into tests in other files. 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..5f0b37a5bb 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,33 @@ test(`should return "Acute angle" when (0 < angle < 90)`, () => { }); // Case 2: Right angle +test(`should return "Right angle" when angle is exactly 90`, () => { + expect(getAngleType(90)).toEqual("Right angle"); +}); // Case 3: Obtuse angles +test(`should return "Obtuse angle" when (90 < angle < 180)`, () => { + // Test various obtuse angles, including boundary cases + expect(getAngleType(91)).toEqual("Obtuse angle"); + expect(getAngleType(135)).toEqual("Obtuse angle"); + expect(getAngleType(179)).toEqual("Obtuse angle"); +}); // Case 4: Straight angle +test(`should return "Straight angle" when angle is exactly 180`, () => { + expect(getAngleType(180)).toEqual("Straight angle"); +}); // Case 5: Reflex angles +test(`should return "Reflex angle" when (180 < angle < 360)`, () => { + // Test various reflex angles, including boundary cases + expect(getAngleType(181)).toEqual("Reflex angle"); + expect(getAngleType(270)).toEqual("Reflex angle"); + expect(getAngleType(359)).toEqual("Reflex angle"); +}); // Case 6: Invalid angles +test('should return "Invalid angle" when angle is 0 or negative', () => { + expect(getAngleType(0)).toEqual("Invalid angle"); + expect(getAngleType(-10)).toEqual("Invalid angle"); +}); +test('should return "Invalid angle" when angle is 360 or greater', () => { + expect(getAngleType(360)).toEqual("Invalid angle"); + expect(getAngleType(400)).toEqual("Invalid angle"); +}); From 607161c10e37cc27a8270220619c672d548c0c9b Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Thu, 12 Mar 2026 07:22:22 +0200 Subject: [PATCH 17/23] test: improve getOrdinalNumber test descriptions and coverage --- Sprint-3/2-practice-tdd/get-ordinal-number.test.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) 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 3c6d5f9019..c5a40fc2d2 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js @@ -14,11 +14,6 @@ test("should append 'nd' for numbers ending with 2, except those ending with 12" expect(getOrdinalNumber(132)).toEqual("132nd"); }); -// In this week's prep, we started implementing getOrdinalNumber. -// This function takes a number as input and returns a string with the appropriate ordinal suffix ("st", "nd", "rd", "th"). -// For example: -// - getOrdinalNumber(1) should return "1st" - // Continue testing and implementing getOrdinalNumber for additional cases. // Write your tests using Jest — remember to run your tests often for continual feedback. test("should append 'rd' for numbers ending with 3, except those ending with 13", () => { @@ -35,7 +30,7 @@ test("should append 'rd' for numbers ending with 3, except those ending with 13" // Case 1: Numbers ending with 1 (but not 11) // When the number ends with 1, except those ending with 11, // Then the function should return a string by appending "st" to the number. -test("should append 'th' for numbers ending with 11, 12, or 13", () => { +test("should append 'th' for special cases 11, 12, or 13", () => { expect(getOrdinalNumber(11)).toEqual("11th"); expect(getOrdinalNumber(12)).toEqual("12th"); expect(getOrdinalNumber(13)).toEqual("13th"); From 65182a54ad431c2146d78b1de13f1be13a772aeb Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Fri, 13 Mar 2026 13:44:11 +0200 Subject: [PATCH 18/23] deleted un related file --- Project-CLI-Treasure-Hunt | 1 - 1 file changed, 1 deletion(-) delete mode 160000 Project-CLI-Treasure-Hunt diff --git a/Project-CLI-Treasure-Hunt b/Project-CLI-Treasure-Hunt deleted file mode 160000 index 2f622599e0..0000000000 --- a/Project-CLI-Treasure-Hunt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2f622599e09fc28147949f59bcb6892ff6721548 From ab1f15e293ff1cfcf5a358810652ef7dad701b21 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Fri, 13 Mar 2026 13:47:02 +0200 Subject: [PATCH 19/23] reverted to previous description --- Sprint-3/2-practice-tdd/get-ordinal-number.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c5a40fc2d2..9a8bceb614 100644 --- a/Sprint-3/2-practice-tdd/get-ordinal-number.test.js +++ b/Sprint-3/2-practice-tdd/get-ordinal-number.test.js @@ -30,7 +30,7 @@ test("should append 'rd' for numbers ending with 3, except those ending with 13" // Case 1: Numbers ending with 1 (but not 11) // When the number ends with 1, except those ending with 11, // Then the function should return a string by appending "st" to the number. -test("should append 'th' for special cases 11, 12, or 13", () => { +test("should append 'th' for numbers ending with 11, 12, or 13", () => { expect(getOrdinalNumber(11)).toEqual("11th"); expect(getOrdinalNumber(12)).toEqual("12th"); expect(getOrdinalNumber(13)).toEqual("13th"); From f980882cae6fbe1da27f57a4c4d523b3db2b8984 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Fri, 13 Mar 2026 14:02:11 +0200 Subject: [PATCH 20/23] fixed the function --- Sprint-3/2-practice-tdd/repeat-str.js | 32 +++------------------------ 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/Sprint-3/2-practice-tdd/repeat-str.js b/Sprint-3/2-practice-tdd/repeat-str.js index d98581e54c..2d198a79e8 100644 --- a/Sprint-3/2-practice-tdd/repeat-str.js +++ b/Sprint-3/2-practice-tdd/repeat-str.js @@ -1,4 +1,7 @@ function repeatStr(n, str) { + if (!Number.isInteger(n) || n < 0) { + throw new Error("Count must be a non-negative integer"); + } let result = ""; for (let i = 0; i < n; i++) { result += str; @@ -7,32 +10,3 @@ function repeatStr(n, str) { } module.exports = repeatStr; -// const repeatStr = require("./repeat-str"); -// Given a target string `str` and a positive integer `count`, -// When the repeatStr function is called with these inputs, -// Then it should: -// test("repeats a string n times", () => { -// expect(repeatStr(3, "hello")).toBe("hellohellohello"); -// }); -const repeatStr = require("./repeat-str"); -test("repeats a string n times", () => { - expect(repeatStr(3, "hello")).toBe("hellohellohello"); -}); -// test("repeats a different string", () => { -// expect(repeatStr(2, "abc")).toBe("abcabc"); -// }); -test("repeats a different string", () => { - expect(repeatStr(2, "abc")).toBe("abcabc"); -}); -// test("returns empty string when n is 0", () => { -// expect(repeatStr(0, "hi")).toBe(""); -// }); -test("returns empty string when n is 0", () => { - expect(repeatStr(0, "hi")).toBe(""); -}); -// test("returns empty string when n is 0", () => { -// expect(repeatStr(0, "hi")).toBe(""); -// }); -test("returns empty string when n is 0", () => { - expect(repeatStr(0, "hi")).toBe(""); -}); From 77df336a5accc068f6f01017619ace09df990302 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Fri, 13 Mar 2026 14:23:40 +0200 Subject: [PATCH 21/23] Remove unrelated sprint folders from PR --- .../1-implement-and-rewrite-tests/README.md | 47 ---------- .../implement/1-get-angle-type.js | 52 ----------- .../implement/2-is-proper-fraction.js | 33 ------- .../implement/3-get-card-value.js | 52 ----------- .../1-get-angle-type.test.js | 46 ---------- .../2-is-proper-fraction.test.js | 10 -- .../3-get-card-value.test.js | 20 ---- .../testing-guide.md | 92 ------------------- Sprint-3/4-stretch/README.md | 9 -- Sprint-3/4-stretch/card-validator.md | 35 ------- Sprint-3/4-stretch/find.js | 25 ----- Sprint-3/4-stretch/password-validator.js | 6 -- Sprint-3/4-stretch/password-validator.test.js | 26 ------ 13 files changed, 453 deletions(-) delete mode 100644 Sprint-3/1-implement-and-rewrite-tests/README.md delete mode 100644 Sprint-3/1-implement-and-rewrite-tests/implement/1-get-angle-type.js delete mode 100644 Sprint-3/1-implement-and-rewrite-tests/implement/2-is-proper-fraction.js delete mode 100644 Sprint-3/1-implement-and-rewrite-tests/implement/3-get-card-value.js delete mode 100644 Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/1-get-angle-type.test.js delete mode 100644 Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/2-is-proper-fraction.test.js delete mode 100644 Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/3-get-card-value.test.js delete mode 100644 Sprint-3/1-implement-and-rewrite-tests/testing-guide.md delete mode 100644 Sprint-3/4-stretch/README.md delete mode 100644 Sprint-3/4-stretch/card-validator.md delete mode 100644 Sprint-3/4-stretch/find.js delete mode 100644 Sprint-3/4-stretch/password-validator.js delete mode 100644 Sprint-3/4-stretch/password-validator.test.js diff --git a/Sprint-3/1-implement-and-rewrite-tests/README.md b/Sprint-3/1-implement-and-rewrite-tests/README.md deleted file mode 100644 index a65bd2077c..0000000000 --- a/Sprint-3/1-implement-and-rewrite-tests/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Implement solutions and rewrite tests with Jest - -Before writing any code, please read the [Testing Function Guide](testing-guide.md) to learn how -to choose test values that thoroughly test a function. - -## 1 Implement solutions - -In the `implement` directory you've got a number of functions you'll need to implement. -For each function, you also have a number of different cases you'll need to check for your function. - -Write your assertions and build up your program case by case. Don't rush to a solution. The point of these assignments is to learn how to write assertions and build up a program step by step. - -Here is a recommended order: - -1. `1-get-angle-type.js` -2. `2-is-proper-fraction.js` -3. `3-get-card-value.js` - -## 2 Rewrite tests with Jest - -`console.log` is most often used as a debugging tool. We use to inspect the state of our program during runtime. - -We can use `console.assert` to write assertions: however, it is not very easy to use when writing large test suites. In the first section, Implement, we used a custom "helper function" to make our assertions more readable. - -Jest is a whole library of helper functions we can use to make our assertions more readable and easier to write. - -Your new task is to write the same tests as you wrote in the `implement` directory, but using Jest instead of `console.assert`. - -You shouldn't have to change the contents of `implement` to write these tests. - -There are files for your Jest tests in the `rewrite-tests-with-jest` directory. They will automatically use the functions you already implemented. - -You can run all the tests in this repo by running `npm test` in your terminal. However, VSCode has a built-in test runner that you can use to run the tests, and this should make it much easier to focus on building up your test cases one at a time. - -https://code.visualstudio.com/docs/editor/testing - -1. Go to rewrite-tests-with-jest/1-get-angle-type.test.js -2. Click the green play button to run the test. It's on the left of the test function in the gutter. -3. Read the output in the TEST_RESULTS tab at the bottom of the screen. -4. Explore all the tests in this repo by opening the TEST EXPLORER tab. The logo is a beaker. - -![VSCode Test Runner](../../run-this-test.png) - -![Test Results](../../test-results-output.png) - -> [!TIP] -> You can always run a single test file by running `npm test path/to/test-file.test.js`. 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 deleted file mode 100644 index 1447cc2d32..0000000000 --- a/Sprint-3/1-implement-and-rewrite-tests/implement/1-get-angle-type.js +++ /dev/null @@ -1,52 +0,0 @@ -// 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) { - if (angle <= 0 || angle >= 360) { - return "Invalid angle"; - } - if (angle < 90) { - return "Acute angle"; - } - if (angle === 90) { - return "Right angle"; - } - if (angle < 180) { - return "Obtuse angle"; - } - if (angle === 180) { - return "Straight angle"; - } - return "Reflex 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}` - ); -} - -// TODO: Write tests to cover all cases, including boundary and invalid cases. -// Example: Identify Right Angles -const right = getAngleType(90); -assertEquals(right, "Right 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 deleted file mode 100644 index 970cb9b641..0000000000 --- a/Sprint-3/1-implement-and-rewrite-tests/implement/2-is-proper-fraction.js +++ /dev/null @@ -1,33 +0,0 @@ -// 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) { - // TODO: Implement this function -} - -// 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. -// What combinations of numerators and denominators should you test? - -// Example: 1/2 is a proper fraction -assertEquals(isProperFraction(1, 2), true); 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 deleted file mode 100644 index c7559e787e..0000000000 --- a/Sprint-3/1-implement-and-rewrite-tests/implement/3-get-card-value.js +++ /dev/null @@ -1,52 +0,0 @@ -// 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) { - // TODO: Implement this function -} - -// 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); - -// Handling invalid cards -try { - getCardValue("invalid"); - - // This line will not be reached if an error is thrown as expected - console.error("Error was not thrown for invalid card"); -} catch (e) {} - -// What other invalid card cases can you think of? 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 deleted file mode 100644 index 5f0b37a5bb..0000000000 --- a/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/1-get-angle-type.test.js +++ /dev/null @@ -1,46 +0,0 @@ -// 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"); - -// TODO: Write tests in Jest syntax to cover all cases/outcomes, -// including boundary and invalid cases. - -// Case 1: Acute angles -test(`should return "Acute angle" when (0 < angle < 90)`, () => { - // Test various acute angles, including boundary cases - expect(getAngleType(1)).toEqual("Acute angle"); - expect(getAngleType(45)).toEqual("Acute angle"); - expect(getAngleType(89)).toEqual("Acute angle"); -}); - -// Case 2: Right angle -test(`should return "Right angle" when angle is exactly 90`, () => { - expect(getAngleType(90)).toEqual("Right angle"); -}); -// Case 3: Obtuse angles -test(`should return "Obtuse angle" when (90 < angle < 180)`, () => { - // Test various obtuse angles, including boundary cases - expect(getAngleType(91)).toEqual("Obtuse angle"); - expect(getAngleType(135)).toEqual("Obtuse angle"); - expect(getAngleType(179)).toEqual("Obtuse angle"); -}); -// Case 4: Straight angle -test(`should return "Straight angle" when angle is exactly 180`, () => { - expect(getAngleType(180)).toEqual("Straight angle"); -}); -// Case 5: Reflex angles -test(`should return "Reflex angle" when (180 < angle < 360)`, () => { - // Test various reflex angles, including boundary cases - expect(getAngleType(181)).toEqual("Reflex angle"); - expect(getAngleType(270)).toEqual("Reflex angle"); - expect(getAngleType(359)).toEqual("Reflex angle"); -}); -// Case 6: Invalid angles -test('should return "Invalid angle" when angle is 0 or negative', () => { - expect(getAngleType(0)).toEqual("Invalid angle"); - expect(getAngleType(-10)).toEqual("Invalid angle"); -}); -test('should return "Invalid angle" when angle is 360 or greater', () => { - expect(getAngleType(360)).toEqual("Invalid angle"); - expect(getAngleType(400)).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 deleted file mode 100644 index 7f087b2ba1..0000000000 --- a/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/2-is-proper-fraction.test.js +++ /dev/null @@ -1,10 +0,0 @@ -// 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"); - -// 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`, () => { - expect(isProperFraction(1, 0)).toEqual(false); -}); 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 deleted file mode 100644 index cf7f9dae2e..0000000000 --- a/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/3-get-card-value.test.js +++ /dev/null @@ -1,20 +0,0 @@ -// 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"); - -// TODO: Write tests in Jest syntax to cover all possible outcomes. - -// Case 1: Ace (A) -test(`Should return 11 when given an ace card`, () => { - 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 - -// 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/1-implement-and-rewrite-tests/testing-guide.md b/Sprint-3/1-implement-and-rewrite-tests/testing-guide.md deleted file mode 100644 index 917194e7a9..0000000000 --- a/Sprint-3/1-implement-and-rewrite-tests/testing-guide.md +++ /dev/null @@ -1,92 +0,0 @@ -# A Beginner's Guide to Testing Functions - -## 1. What Is a Function? - -``` -Input ──▶ Function ──▶ Output -``` - -A function -- Takes **input** (via **arguments**) -- Does some work -- Produces **one output** (via a **return value**) - -Example: - -``` -sum(2, 3) → 5 -``` - -Important idea: the same input should produce the same output. - - -## 2. Testing Means Predicting - -Testing means: -> If I give this input, what output should I get? - - -## 3. Choosing Good Test Values - -### Step 1: Determining the space of possible inputs -Ask: -- What type of value is expected? -- What values make sense? - - If they are numbers: - - Are they integers or floating-point numbers? - - What is their range? - - If they are strings: - - What are their length and patterns? -- What values would not make sense? - -### Step 2: Choosing Good Test Values - -#### Normal Cases - -These confirm that the function works in normal use. - -- What does a typical, ordinary input look like? -- Are there multiple ordinary groups of inputs? e.g. for an age checking function, maybe there are "adults" and "children" as expected ordinary groups of inputs. - - -#### Boundary Cases - -Test values exactly at, just inside, and just outside defined ranges. -These values are where logic breaks most often. - -#### Consider All Outcomes - -Every outcome must be reached by at least one test. - -- How many different results can this function produce? -- Have I tested a value that leads to each one? - -#### Crossing the Edges and Invalid Values - -This tests how the function behaves when assumptions are violated. -- What happens when input is outside of the expected range? -- What happens when input is not of the expected type? -- What happens when input is not in the expected format? - -## 4. How to Test - -### 1. Using `console.assert()` - -```javascript - // Report a failure only when the first argument is false - console.assert( sum(4, 6) === 10, "Expected 4 + 6 to equal 10" ); -``` - -It is simpler than using `if-else` and requires no setup. - -### 2. Jest Testing Framework - -```javascript - test("Should correctly return the sum of two positive numbers", () => { - expect( sum(4, 6) ).toEqual(10); - ... // Can test multiple samples - }); - -``` - -Jest supports many useful functions for testing but requires additional setup. diff --git a/Sprint-3/4-stretch/README.md b/Sprint-3/4-stretch/README.md deleted file mode 100644 index 8f01227bf9..0000000000 --- a/Sprint-3/4-stretch/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# 🔍 Stretch - -These stretch activities are not mandatory, but we hope you will explore them after you have completed the mandatory work. - -In this exercise, you'll need to **play computer** with the function `find`. This function makes use of while loop statement. Your task will be to step through the code to figure out what is happening when the computer executes the code. - -Next, try implementing the functions specified in `password-validator.js`. - -Finally, set up your own script and test files for `card-validator.md` diff --git a/Sprint-3/4-stretch/card-validator.md b/Sprint-3/4-stretch/card-validator.md deleted file mode 100644 index e39c6ace6e..0000000000 --- a/Sprint-3/4-stretch/card-validator.md +++ /dev/null @@ -1,35 +0,0 @@ -## **PROJECT: Credit Card Validator** - -In this project you'll write a script that validates whether or not a credit card number is valid. - -Here are the rules for a valid number: - -- Number must be 16 digits, all of them must be numbers. -- You must have at least two different digits represented (all of the digits cannot be the same). -- The final digit must be even. -- The sum of all the digits must be greater than 16. - -For example, the following credit card numbers are valid: - -```markdown -9999777788880000 -6666666666661666 -``` - -And the following credit card numbers are invalid: - -```markdown -a92332119c011112 (invalid characters) -4444444444444444 (only one type of number) -1111111111111110 (sum less than 16) -6666666666666661 (odd final number) -``` - -These are the requirements your project needs to fulfill: - -- Make a JavaScript file with a name that describes its contents. -- Create a function with a descriptive name which makes it clear what the function does. The function should take one argument, the credit card number to validate. -- Write at least 2 comments that explain to others what a line of code is meant to do. -- Return a boolean from the function to indicate whether the credit card number is valid. - -Good luck! diff --git a/Sprint-3/4-stretch/find.js b/Sprint-3/4-stretch/find.js deleted file mode 100644 index c7e79a2f21..0000000000 --- a/Sprint-3/4-stretch/find.js +++ /dev/null @@ -1,25 +0,0 @@ -function find(str, char) { - let index = 0; - - while (index < str.length) { - if (str[index] === char) { - return index; - } - index++; - } - return -1; -} - -console.log(find("code your future", "u")); -console.log(find("code your future", "z")); - -// The while loop statement allows us to do iteration - the repetition of a certain number of tasks according to some condition -// See the docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while - -// Use the Python Visualiser to help you play computer with this example and observe how this code is executed -// Pay particular attention to the following: - -// a) How the index variable updates during the call to find -// b) What is the if statement used to check -// c) Why is index++ being used? -// d) What is the condition index < str.length used for? diff --git a/Sprint-3/4-stretch/password-validator.js b/Sprint-3/4-stretch/password-validator.js deleted file mode 100644 index b55d527dba..0000000000 --- a/Sprint-3/4-stretch/password-validator.js +++ /dev/null @@ -1,6 +0,0 @@ -function passwordValidator(password) { - return password.length < 5 ? false : true -} - - -module.exports = passwordValidator; \ No newline at end of file diff --git a/Sprint-3/4-stretch/password-validator.test.js b/Sprint-3/4-stretch/password-validator.test.js deleted file mode 100644 index 8fa3089d6b..0000000000 --- a/Sprint-3/4-stretch/password-validator.test.js +++ /dev/null @@ -1,26 +0,0 @@ -/* -Password Validation - -Write a program that should check if a password is valid -and returns a boolean - -To be valid, a password must: -- Have at least 5 characters. -- Have at least one English uppercase letter (A-Z) -- Have at least one English lowercase letter (a-z) -- Have at least one number (0-9) -- Have at least one of the following non-alphanumeric symbols: ("!", "#", "$", "%", ".", "*", "&") -- Must not be any previous password in the passwords array. - -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 From ff3d1d37346bc38f4679c522faf80379983ac622 Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Sun, 15 Mar 2026 12:00:37 +0200 Subject: [PATCH 22/23] restored deleted files --- .../1-implement-and-rewrite-tests/README.md | 47 ++++++++++ .../implement/1-get-angle-type.js | 37 ++++++++ .../implement/2-is-proper-fraction.js | 33 +++++++ .../implement/3-get-card-value.js | 52 +++++++++++ .../1-get-angle-type.test.js | 20 ++++ .../2-is-proper-fraction.test.js | 10 ++ .../3-get-card-value.test.js | 20 ++++ .../testing-guide.md | 92 +++++++++++++++++++ 8 files changed, 311 insertions(+) create mode 100644 Sprint-3/1-implement-and-rewrite-tests/README.md create mode 100644 Sprint-3/1-implement-and-rewrite-tests/implement/1-get-angle-type.js create mode 100644 Sprint-3/1-implement-and-rewrite-tests/implement/2-is-proper-fraction.js create mode 100644 Sprint-3/1-implement-and-rewrite-tests/implement/3-get-card-value.js create mode 100644 Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/1-get-angle-type.test.js create mode 100644 Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/2-is-proper-fraction.test.js create mode 100644 Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/3-get-card-value.test.js create mode 100644 Sprint-3/1-implement-and-rewrite-tests/testing-guide.md diff --git a/Sprint-3/1-implement-and-rewrite-tests/README.md b/Sprint-3/1-implement-and-rewrite-tests/README.md new file mode 100644 index 0000000000..a65bd2077c --- /dev/null +++ b/Sprint-3/1-implement-and-rewrite-tests/README.md @@ -0,0 +1,47 @@ +# Implement solutions and rewrite tests with Jest + +Before writing any code, please read the [Testing Function Guide](testing-guide.md) to learn how +to choose test values that thoroughly test a function. + +## 1 Implement solutions + +In the `implement` directory you've got a number of functions you'll need to implement. +For each function, you also have a number of different cases you'll need to check for your function. + +Write your assertions and build up your program case by case. Don't rush to a solution. The point of these assignments is to learn how to write assertions and build up a program step by step. + +Here is a recommended order: + +1. `1-get-angle-type.js` +2. `2-is-proper-fraction.js` +3. `3-get-card-value.js` + +## 2 Rewrite tests with Jest + +`console.log` is most often used as a debugging tool. We use to inspect the state of our program during runtime. + +We can use `console.assert` to write assertions: however, it is not very easy to use when writing large test suites. In the first section, Implement, we used a custom "helper function" to make our assertions more readable. + +Jest is a whole library of helper functions we can use to make our assertions more readable and easier to write. + +Your new task is to write the same tests as you wrote in the `implement` directory, but using Jest instead of `console.assert`. + +You shouldn't have to change the contents of `implement` to write these tests. + +There are files for your Jest tests in the `rewrite-tests-with-jest` directory. They will automatically use the functions you already implemented. + +You can run all the tests in this repo by running `npm test` in your terminal. However, VSCode has a built-in test runner that you can use to run the tests, and this should make it much easier to focus on building up your test cases one at a time. + +https://code.visualstudio.com/docs/editor/testing + +1. Go to rewrite-tests-with-jest/1-get-angle-type.test.js +2. Click the green play button to run the test. It's on the left of the test function in the gutter. +3. Read the output in the TEST_RESULTS tab at the bottom of the screen. +4. Explore all the tests in this repo by opening the TEST EXPLORER tab. The logo is a beaker. + +![VSCode Test Runner](../../run-this-test.png) + +![Test Results](../../test-results-output.png) + +> [!TIP] +> You can always run a single test file by running `npm test path/to/test-file.test.js`. 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 new file mode 100644 index 0000000000..9e05a871e2 --- /dev/null +++ b/Sprint-3/1-implement-and-rewrite-tests/implement/1-get-angle-type.js @@ -0,0 +1,37 @@ +// 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"); 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 new file mode 100644 index 0000000000..970cb9b641 --- /dev/null +++ b/Sprint-3/1-implement-and-rewrite-tests/implement/2-is-proper-fraction.js @@ -0,0 +1,33 @@ +// 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) { + // TODO: Implement this function +} + +// 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. +// What combinations of numerators and denominators should you test? + +// Example: 1/2 is a proper fraction +assertEquals(isProperFraction(1, 2), true); 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 new file mode 100644 index 0000000000..c7559e787e --- /dev/null +++ b/Sprint-3/1-implement-and-rewrite-tests/implement/3-get-card-value.js @@ -0,0 +1,52 @@ +// 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) { + // TODO: Implement this function +} + +// 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); + +// Handling invalid cards +try { + getCardValue("invalid"); + + // This line will not be reached if an error is thrown as expected + console.error("Error was not thrown for invalid card"); +} catch (e) {} + +// What other invalid card cases can you think of? 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 new file mode 100644 index 0000000000..d777f348d3 --- /dev/null +++ b/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/1-get-angle-type.test.js @@ -0,0 +1,20 @@ +// 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"); + +// TODO: Write tests in Jest syntax to cover all cases/outcomes, +// including boundary and invalid cases. + +// Case 1: Acute angles +test(`should return "Acute angle" when (0 < angle < 90)`, () => { + // Test various acute angles, including boundary cases + expect(getAngleType(1)).toEqual("Acute angle"); + expect(getAngleType(45)).toEqual("Acute angle"); + expect(getAngleType(89)).toEqual("Acute angle"); +}); + +// Case 2: Right angle +// Case 3: Obtuse angles +// Case 4: Straight angle +// Case 5: Reflex angles +// Case 6: Invalid angles 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 new file mode 100644 index 0000000000..7f087b2ba1 --- /dev/null +++ b/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/2-is-proper-fraction.test.js @@ -0,0 +1,10 @@ +// 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"); + +// 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`, () => { + expect(isProperFraction(1, 0)).toEqual(false); +}); 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 new file mode 100644 index 0000000000..cf7f9dae2e --- /dev/null +++ b/Sprint-3/1-implement-and-rewrite-tests/rewrite-tests-with-jest/3-get-card-value.test.js @@ -0,0 +1,20 @@ +// 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"); + +// TODO: Write tests in Jest syntax to cover all possible outcomes. + +// Case 1: Ace (A) +test(`Should return 11 when given an ace card`, () => { + 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 + +// 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/1-implement-and-rewrite-tests/testing-guide.md b/Sprint-3/1-implement-and-rewrite-tests/testing-guide.md new file mode 100644 index 0000000000..917194e7a9 --- /dev/null +++ b/Sprint-3/1-implement-and-rewrite-tests/testing-guide.md @@ -0,0 +1,92 @@ +# A Beginner's Guide to Testing Functions + +## 1. What Is a Function? + +``` +Input ──▶ Function ──▶ Output +``` + +A function +- Takes **input** (via **arguments**) +- Does some work +- Produces **one output** (via a **return value**) + +Example: + +``` +sum(2, 3) → 5 +``` + +Important idea: the same input should produce the same output. + + +## 2. Testing Means Predicting + +Testing means: +> If I give this input, what output should I get? + + +## 3. Choosing Good Test Values + +### Step 1: Determining the space of possible inputs +Ask: +- What type of value is expected? +- What values make sense? + - If they are numbers: + - Are they integers or floating-point numbers? + - What is their range? + - If they are strings: + - What are their length and patterns? +- What values would not make sense? + +### Step 2: Choosing Good Test Values + +#### Normal Cases + +These confirm that the function works in normal use. + +- What does a typical, ordinary input look like? +- Are there multiple ordinary groups of inputs? e.g. for an age checking function, maybe there are "adults" and "children" as expected ordinary groups of inputs. + + +#### Boundary Cases + +Test values exactly at, just inside, and just outside defined ranges. +These values are where logic breaks most often. + +#### Consider All Outcomes + +Every outcome must be reached by at least one test. + +- How many different results can this function produce? +- Have I tested a value that leads to each one? + +#### Crossing the Edges and Invalid Values + +This tests how the function behaves when assumptions are violated. +- What happens when input is outside of the expected range? +- What happens when input is not of the expected type? +- What happens when input is not in the expected format? + +## 4. How to Test + +### 1. Using `console.assert()` + +```javascript + // Report a failure only when the first argument is false + console.assert( sum(4, 6) === 10, "Expected 4 + 6 to equal 10" ); +``` + +It is simpler than using `if-else` and requires no setup. + +### 2. Jest Testing Framework + +```javascript + test("Should correctly return the sum of two positive numbers", () => { + expect( sum(4, 6) ).toEqual(10); + ... // Can test multiple samples + }); + +``` + +Jest supports many useful functions for testing but requires additional setup. From 32f9cc14a8f80f7905c32349e3d4d88ed80b124d Mon Sep 17 00:00:00 2001 From: Pretty Taruvinga Date: Sun, 15 Mar 2026 12:12:47 +0200 Subject: [PATCH 23/23] restored the deleted file --- Sprint-3/4-stretch/README.md | 9 +++++ Sprint-3/4-stretch/card-validator.md | 35 +++++++++++++++++++ Sprint-3/4-stretch/find.js | 25 +++++++++++++ Sprint-3/4-stretch/password-validator.js | 6 ++++ Sprint-3/4-stretch/password-validator.test.js | 26 ++++++++++++++ 5 files changed, 101 insertions(+) create mode 100644 Sprint-3/4-stretch/README.md create mode 100644 Sprint-3/4-stretch/card-validator.md create mode 100644 Sprint-3/4-stretch/find.js create mode 100644 Sprint-3/4-stretch/password-validator.js create mode 100644 Sprint-3/4-stretch/password-validator.test.js diff --git a/Sprint-3/4-stretch/README.md b/Sprint-3/4-stretch/README.md new file mode 100644 index 0000000000..8f01227bf9 --- /dev/null +++ b/Sprint-3/4-stretch/README.md @@ -0,0 +1,9 @@ +# 🔍 Stretch + +These stretch activities are not mandatory, but we hope you will explore them after you have completed the mandatory work. + +In this exercise, you'll need to **play computer** with the function `find`. This function makes use of while loop statement. Your task will be to step through the code to figure out what is happening when the computer executes the code. + +Next, try implementing the functions specified in `password-validator.js`. + +Finally, set up your own script and test files for `card-validator.md` diff --git a/Sprint-3/4-stretch/card-validator.md b/Sprint-3/4-stretch/card-validator.md new file mode 100644 index 0000000000..e39c6ace6e --- /dev/null +++ b/Sprint-3/4-stretch/card-validator.md @@ -0,0 +1,35 @@ +## **PROJECT: Credit Card Validator** + +In this project you'll write a script that validates whether or not a credit card number is valid. + +Here are the rules for a valid number: + +- Number must be 16 digits, all of them must be numbers. +- You must have at least two different digits represented (all of the digits cannot be the same). +- The final digit must be even. +- The sum of all the digits must be greater than 16. + +For example, the following credit card numbers are valid: + +```markdown +9999777788880000 +6666666666661666 +``` + +And the following credit card numbers are invalid: + +```markdown +a92332119c011112 (invalid characters) +4444444444444444 (only one type of number) +1111111111111110 (sum less than 16) +6666666666666661 (odd final number) +``` + +These are the requirements your project needs to fulfill: + +- Make a JavaScript file with a name that describes its contents. +- Create a function with a descriptive name which makes it clear what the function does. The function should take one argument, the credit card number to validate. +- Write at least 2 comments that explain to others what a line of code is meant to do. +- Return a boolean from the function to indicate whether the credit card number is valid. + +Good luck! diff --git a/Sprint-3/4-stretch/find.js b/Sprint-3/4-stretch/find.js new file mode 100644 index 0000000000..c7e79a2f21 --- /dev/null +++ b/Sprint-3/4-stretch/find.js @@ -0,0 +1,25 @@ +function find(str, char) { + let index = 0; + + while (index < str.length) { + if (str[index] === char) { + return index; + } + index++; + } + return -1; +} + +console.log(find("code your future", "u")); +console.log(find("code your future", "z")); + +// The while loop statement allows us to do iteration - the repetition of a certain number of tasks according to some condition +// See the docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while + +// Use the Python Visualiser to help you play computer with this example and observe how this code is executed +// Pay particular attention to the following: + +// a) How the index variable updates during the call to find +// b) What is the if statement used to check +// c) Why is index++ being used? +// d) What is the condition index < str.length used for? diff --git a/Sprint-3/4-stretch/password-validator.js b/Sprint-3/4-stretch/password-validator.js new file mode 100644 index 0000000000..b55d527dba --- /dev/null +++ b/Sprint-3/4-stretch/password-validator.js @@ -0,0 +1,6 @@ +function passwordValidator(password) { + return password.length < 5 ? false : true +} + + +module.exports = passwordValidator; \ No newline at end of file diff --git a/Sprint-3/4-stretch/password-validator.test.js b/Sprint-3/4-stretch/password-validator.test.js new file mode 100644 index 0000000000..8fa3089d6b --- /dev/null +++ b/Sprint-3/4-stretch/password-validator.test.js @@ -0,0 +1,26 @@ +/* +Password Validation + +Write a program that should check if a password is valid +and returns a boolean + +To be valid, a password must: +- Have at least 5 characters. +- Have at least one English uppercase letter (A-Z) +- Have at least one English lowercase letter (a-z) +- Have at least one number (0-9) +- Have at least one of the following non-alphanumeric symbols: ("!", "#", "$", "%", ".", "*", "&") +- Must not be any previous password in the passwords array. + +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