From 5f153097509cc1d399190ea79860b33aa9abb2a3 Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Tue, 31 Mar 2026 15:26:18 +0100 Subject: [PATCH 01/15] predicting the output and debugging the code. --- Sprint-2/debug/address.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..f04f731c8 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,5 +1,5 @@ // Predict and explain first... - +// this code should log out undefined because even the object "address" is well defined but the property "houseNumber" is not being correctly accessed in the last line of code. // This code should log out the houseNumber from the address object // but it isn't working... // Fix anything that isn't working @@ -12,4 +12,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address.houseNumber}`); From 5638fc490187647ca1b8bd6bae329c2c2e5ac3f6 Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Tue, 31 Mar 2026 15:41:25 +0100 Subject: [PATCH 02/15] predicting and debugging --- Sprint-2/debug/author.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..e9fa5b762 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,5 +1,5 @@ // Predict and explain first... - +// it should log out an error because the for statement is not correctly expressed and the prorties of the object are accessed instead of the values. // This program attempts to log out all the property values in the object. // But it isn't working. Explain why first and then fix the problem @@ -11,6 +11,6 @@ const author = { alive: true, }; -for (const value of author) { - console.log(value); +for (const value in author) { + console.log(author[value]); } From 70fe1ba7d0bfddcc0c1f5a8118ea972ac26f088e Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Tue, 31 Mar 2026 15:49:39 +0100 Subject: [PATCH 03/15] predicting and debugging --- Sprint-2/debug/recipe.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..259f9a2ba 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,5 +1,5 @@ // Predict and explain first... - +// it should not log out the ingredients property's values because the ingredients are stored in an array and the code is not correctly accessing the array elements. // This program should log out the title, how many it serves and the ingredients. // Each ingredient should be logged on a new line // How can you fix it? @@ -12,4 +12,4 @@ const recipe = { console.log(`${recipe.title} serves ${recipe.serves} ingredients: -${recipe}`); +${recipe.ingredients.join("\n")}`); From 648ae2883ecbb0f8768b955676ca3bc0711cccc9 Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Sun, 5 Apr 2026 16:31:07 +0100 Subject: [PATCH 04/15] implements a function that returns true if the object has a given property, and false otherwise --- Sprint-2/implement/contains.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..276ce3eab 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,6 @@ -function contains() {} +function contains(obj, name) { + if (typeof obj == "object" || obj !== null || Object.keys(obj).length !== 0) + return Object.hasOwn(obj, name); +} module.exports = contains; From d76a207ed3f6f78b358b0542b79d48afb42b46bb Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Sun, 5 Apr 2026 17:15:30 +0100 Subject: [PATCH 05/15] implemented the createLookup function --- Sprint-2/implement/lookup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..5c120898b 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,5 @@ -function createLookup() { - // implementation here +function createLookup(countryCurrencyPairs) { + return Object.fromEntries(countryCurrencyPairs); } module.exports = createLookup; From dcafc3b7a3694df9ce05b2a731db792ed4cc0702 Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Sun, 5 Apr 2026 19:18:33 +0100 Subject: [PATCH 06/15] cover missing case --- Sprint-2/implement/contains.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 276ce3eab..03f3da11f 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,6 +1,7 @@ function contains(obj, name) { if (typeof obj == "object" || obj !== null || Object.keys(obj).length !== 0) return Object.hasOwn(obj, name); + return false; } module.exports = contains; From 2830956ba51d8003e6dd75342c24883ea90781ab Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Tue, 7 Apr 2026 15:58:43 +0100 Subject: [PATCH 07/15] completed the todo tests --- Sprint-2/implement/contains.test.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..c28f10082 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -20,16 +20,31 @@ as the object doesn't contains a key of 'c' // Given an empty object // When passed to contains // Then it should return false -test.todo("contains on empty object returns false"); +test("given an empty object, returns false", () => { + expect(contains({}, "x")).toEqual(false); +}); // Given an object with properties // When passed to contains with an existing property name // Then it should return true +test("given an object with properties, returns true when passed to contains with an existing property name", () => { + expect( + contains({ gitName: "djebsoft", position: "cyf trainee" }, "gitName") + ).toEqual(true); +}); // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +test("given an object with properties, returns false when passed to contains with a non-existent property name", () => { + expect( + contains({ gitName: "djebsoft", position: "cyf trainee" }, "age") + ).toEqual(false); +}); // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +test("given invalid parameters, returns false or throws an error", () => { + expect(contains(["gitName", "position"], "gitName")).toEqual(false); +}); From 611d2471a0bec575b133396c0c2fcd9952f168b4 Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Thu, 9 Apr 2026 00:10:38 +0100 Subject: [PATCH 08/15] complted sprint-2 coursework --- Sprint-2/implement/lookup.js | 25 +++++++- Sprint-2/implement/lookup.test.js | 44 +++++++++++++- Sprint-2/implement/querystring.js | 11 +++- Sprint-2/implement/querystring.test.js | 79 +++++++++++++++++++++++++- Sprint-2/implement/tally.js | 13 ++++- Sprint-2/implement/tally.test.js | 53 ++++++++++++++++- Sprint-2/interpret/invert.js | 14 ++++- Sprint-2/interpret/invert.test.js | 36 ++++++++++++ 8 files changed, 260 insertions(+), 15 deletions(-) create mode 100644 Sprint-2/interpret/invert.test.js diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 5c120898b..8de5ff2db 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,24 @@ -function createLookup(countryCurrencyPairs) { - return Object.fromEntries(countryCurrencyPairs); +// the first element is the country code +// the second array is the currency code of the country +// the function should return an object +// the keys of the object should be the first element of each inner array (country code) +// the values of the object should be the second element of each inner array (currency code) + +function Lookup(coCuPairs) { + // check if the argument is an array of arrays + if ( + Array.isArray(coCuPairs) && + // check if each inner array is an array. + coCuPairs.every((pair) => Array.isArray(pair)) && + // check if each inner array has two elements. + coCuPairs.every((pair) => pair.length === 2) + // we can also use index to check the pair is an array as follows: + // for (let i = 0; i < coCuPairs.length; i++) + // return Array.isArray(coCuPairs[i]) + ) { + return Object.fromEntries(coCuPairs); + } + return "Invalid input: expected an array of arrays"; } -module.exports = createLookup; +module.exports = Lookup; diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..e7ad82a83 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,6 +1,18 @@ -const createLookup = require("./lookup.js"); +const Lookup = require("./lookup.js"); -test.todo("creates a country currency code lookup for multiple codes"); +test("creates a country currency code lookup for multiple codes", () => { + const input = [ + ["DZ", "DZD"], + ["CA", "CAD"], + ["GB", "GBP"], + ]; + const result = { + DZ: "DZD", + CA: "CAD", + GB: "GBP", + }; + expect(Lookup(input)).toEqual(result); +}); /* @@ -24,7 +36,7 @@ Example Given: [['US', 'USD'], ['CA', 'CAD']] When -createLookup(countryCurrencyPairs) is called +Lookup(coCuPairs) is called Then It should return: @@ -33,3 +45,29 @@ It should return: 'CA': 'CAD' } */ +// Given an invalid input (not an array of arrays), +test('return "Invalid input: expected an array of arrays" for string input', () => { + const input = "invalid input: expected an array of arrays"; + expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays"); +}); + +// Given an array where its elements are not arrays, +test('return "Invalid input: expected an array of arrays" for non-array elements', () => { + const input = [["US", "USD"], "CA"]; + expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays"); +}); + +// Given an array where its elements are arrays with more than two elements, +test('return "Invalid input: expected an array of arrays" for arrays with too many elements', () => { + const input = [ + ["US", "USD", "flag"], + ["CA", "CAD"], + ]; + expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays"); +}); + +// Given an array where its elements are arrays with less than two elements, +test('return "Invalid input: expected an array of arrays" for arrays with too few elements', () => { + const input = [["US", "USD"], ["CA"]]; + expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays"); +}); diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..cad8592a6 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,13 +1,20 @@ +// the bug in the code is that it does not handle cases where the query string has two = signs or more between two parameters. +// in this case we make sure to split the string only at the first = sign. +// so we use the spread operator. function parseQueryString(queryString) { const queryParams = {}; + if (queryString === null || queryString === undefined) { + return "invalid query string"; + } if (queryString.length === 0) { return queryParams; } const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); - queryParams[key] = value; + const [key, ...value] = pair.split("="); + // we convert the value array back to a string and we get back the = signs by using it as separator. + queryParams[key] = value.join("="); } return queryParams; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 3e218b789..d9171b8c9 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -3,10 +3,85 @@ // Below is one test case for an edge case the implementation doesn't handle well. // Fix the implementation for this test, and try to think of as many other edge cases as possible - write tests and fix those too. -const parseQueryString = require("./querystring.js") +const parseQueryString = require("./querystring.js"); +// testing when the query string with a value contains = signs test("parses querystring values containing =", () => { expect(parseQueryString("equation=x=y+1")).toEqual({ - "equation": "x=y+1", + equation: "x=y+1", + }); +}); + +// testing when the query string has multiple ampersands +test("parses query string with multiple parameters", () => { + expect(parseQueryString("name=Ben&age=45&city=new%20city")).toEqual({ + name: "Ben", + age: "45", + city: "new%20city", + }); +}); + +// testing when the query string has two ampersands in a row +test("parses query string with two ampersands in a row", () => { + expect(parseQueryString("name=Ben&&age=45")).toEqual({ + name: "Ben", + "": "", + age: "45", + }); +}); + +// testing when the query string has no ampersands +test("parses query string with no ampersands", () => { + expect(parseQueryString("name=Ben")).toEqual({ + name: "Ben", + }); +}); + +// testing when the query string has no ampersands and no equal signs +test("parses query string with no ampersands and no equal signs", () => { + expect(parseQueryString("name")).toEqual({ + name: "", + }); +}); + +// testing when the query string is empty +test("parses query string with empty value", () => { + expect(parseQueryString("")).toEqual({}); +}); + +// testing when the query string is null +test("parses query string with null value", () => { + expect(parseQueryString(null)).toEqual("invalid query string"); +}); + +// testing when the query string is undefined +test("parses query string with undefined value", () => { + expect(parseQueryString(undefined)).toEqual("invalid query string"); +}); + +// testing when a pair ends with equal sign (no value) +test("parses query string with no equal sign", () => { + expect(parseQueryString("name=Ben&age=&city=")).toEqual({ + name: "Ben", + age: "", + city: "", + }); +}); + +// testing when a pair starts with equal sign (no key) +test("parses query string starting with equal sign", () => { + expect(parseQueryString("name=Ben&=45")).toEqual({ + name: "Ben", + "": "45", + }); +}); + +// testing when a pair has no equal sign (no value and no key) +// the pair will be the key and the value will be an empty string +test("parses query string with no equal sign", () => { + expect(parseQueryString("name&age=45&city")).toEqual({ + name: "", + age: "45", + city: "", }); }); diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..955f2c482 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,12 @@ -function tally() {} - +function tally(arr) { + if (!Array.isArray(arr)) { + throw new Error("invalid input"); + } + let result = {}; + for (let i = 0; i <= arr.length - 1; i++) { + let item = arr[i]; + result[item] = (result[item] || 0) + 1; + } + return result; +} module.exports = tally; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..3dd61e91e 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -23,12 +23,63 @@ const tally = require("./tally.js"); // Given an empty array // When passed to tally // Then it should return an empty object -test.todo("tally on an empty array returns an empty object"); +test("tally on an empty array returns an empty object", () => { + expect(tally([])).toEqual({}); +}); // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item +test("tally on an empty array returns an empty object", () => { + expect(tally([])).toEqual({}); +}); + +// Given an array with duplicate items +// When passed to tally +// Then it should return counts for each unique item +test("tally on an array with duplicates returns correct counts for each unique item", () => { + expect( + tally([ + "CYF", + "CYF", + "AWS", + "Capgemini", + "Deloitte", + "Google", + "Slack", + "Capgemini", + ]) + ).toEqual({ CYF: 2, AWS: 1, Capgemini: 2, Deloitte: 1, Google: 1, Slack: 1 }); +}); // Given an invalid input like a string // When passed to tally // Then it should throw an error +test("given invalid input throws an error", () => { + expect(() => tally("invalid")).toThrow("invalid input"); +}); + +// Given an invalid input like a number +test("given invalid input throws an error", () => { + expect(() => tally("invalid")).toThrow("invalid input"); +}); + +// Given an invalid input like a number +test("given invalid input throws an error", () => { + expect(() => tally(123)).toThrow("invalid input"); +}); + +// Given an invalid input like an object +test("given invalid input throws an error", () => { + expect(() => tally({})).toThrow("invalid input"); +}); + +// Given an invalid input like null +test("given invalid input throws an error", () => { + expect(() => tally(null)).toThrow("invalid input"); +}); + +// Given an invalid input like undefined +test("given invalid input throws an error", () => { + expect(() => tally(undefined)).toThrow("invalid input"); +}); diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..e8bd4fb20 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -8,22 +8,32 @@ function invert(obj) { const invertedObj = {}; - + if (typeof obj !== "object" || obj === null || Array.isArray(obj)) + return invertedObj; for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; + invertedObj[value] = key; } return invertedObj; } // a) What is the current return value when invert is called with { a : 1 } +// {key: 1} // b) What is the current return value when invert is called with { a: 1, b: 2 } +// {key: 2} // c) What is the target return value when invert is called with {a : 1, b: 2} +// {"1": "a", "2": "b"} // c) What does Object.entries return? Why is it needed in this program? +// it returns an array of the pairs properties [key, value] of the object. +// it is needed in this program to iterate over the key value pairs of the object to swap them in new object. // d) Explain why the current return value is different from the target output +// because first it doesn't swap. +// second, we're using the dot notation to assign the value where we should user the brackets notation as the key is variable and not a string literal. // e) Fix the implementation of invert (and write tests to prove it's fixed!) + +module.exports = invert; diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js new file mode 100644 index 000000000..927bed307 --- /dev/null +++ b/Sprint-2/interpret/invert.test.js @@ -0,0 +1,36 @@ +const invert = require("./invert.js"); +// writing some tests. +// Given an simple ordinary object. +test("invert on a simple object returns the correct inverted object", () => { + expect(invert({ a: 1 })).toEqual({ 1: "a" }); +}); +// Given an object with multiple key value pairs. +test("invert on an object with multiple key value pairs returns the correct inverted object", () => { + expect(invert({ a: 1, b: 2 })).toEqual({ 1: "a", 2: "b" }); +}); +// Given an object with duplicate values. +test("invert on an object with duplicate values returns the correct inverted object", () => { + expect(invert({ a: 1, b: 1 })).toEqual({ 1: "a", 1: "b" }); +}); +// Given an empty object. +test("invert on an empty object returns an empty object", () => { + expect(invert({})).toEqual({}); +}); +// Given an invalid input like a string. +test("invert on an invalid input like a string returns an empty object", () => { + expect(invert("invalid")).toEqual({}); +}); + +// Given an invalid input like a number. +test("invert on an invalid input like a number returns an empty object", () => { + expect(invert(123)).toEqual({}); +}); +// Given an invalid input like an array. +test("invert on an invalid input like an array returns an empty object", () => { + expect(invert([1, 2, 3])).toEqual({}); +}); +// Given an invalid input like null or undefined. +test("invert on an invalid input like null or undefined returns an empty object", () => { + expect(invert(null)).toEqual({}); + expect(invert(undefined)).toEqual({}); +}); From 0dddbf3170215d217bcfc3a6f791ff78e06772ae Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Thu, 9 Apr 2026 08:52:33 +0100 Subject: [PATCH 09/15] fixed contains function --- Sprint-2/implement/contains.js | 7 ++++--- Sprint-2/implement/contains.test.js | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 03f3da11f..a49b5cf01 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,7 +1,8 @@ function contains(obj, name) { - if (typeof obj == "object" || obj !== null || Object.keys(obj).length !== 0) - return Object.hasOwn(obj, name); - return false; + if (typeof obj !== "object" || obj === null || Array.isArray(obj)) { + return false; + } + return Object.hasOwn(obj, name); } module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index c28f10082..7c326b099 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -45,6 +45,10 @@ test("given an object with properties, returns false when passed to contains wit // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error -test("given invalid parameters, returns false or throws an error", () => { +test("given invalid parameters (array), returns false or throws an error", () => { expect(contains(["gitName", "position"], "gitName")).toEqual(false); }); + +test("given invalid parameters (like null or undefined), returns false or throws an error", () => { + expect(contains(null, "gitName")).toEqual(false); +}); From e90345044ea20d7c2e6f6af3650c2aeb853296aa Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Thu, 9 Apr 2026 09:08:31 +0100 Subject: [PATCH 10/15] changed the name of the parameter --- Sprint-2/implement/lookup.js | 14 +++++++------- Sprint-2/implement/lookup.test.js | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 8de5ff2db..0a2c058da 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -4,19 +4,19 @@ // the keys of the object should be the first element of each inner array (country code) // the values of the object should be the second element of each inner array (currency code) -function Lookup(coCuPairs) { +function Lookup(countryCurrencyPairs) { // check if the argument is an array of arrays if ( - Array.isArray(coCuPairs) && + Array.isArray(countryCurrencyPairs) && // check if each inner array is an array. - coCuPairs.every((pair) => Array.isArray(pair)) && + countryCurrencyPairs.every((pair) => Array.isArray(pair)) && // check if each inner array has two elements. - coCuPairs.every((pair) => pair.length === 2) + countryCurrencyPairs.every((pair) => pair.length === 2) // we can also use index to check the pair is an array as follows: - // for (let i = 0; i < coCuPairs.length; i++) - // return Array.isArray(coCuPairs[i]) + // for (let i = 0; i < countryCurrencyPairs.length; i++) + // return Array.isArray(countryCurrencyPairs[i]) ) { - return Object.fromEntries(coCuPairs); + return Object.fromEntries(countryCurrencyPairs); } return "Invalid input: expected an array of arrays"; } diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index e7ad82a83..23b6703e1 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -36,7 +36,7 @@ Example Given: [['US', 'USD'], ['CA', 'CAD']] When -Lookup(coCuPairs) is called +Lookup(countryCurrencyPairs) is called Then It should return: From 5eee074fd594c4eafbfd50677e33b7a437ddd8ba Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Thu, 9 Apr 2026 09:51:29 +0100 Subject: [PATCH 11/15] throw an error instead --- Sprint-2/implement/lookup.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 0a2c058da..9598f2dfe 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -7,18 +7,18 @@ function Lookup(countryCurrencyPairs) { // check if the argument is an array of arrays if ( - Array.isArray(countryCurrencyPairs) && + !Array.isArray(countryCurrencyPairs) || // check if each inner array is an array. - countryCurrencyPairs.every((pair) => Array.isArray(pair)) && + !countryCurrencyPairs.every((pair) => Array.isArray(pair)) || // check if each inner array has two elements. - countryCurrencyPairs.every((pair) => pair.length === 2) + !countryCurrencyPairs.every((pair) => pair.length === 2) // we can also use index to check the pair is an array as follows: // for (let i = 0; i < countryCurrencyPairs.length; i++) // return Array.isArray(countryCurrencyPairs[i]) ) { - return Object.fromEntries(countryCurrencyPairs); + throw new Error("Invalid input: expected an array of arrays"); } - return "Invalid input: expected an array of arrays"; + return Object.fromEntries(countryCurrencyPairs); } module.exports = Lookup; From df82c4f706302b54e029ca8e36c7178ff29f49c1 Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Thu, 9 Apr 2026 13:06:23 +0100 Subject: [PATCH 12/15] fixed all errors to pass all tests --- Sprint-2/implement/lookup.js | 4 ++-- Sprint-2/implement/lookup.test.js | 28 ++++++++++++++++++---------- Sprint-2/implement/tally.js | 3 ++- Sprint-2/implement/tally.test.js | 21 +++++++++------------ 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 9598f2dfe..944eb404c 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -9,9 +9,9 @@ function Lookup(countryCurrencyPairs) { if ( !Array.isArray(countryCurrencyPairs) || // check if each inner array is an array. - !countryCurrencyPairs.every((pair) => Array.isArray(pair)) || + countryCurrencyPairs.some((pair) => !Array.isArray(pair)) || // check if each inner array has two elements. - !countryCurrencyPairs.every((pair) => pair.length === 2) + countryCurrencyPairs.some((pair) => pair.length !== 2) // we can also use index to check the pair is an array as follows: // for (let i = 0; i < countryCurrencyPairs.length; i++) // return Array.isArray(countryCurrencyPairs[i]) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 23b6703e1..1909a7039 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -46,28 +46,36 @@ It should return: } */ // Given an invalid input (not an array of arrays), -test('return "Invalid input: expected an array of arrays" for string input', () => { - const input = "invalid input: expected an array of arrays"; - expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays"); +test('given string input throw "Invalid input: expected an array of arrays"', () => { + let input = "invalid input: expected an array of arrays"; + expect(() => Lookup(input)).toThrow( + "Invalid input: expected an array of arrays" + ); }); // Given an array where its elements are not arrays, -test('return "Invalid input: expected an array of arrays" for non-array elements', () => { - const input = [["US", "USD"], "CA"]; - expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays"); +test('given array with non-array elements throw "Invalid input: expected an array of arrays"', () => { + let input = [["US", "USD"], "CA"]; + expect(() => Lookup(input)).toThrow( + "Invalid input: expected an array of arrays" + ); }); // Given an array where its elements are arrays with more than two elements, -test('return "Invalid input: expected an array of arrays" for arrays with too many elements', () => { +test('given arrays with too many elements throw "Invalid input: expected an array of arrays"', () => { const input = [ ["US", "USD", "flag"], ["CA", "CAD"], ]; - expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays"); + expect(() => Lookup(input)).toThrow( + "Invalid input: expected an array of arrays" + ); }); // Given an array where its elements are arrays with less than two elements, -test('return "Invalid input: expected an array of arrays" for arrays with too few elements', () => { +test('given arrays with too few elements throw "Invalid input: expected an array of arrays"', () => { const input = [["US", "USD"], ["CA"]]; - expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays"); + expect(() => Lookup(input)).toThrow( + "Invalid input: expected an array of arrays" + ); }); diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 955f2c482..ab2ba96bc 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -2,7 +2,8 @@ function tally(arr) { if (!Array.isArray(arr)) { throw new Error("invalid input"); } - let result = {}; + // using Object.create(null) to create a plain object without prototype + let result = Object.create(null); for (let i = 0; i <= arr.length - 1; i++) { let item = arr[i]; result[item] = (result[item] || 0) + 1; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 3dd61e91e..68e1ec667 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -27,13 +27,6 @@ test("tally on an empty array returns an empty object", () => { expect(tally([])).toEqual({}); }); -// Given an array with duplicate items -// When passed to tally -// Then it should return counts for each unique item -test("tally on an empty array returns an empty object", () => { - expect(tally([])).toEqual({}); -}); - // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item @@ -52,6 +45,15 @@ test("tally on an array with duplicates returns correct counts for each unique i ).toEqual({ CYF: 2, AWS: 1, Capgemini: 2, Deloitte: 1, Google: 1, Slack: 1 }); }); +test("tally on an array with duplicates returns correct counts for each unique item", () => { + expect(tally(["toString", "toString"])).toEqual({ toString: 2 }); +}); + +// Given an input that you mentioned in the review. +//test("tally on an array with duplicates returns correct counts for each unique item", () => { +// expect(tally(["toString", "toString"])).toEqual({ toString: 2 }); +//}); + // Given an invalid input like a string // When passed to tally // Then it should throw an error @@ -59,11 +61,6 @@ test("given invalid input throws an error", () => { expect(() => tally("invalid")).toThrow("invalid input"); }); -// Given an invalid input like a number -test("given invalid input throws an error", () => { - expect(() => tally("invalid")).toThrow("invalid input"); -}); - // Given an invalid input like a number test("given invalid input throws an error", () => { expect(() => tally(123)).toThrow("invalid input"); From 6a6d255c5794d3ac3f488f77a1e01199d7ea5d5a Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Thu, 9 Apr 2026 13:28:52 +0100 Subject: [PATCH 13/15] adjusted the function name --- Sprint-2/implement/lookup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 944eb404c..a5bb64409 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -4,7 +4,7 @@ // the keys of the object should be the first element of each inner array (country code) // the values of the object should be the second element of each inner array (currency code) -function Lookup(countryCurrencyPairs) { +function createLookup(countryCurrencyPairs) { // check if the argument is an array of arrays if ( !Array.isArray(countryCurrencyPairs) || @@ -21,4 +21,4 @@ function Lookup(countryCurrencyPairs) { return Object.fromEntries(countryCurrencyPairs); } -module.exports = Lookup; +module.exports = createLookup; From 57fab6119bb25fc5b018e3791ca69b16738f6b07 Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Thu, 9 Apr 2026 17:41:18 +0100 Subject: [PATCH 14/15] updated the array input test. --- Sprint-2/implement/contains.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 7c326b099..1548d3e8d 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -46,7 +46,7 @@ test("given an object with properties, returns false when passed to contains wit // When passed to contains // Then it should return false or throw an error test("given invalid parameters (array), returns false or throws an error", () => { - expect(contains(["gitName", "position"], "gitName")).toEqual(false); + expect(contains(["gitName", "age", "position"], "cohort")).toEqual(false); }); test("given invalid parameters (like null or undefined), returns false or throws an error", () => { From 5f437296a46a9fd69f86f943d0924fcbb033e576 Mon Sep 17 00:00:00 2001 From: boladjebsoft Date: Thu, 9 Apr 2026 19:34:15 +0100 Subject: [PATCH 15/15] udated the array input test --- Sprint-2/implement/contains.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 1548d3e8d..9acbfd464 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -45,8 +45,9 @@ test("given an object with properties, returns false when passed to contains wit // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +// "length" is perfect for the test because it's real property on the array itself test("given invalid parameters (array), returns false or throws an error", () => { - expect(contains(["gitName", "age", "position"], "cohort")).toEqual(false); + expect(contains(["gitName", "age", "position"], "length")).toBe(false); }); test("given invalid parameters (like null or undefined), returns false or throws an error", () => {