From ca796ca99970d998e576ea255876ccd73ad59f0a Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Sat, 5 Jul 2025 12:55:57 +0100 Subject: [PATCH 01/33] added comments for my prediction and given suggestion --- Sprint-2/debug/address.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..6ba6dfc13 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,4 +1,9 @@ // Predict and explain first... +// the code below has all the information for an address and is trying to log the house number to the console +// i expect it to log undefined or an error because the values in the object are not accessed correctly as its trying to use an index as if it is an array and not defined as a key in the object +// after running the code it came back as "my house number is `undefined`" +// i think using "address.houseNumber" or "address["houseNumber"] would work instead of "address[0]" + // This code should log out the houseNumber from the address object // but it isn't working... From 87aa2f848a1090c1c42c8f708d10d51d9a1dc28b Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Sat, 5 Jul 2025 13:08:24 +0100 Subject: [PATCH 02/33] Fix console log to correctly display house number from address object --- Sprint-2/debug/address.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 6ba6dfc13..5501c0088 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -17,4 +17,5 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +// console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address["houseNumber"]}`); // corrected to print the house number from the address object From b586c5d2a61dd64700eb769b30171019f2e705b2 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Sat, 5 Jul 2025 17:11:25 +0100 Subject: [PATCH 03/33] added comments predicting and expecting to happen and given reasons to why --- Sprint-2/debug/author.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..c29da781d 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,4 +1,10 @@ // Predict and explain first... +// i predict that the code is going to try to get the values from each of the keys in "author" and print them to the console +// i expect it to throw an error as its trying to loop for values of an array +// to fix this you would need to return an array from the values of author using "object.values()" so the "for...of" loops through each value in that array +// after running the code it gives a "TypeError: author is not iterable" +// this is because for...of only works on iterables like arrays, strings, maps, etc. but author is a plain object which is not iterable by default. + // 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 From 3d8c0e40ead383349656bff14cf2ecb034c2681f Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Sat, 5 Jul 2025 17:19:38 +0100 Subject: [PATCH 04/33] Fix error by using Object.values() in for...of loop --- Sprint-2/debug/author.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index c29da781d..0975b7ba7 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -17,6 +17,6 @@ const author = { alive: true, }; -for (const value of author) { +for (const value of Object.values(author)){ console.log(value); } From 0c740e30372aa976d457d89c0b51dbdd4d333302 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Sat, 5 Jul 2025 18:52:43 +0100 Subject: [PATCH 05/33] Add comments to explain expected behavior and necessary fixes for ingredient logging --- Sprint-2/debug/recipe.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..48849469e 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,8 +1,12 @@ // Predict and explain first... +// i expect the code to run but not produce the ingredients as its not calling the key pair values of ingredients array with the recipe.ingredients call +// i also expect that each part will not be produced on a new line when called as there is no new line breaks called with the \n after each property has been called in the console log // 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? +// to fix this you would need to change "${recipe}`" to "${recipe.ingredients}`" +// to fix each ingredient being called individually you'd use the array call on "recipe.ingredients[]\n" to call individual elements of the array and put them on a new line const recipe = { title: "bruschetta", From 996a55eb1705c3172df96907d6a8d7a843767ca0 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Sat, 5 Jul 2025 19:39:51 +0100 Subject: [PATCH 06/33] refactored code in console log to correctly call ingredients to the console on new lines --- Sprint-2/debug/recipe.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 48849469e..855db96c2 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -14,6 +14,4 @@ const recipe = { ingredients: ["olive oil", "tomatoes", "salt", "pepper"], }; -console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); +console.log(`${recipe.title}\n serves ${recipe.serves}\n ingredients:\n ${recipe.ingredients[0]}\n ${recipe.ingredients[1]}\n ${recipe.ingredients[2]}\n ${recipe.ingredients[3]}`); From cbcab13caf75cb9d2053f921d9c61e36afd6d9b3 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Wed, 9 Jul 2025 15:03:26 +0100 Subject: [PATCH 07/33] Refactor parseQueryString to handle values with "=" by splitting only the first occurrence and rejoining the rest --- Sprint-2/implement/querystring.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..1cd70a63c 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -6,7 +6,12 @@ function parseQueryString(queryString) { const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); + // split only the first "=" to handle cases where the value contains "=" + const [key, ...rest] = pair.split("="); + + // rejoin the rest incase there are "=" in the value + const value = rest.join("="); + queryParams[key] = value; } From 53b286fa17845f16e62dec9a73cc7f7f1e577f2a Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Wed, 9 Jul 2025 15:08:30 +0100 Subject: [PATCH 08/33] added tests to cover parses keys with multiple "=" signs --- Sprint-2/implement/querystring.test.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 3e218b789..df1dc325d 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -10,3 +10,9 @@ test("parses querystring values containing =", () => { "equation": "x=y+1", }); }); + +test("parses keys with multiple = signs in value", () => { + expect(parseQueryString("foo=bar=baz=qux")).toEqual({ + foo: "bar=baz=qux", + }); +}); From 88ad32f6dd059a2e294afc305c61ab3a92d049ec Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Wed, 9 Jul 2025 15:10:31 +0100 Subject: [PATCH 09/33] Add test for parsing querystring with no value --- Sprint-2/implement/querystring.test.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index df1dc325d..a99dad051 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -16,3 +16,9 @@ test("parses keys with multiple = signs in value", () => { foo: "bar=baz=qux", }); }); + +test("parses querystring with no value", () => { + expect(parseQueryString("keyOnly")).toEqual({ + "keyOnly": "", + }); +}); \ No newline at end of file From 60d9b7cf8f9cfff54997091f6a038521e08deb69 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Wed, 9 Jul 2025 16:54:52 +0100 Subject: [PATCH 10/33] added comments answering questions around the function invert --- Sprint-2/interpret/invert.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..c4a926e7b 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -6,7 +6,7 @@ // E.g. invert({x : 10, y : 20}), target output: {"10": "x", "20": "y"} -function invert(obj) { + function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { @@ -17,13 +17,19 @@ function invert(obj) { } // a) What is the current return value when invert is called with { a : 1 } +// answer: the current return value is {key : 1} because the key is not being set correctly // b) What is the current return value when invert is called with { a: 1, b: 2 } +// answer: the current return value is {key : 2} because the key is not being set correctly and it overwrites the previous key-value pair // c) What is the target return value when invert is called with {a : 1, b: 2} +// answer: the target return values should be {"1": "a", "2": "b"} because we want to swap the keys and values around in the object // c) What does Object.entries return? Why is it needed in this program? +// answer: Object.entries returns an array of key values pairs from the object to make it easier to iterate through object properties // d) Explain why the current return value is different from the target output +// answer: the current return value is different from the target output because the key is not being set correctly in the invertedObj instead of setting the value as the key it is setting the key as the value. // e) Fix the implementation of invert (and write tests to prove it's fixed!) +// answer: to fix this we have need to change the line "invertedObj.key = value;" to "invertedObj[value] = key;" so that the value is set as the key and the key is set to the value From 2307da8c0d8daee54193ee07aa8107accce63fc5 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Wed, 9 Jul 2025 16:55:54 +0100 Subject: [PATCH 11/33] Fix implementation of invert function to correctly swap keys and values --- Sprint-2/interpret/invert.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index c4a926e7b..3fb0ad23b 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -6,7 +6,7 @@ // E.g. invert({x : 10, y : 20}), target output: {"10": "x", "20": "y"} - function invert(obj) { +/* function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { @@ -15,6 +15,7 @@ return invertedObj; } +*/ // a) What is the current return value when invert is called with { a : 1 } // answer: the current return value is {key : 1} because the key is not being set correctly @@ -33,3 +34,13 @@ // e) Fix the implementation of invert (and write tests to prove it's fixed!) // answer: to fix this we have need to change the line "invertedObj.key = value;" to "invertedObj[value] = key;" so that the value is set as the key and the key is set to the value + +function invert(obj) { + const invertedObj = {}; + + for (const [key, value] of Object.entries(obj)) { + invertedObj[value] = key; + } + + return invertedObj; +} \ No newline at end of file From ac0ffda8ed6fd46e2b9e94a95f676465a7b42fbe Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Fri, 11 Jul 2025 12:30:25 +0100 Subject: [PATCH 12/33] implemented parameters to contains function and to check if obj is an object and not an array --- Sprint-2/implement/contains.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..b497e4d25 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,7 @@ -function contains() {} +function contains(obj, key) { + // check if "obj" is an object and not an array and we are working with plain objects + if (typeof obj !== object || Array.isArray(obj)) return false; + +} module.exports = contains; From 339ddd7ed7d90b0838776fc4741f95557b5ec587 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Fri, 11 Jul 2025 12:35:00 +0100 Subject: [PATCH 13/33] added jest test: for when an empty object is passed into contains function --- Sprint-2/implement/contains.test.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..4cfe03cf8 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -20,8 +20,9 @@ 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("when given an empty object returns false", () => { + expect(contains({}, "a")).toBe(false); +}); // Given an object with properties // When passed to contains with an existing property name // Then it should return true From b96968fc57a9dfda8781d10ef994d631a539661c Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Fri, 11 Jul 2025 12:50:49 +0100 Subject: [PATCH 14/33] Fix type check for object in contains function --- Sprint-2/implement/contains.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index b497e4d25..ef258fac8 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,7 +1,5 @@ function contains(obj, key) { // check if "obj" is an object and not an array and we are working with plain objects - if (typeof obj !== object || Array.isArray(obj)) return false; - + if (typeof obj !== "object" || Array.isArray(obj)) return false; } - module.exports = contains; From 228755f2497ba14c5c7174171475bfb3d1c6ba3b Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Fri, 11 Jul 2025 12:54:02 +0100 Subject: [PATCH 15/33] fix: add missing return false to handle cases where key is not found --- Sprint-2/implement/contains.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index ef258fac8..8a3069cef 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,5 +1,7 @@ function contains(obj, key) { // check if "obj" is an object and not an array and we are working with plain objects if (typeof obj !== "object" || Array.isArray(obj)) return false; + + return false; // if no object or key is found return false } module.exports = contains; From 370b07cc25f6b62323278b901d5d29e7dbe457f0 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Fri, 11 Jul 2025 13:09:08 +0100 Subject: [PATCH 16/33] implemented: loop through object keys using for...in and check for matching key inside loop and return true if matches during iteration --- Sprint-2/implement/contains.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 8a3069cef..4ad4fb89a 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -2,6 +2,13 @@ function contains(obj, key) { // check if "obj" is an object and not an array and we are working with plain objects if (typeof obj !== "object" || Array.isArray(obj)) return false; + // loop over each property name in the object + for (let properties in obj){ + + // check that if each of the properties names matches what were looking for in the key and return true if matches + if (properties === key) return true; + } + return false; // if no object or key is found return false } module.exports = contains; From 3b151310927b02d58c8b88746da433dceb5f4c0a Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Fri, 11 Jul 2025 13:09:32 +0100 Subject: [PATCH 17/33] added test case for contains function to verify it returns true for existing properties --- Sprint-2/implement/contains.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 4cfe03cf8..d42215360 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -26,6 +26,10 @@ test("when given an empty object returns false", () => { // Given an object with properties // When passed to contains with an existing property name // Then it should return true +test("when given an object with properties returns true", () => { + expect(contains({a: 1, b: 2}, "a")).toBe(true); + expect(contains({a: 2, b: 4, c: 5}, "c")).toBe(true); +}) // Given an object with properties // When passed to contains with a non-existent property name From b7b021502b985a25c0de98423cd8709852f4cb9b Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Fri, 11 Jul 2025 13:16:17 +0100 Subject: [PATCH 18/33] refactor: update test descriptions for clarity and consistency and added test for non existent properties --- Sprint-2/implement/contains.test.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index d42215360..9a40b2409 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -26,14 +26,17 @@ test("when given an empty object returns false", () => { // Given an object with properties // When passed to contains with an existing property name // Then it should return true -test("when given an object with properties returns true", () => { +test("when given an object with existing properties returns true", () => { expect(contains({a: 1, b: 2}, "a")).toBe(true); expect(contains({a: 2, b: 4, c: 5}, "c")).toBe(true); -}) +}); // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +test("when given an object with non existent properties returns false", () => { + expect(contains({a: 1, b: 2,}, "c")).toBe(false); +}); // Given invalid parameters like an array // When passed to contains From 8f6fe9718f1af6b11ebde79b2760efed422ebd7f Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Fri, 11 Jul 2025 13:26:16 +0100 Subject: [PATCH 19/33] added test case for when invalid parameters like an array --- Sprint-2/implement/contains.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 9a40b2409..92f827417 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -41,3 +41,6 @@ test("when given an object with non existent properties returns false", () => { // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +test("when given an invalid parameters like arrays returns false", () => { + expect(contains([1, 2, 3], 1)).toBe(false); +}); From 67429029a9f8b8ee57bc18ce83447a448a318e65 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Tue, 22 Jul 2025 15:02:38 +0100 Subject: [PATCH 20/33] initialize results object in createLookup function --- Sprint-2/implement/lookup.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..1e870c9ed 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,6 @@ function createLookup() { // implementation here + const results = {}; // create an empty object to be able to store results } module.exports = createLookup; From c3764f576d67bd897dab16deade8df61884a5477 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Tue, 22 Jul 2025 15:20:10 +0100 Subject: [PATCH 21/33] implemented parameter to createLookup function and correct result variable name --- Sprint-2/implement/lookup.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 1e870c9ed..ae087cdaf 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,6 +1,14 @@ -function createLookup() { +function createLookup(pairs) { // implementation here const results = {}; // create an empty object to be able to store results + + // loop through each of the pairs in the array + for (const [country, currency] of pairs){ + // add new key value pairs to the object "country" is the key and "currency" is the value + result[country] = currency; + } + + return result; // returns the final object that maps each key to the corresponding values } module.exports = createLookup; From 75253144b85ce525fbada1b304c42dc770a157d7 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Tue, 22 Jul 2025 15:44:23 +0100 Subject: [PATCH 22/33] fix: correct variable name from 'result' to 'results' in 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 ae087cdaf..2484d831c 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -5,10 +5,10 @@ function createLookup(pairs) { // loop through each of the pairs in the array for (const [country, currency] of pairs){ // add new key value pairs to the object "country" is the key and "currency" is the value - result[country] = currency; + results[country] = currency; } - return result; // returns the final object that maps each key to the corresponding values + return results; // returns the final object that maps each key to the corresponding values } module.exports = createLookup; From 84e85525e6e4f9a0abe687c11b1d67323132a779 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Tue, 22 Jul 2025 15:44:32 +0100 Subject: [PATCH 23/33] test: implement test for country currency code lookup functionality --- Sprint-2/implement/lookup.test.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..64e9ab9fa 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,7 +1,9 @@ const createLookup = require("./lookup.js"); -test.todo("creates a country currency code lookup for multiple codes"); - +test("creates a country currency code lookup for multiple codes", () => { + expect(createLookup([['US', 'USD'], ['CA', 'CAD'], ['GB', 'GBP']])) + .toEqual({ US: 'USD', CA: 'CAD', GB: 'GBP' }); +}); /* Create a lookup object of key value pairs from an array of code pairs From a11cbcdbf380b8c020b8c4a6931956ba304a55ca Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Tue, 22 Jul 2025 15:49:34 +0100 Subject: [PATCH 24/33] test: add test case for returning an empty object with an empty array --- Sprint-2/implement/lookup.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 64e9ab9fa..cdd814f96 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -4,6 +4,10 @@ test("creates a country currency code lookup for multiple codes", () => { expect(createLookup([['US', 'USD'], ['CA', 'CAD'], ['GB', 'GBP']])) .toEqual({ US: 'USD', CA: 'CAD', GB: 'GBP' }); }); + +test("returns an empty object when given an empty array", () => { + expect(createLookup([])).toEqual({}); +}); /* Create a lookup object of key value pairs from an array of code pairs From 9539ce3b10fbf4195bbd0feba209a6673ef4aa5d Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Thu, 24 Jul 2025 13:30:55 +0100 Subject: [PATCH 25/33] implement input validation for tally function to ensure array input --- Sprint-2/implement/tally.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..38fb482b9 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,9 @@ -function tally() {} +function tally(array) { + // ensures that the input is an array. + if (!Array.isArray(array)){ + // throw an error if input is not an array + throw new Error("expected input to be an array"); + } +} module.exports = tally; From a257896fb4271b8cfff6a202f4ac397d8dea5e44 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Thu, 24 Jul 2025 13:54:08 +0100 Subject: [PATCH 26/33] added a empty object to store counted items --- Sprint-2/implement/tally.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 38fb482b9..2e0b3007f 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -4,6 +4,11 @@ function tally(array) { // throw an error if input is not an array throw new Error("expected input to be an array"); } + + // make an empty object to store items counted + const itemCount = {}; + + return itemCount; } module.exports = tally; From 79afe87b17ee435a85cabf9729af016f5387ed0b Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Thu, 24 Jul 2025 13:55:15 +0100 Subject: [PATCH 27/33] implemented jest test for if function(Tally) is given an empty array --- Sprint-2/implement/tally.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..ff3674536 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -23,7 +23,9 @@ 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 From 0da94ce5369ed6cbf8c4c81c309236400f471cd1 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Thu, 24 Jul 2025 14:16:25 +0100 Subject: [PATCH 28/33] Add for...of loop to count how many times each item appears in array --- Sprint-2/implement/tally.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 2e0b3007f..76fbf2767 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -7,7 +7,13 @@ function tally(array) { // make an empty object to store items counted const itemCount = {}; - + + // loop over each item in the array + for (const item of array){ + // if the item hasn't been counted yet treat it as 0 + itemCount[item] = (itemCount[item] || 0) + 1; // then adds 1 to either start or increment the count for this item + } + return itemCount; } From 2a37e5ec7d7900d95674dad953a9b8bd1d41a42a Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Thu, 24 Jul 2025 14:23:52 +0100 Subject: [PATCH 29/33] added jest test for when a given array has duplicate items --- Sprint-2/implement/tally.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index ff3674536..1309a3e31 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -30,6 +30,9 @@ test("tally on an empty array returns an empty object", () => { // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item +test("counts duplicate items in an array", () => { + expect(tally(["a", "b", "a", "c"])).toEqual({a: 2, b: 1, c: 1}); +}); // Given an invalid input like a string // When passed to tally From 430f315da5f164e283eb9f8254b501f5a6756871 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Thu, 24 Jul 2025 14:26:28 +0100 Subject: [PATCH 30/33] added jest test for a given invalid input --- Sprint-2/implement/tally.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 1309a3e31..658e9cb5a 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -37,3 +37,6 @@ test("counts duplicate items in an array", () => { // Given an invalid input like a string // When passed to tally // Then it should throw an error +test("throws an error when an invalid input is given", () => { + expect(() => tally("not an array")).toThrow(Error); +}); \ No newline at end of file From 604453374d13de2c86d94bb24dc1274f2f0bd294 Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Sat, 29 Nov 2025 12:45:15 +0000 Subject: [PATCH 31/33] Fix: update console log to display ingredients on a single line using .join() instead of calling individually to work with any amount of ingredients --- Sprint-2/debug/recipe.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 855db96c2..b930ac142 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -14,4 +14,8 @@ const recipe = { ingredients: ["olive oil", "tomatoes", "salt", "pepper"], }; -console.log(`${recipe.title}\n serves ${recipe.serves}\n ingredients:\n ${recipe.ingredients[0]}\n ${recipe.ingredients[1]}\n ${recipe.ingredients[2]}\n ${recipe.ingredients[3]}`); +console.log( + `${recipe.title}\n serves ${ + recipe.serves + }\n ingredients:\n ${recipe.ingredients.join(", ")}` +); From 6f7ef9c882b31a17b7e06aafd19bb1c4a7bc17fa Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Sat, 29 Nov 2025 13:10:56 +0000 Subject: [PATCH 32/33] Refactor: improve readability of the contains function by adjusting indentation and formatting and handles null safety --- Sprint-2/implement/contains.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 4ad4fb89a..6de748b2d 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,14 +1,14 @@ function contains(obj, key) { - // check if "obj" is an object and not an array and we are working with plain objects - if (typeof obj !== "object" || Array.isArray(obj)) return false; + // check if "obj" is an object and not an array and we are working with plain objects + if (typeof obj !== "object" || obj === null || Array.isArray(obj)) + return false; - // loop over each property name in the object - for (let properties in obj){ + // loop over each property name in the object + for (let properties in obj) { + // check that if each of the properties names matches what were looking for in the key and return true if matches + if (properties === key) return true; + } - // check that if each of the properties names matches what were looking for in the key and return true if matches - if (properties === key) return true; - } - - return false; // if no object or key is found return false + return false; // if no object or key is found return false } module.exports = contains; From 4141123a771de16a9f24da21b7abc6fe2714f8cf Mon Sep 17 00:00:00 2001 From: Declan Williams Date: Sat, 29 Nov 2025 15:14:20 +0000 Subject: [PATCH 33/33] Refactor: change itemCount initialization to use Object.create(null) for a cleaner object creation --- Sprint-2/implement/tally.js | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 76fbf2767..86fe32d92 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,20 +1,21 @@ function tally(array) { - // ensures that the input is an array. - if (!Array.isArray(array)){ - // throw an error if input is not an array - throw new Error("expected input to be an array"); - } + // ensures that the input is an array. + if (!Array.isArray(array)) { + // throw an error if input is not an array + throw new Error("expected input to be an array"); + } - // make an empty object to store items counted - const itemCount = {}; + // make an empty object to store items counted + const itemCount = Object.create(null); - // loop over each item in the array - for (const item of array){ - // if the item hasn't been counted yet treat it as 0 - itemCount[item] = (itemCount[item] || 0) + 1; // then adds 1 to either start or increment the count for this item - } + // loop over each item in the array + for (const item of array) { + // if the item hasn't been counted yet treat it as 0 + itemCount[item] = (itemCount[item] || 0) + 1; // then adds 1 to either start or increment the count for this item + } - return itemCount; + return itemCount; } +console.log(tally(["toString", "toString"])); module.exports = tally;