From 853119144b6ce03cda9180d081667e109fd1bd52 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Thu, 5 Nov 2026 23:12:38 +0000 Subject: [PATCH 01/43] object prep --- Sprint-2/prep/ordered-data.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Sprint-2/prep/ordered-data.js diff --git a/Sprint-2/prep/ordered-data.js b/Sprint-2/prep/ordered-data.js new file mode 100644 index 000000000..016c7f9b2 --- /dev/null +++ b/Sprint-2/prep/ordered-data.js @@ -0,0 +1,18 @@ +// const profileData = { +// firstName: "Franceso", +// lastName: "Leoni", +// age: 33, +// } + +// // console.log(profileData.cityOfResidence); +// profileData.cityOfResidence = "Manchester" +// console.log(profileData.cityOfResidence); + +const object1 = { + firstName: "Franceso", + lastName: "Leoni", +} + +const object2 = {}; +object2.firstName = "Franceso"; +object2.lastName = "Leoni"; \ No newline at end of file From 037311d0c016c150cf007b0fdedcba6be22cb1e9 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 10:30:05 +0000 Subject: [PATCH 02/43] fix houseNumber error --- Sprint-2/debug/address.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..45fea9ae2 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,8 +1,8 @@ // Predict and explain first... -// This code should log out the houseNumber from the address object -// but it isn't working... -// Fix anything that isn't working +// Answer: +// The address in the code is an object not an array, +// it wont log out because we try to use the array syntax instead of the object syntax const address = { houseNumber: 42, @@ -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 13f83e151fc7bc46e85cc05ff3a14a5e70d04d6b Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 10:46:02 +0000 Subject: [PATCH 03/43] fix author object iteration --- Sprint-2/debug/author.js | 6 +++--- Sprint-2/prep/parse-query-string.js | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 Sprint-2/prep/parse-query-string.js diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..31c5eb0d1 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,7 +1,7 @@ // Predict and explain first... -// 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 +// Answer: +// A plain object is not iterable, so 'for...of cannot loop over author directly const author = { firstName: "Zadie", @@ -11,6 +11,6 @@ const author = { alive: true, }; -for (const value of author) { +for (const value of Object.values(author)) { console.log(value); } diff --git a/Sprint-2/prep/parse-query-string.js b/Sprint-2/prep/parse-query-string.js new file mode 100644 index 000000000..41c0b1f8b --- /dev/null +++ b/Sprint-2/prep/parse-query-string.js @@ -0,0 +1,15 @@ +function parseQueryString(queryString) { + const queryParams = {}; + if (queryString.length === 0) { + return queryParams; + } + const keyValuePairs = queryString.split("&"); + + for (const pair of keyValuePairs) { + const [key, value] = pair.split("="); + queryParams[key] = value; + } + + return queryParams; +} +module.exports = parseQueryString; From 3d72ba18db43cb679aa9f9027b6684a7502b1c36 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 10:46:48 +0000 Subject: [PATCH 04/43] add tests for parseQueryString function to validate query string parsing --- Sprint-2/prep/parse-query-string.test.js | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Sprint-2/prep/parse-query-string.test.js diff --git a/Sprint-2/prep/parse-query-string.test.js b/Sprint-2/prep/parse-query-string.test.js new file mode 100644 index 000000000..639d4baa5 --- /dev/null +++ b/Sprint-2/prep/parse-query-string.test.js @@ -0,0 +1,27 @@ +const parseQueryString = require("./parse-query-string.js"); + +test("given a query string with no query parameter, return an empty object", () => { + const input = ""; + const currentOutput = parseQueryString(input); + const targetOutput = {}; + + expect(currentOutput).toEqual(targetOutput); +}); + +test("given a query string with one pair of query params, return them in object form", function () { + const input = "fruit=banana"; + const currentOutput = parseQueryString(input); + const targetOutput = { fruit: "banana"}; + + expect(currentOutput).toEqual(targetOutput); + +}); + +test("given a query string with multiple key-value pairs, returns them in object form", function () { + const input = "sort=lowest&colour=yellow"; + const currentOutput = parseQueryString(input); + const targetOutput = { sort: "lowest", colour: "yellow" }; + + expect(currentOutput).toEqual(targetOutput); +}); + From 454659b0af0000b6c4f0e809ec97d6cbe3d29284 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 10:46:56 +0000 Subject: [PATCH 05/43] add function to double all numbers in an array --- prep/doubleAllNumbers.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 prep/doubleAllNumbers.js diff --git a/prep/doubleAllNumbers.js b/prep/doubleAllNumbers.js new file mode 100644 index 000000000..58045564e --- /dev/null +++ b/prep/doubleAllNumbers.js @@ -0,0 +1,13 @@ +function doubleAllNumbers() { + let doubledNumbers; + + for (let n of numbers) { + doubledNumbers.push(n * 2); + } + + return doubledNumbers; +} + +const myNums = [10, 20, 30]; +doubleAllNumbers(myNums); +console.log(myNums); From af702ab01d350e9c9d4d647f35a52085abe907db Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 10:47:22 +0000 Subject: [PATCH 06/43] fix formatting in address.js comments for clarity --- 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 45fea9ae2..fbd2f3a7f 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,7 +1,7 @@ // Predict and explain first... -// Answer: -// The address in the code is an object not an array, +// Answer: +// The address in the code is an object not an array, // it wont log out because we try to use the array syntax instead of the object syntax const address = { From e6ed80a1a273f6c3c5054ecc7b358d4f14db8b10 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 10:58:55 +0000 Subject: [PATCH 07/43] fix recipe logging to display ingredients correctly --- Sprint-2/debug/recipe.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..1775f131d 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -12,4 +12,5 @@ const recipe = { console.log(`${recipe.title} serves ${recipe.serves} ingredients: -${recipe}`); +${recipe.ingredients.join("\n")}`); + From e80fd6fad4bde6d4ccf92eb5981924024c068743 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 11:02:56 +0000 Subject: [PATCH 08/43] fix comments in recipe.js to clarify logging functionality --- Sprint-2/debug/recipe.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 1775f131d..f4f6f24ce 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,8 +1,7 @@ // Predict and explain first... -// 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? +// The program won't print the ingredients because it wasn't called on line 14 + const recipe = { title: "bruschetta", From 74c65b797d7c75d5761d09f72fbd31ab835b30c7 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 11:34:22 +0000 Subject: [PATCH 09/43] implement test for contains function to check empty object case --- Sprint-2/implement/contains.test.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 719272787..e997cd424 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -23,7 +23,10 @@ as an array isn't an object // Given an empty object // When passed to contains // Then it should return false -test.todo("contains on empty object returns false"); +test("contains on empty object returns false", () => { + expect(contains({}, "a")).toBe(false) +}); + // Given an object with properties // When passed to contains with an existing property name From c61f58edbd05fbc56c760475a1259219ba575bd8 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 11:46:29 +0000 Subject: [PATCH 10/43] implement contains function to check if property exists in object --- Sprint-2/implement/contains.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..fcc208518 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,5 @@ -function contains() {} +function contains(object, property) { + return property in object; +} module.exports = contains; From 438293bebcc3ab84fd749e4fedbf3491963588fb Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 11:46:35 +0000 Subject: [PATCH 11/43] refactor contains.test.js to improve test structure and formatting --- Sprint-2/implement/contains.test.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index e997cd424..d15cfe216 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -24,9 +24,12 @@ as an array isn't an object // When passed to contains // Then it should return false test("contains on empty object returns false", () => { - expect(contains({}, "a")).toBe(false) + expect(contains({}, "a")).toBe(false); }); +test("contains an object with existing property, return true", () => { + expect(contains({ a: 1, b: 2 }, "a")).toBe(true); +}); // Given an object with properties // When passed to contains with an existing property name From 4e217bc765f4c64702a5fa2bf36e6404f8210a20 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 11:50:40 +0000 Subject: [PATCH 12/43] add test for contains function to verify behavior with missing property --- 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 d15cfe216..0d57fb0d3 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -31,6 +31,10 @@ test("contains an object with existing property, return true", () => { expect(contains({ a: 1, b: 2 }, "a")).toBe(true); }); +test("contains an object with missing property, return false", () => { + expect(contains({ a: 1, b: 2 }, "c")).toBe(false); +}); + // Given an object with properties // When passed to contains with an existing property name // Then it should return true From b72528b703aff97c6f0f7bfb6deaf69987d611b2 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 12:10:11 +0000 Subject: [PATCH 13/43] add test to ensure contains function throws error for array input --- 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 0d57fb0d3..213034380 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -35,6 +35,9 @@ test("contains an object with missing property, return false", () => { expect(contains({ a: 1, b: 2 }, "c")).toBe(false); }); +test("contains throws for an array", () => { + expect(() => contains([1, 2, 3], "a")).toThrow("contains requires an object"); +}); // Given an object with properties // When passed to contains with an existing property name // Then it should return true From e8cf923e1682b207d4c47420bc181efbf9c67f05 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 12:15:05 +0000 Subject: [PATCH 14/43] refactor contains function to validate input type before checking property existence --- 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 fcc208518..0b4758042 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,5 +1,8 @@ function contains(object, property) { - return property in object; + if (typeof object !== "object" || object === null || Array.isArray(object)) { + throw new Error("contains requires an object"); + } + return property in object; } module.exports = contains; From 8e89f1d80c87b5ecd1904832bb35d10c41f84997 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 12:16:04 +0000 Subject: [PATCH 15/43] remove redundant comments and acceptance criteria from contains.test.js --- Sprint-2/implement/contains.test.js | 36 ----------------------------- 1 file changed, 36 deletions(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 213034380..72c19df6c 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -1,28 +1,5 @@ const contains = require("./contains.js"); -/* -Implement a function called contains that checks an object contains a -particular property - -E.g. contains({a: 1, b: 2}, 'a') // returns true -as the object contains a key of 'a' - -E.g. contains({a: 1, b: 2}, 'c') // returns false -as the object doesn't contains a key of 'c' - -E.g. contains([1, 2, 3], 'a') throws Error("contains requires an object") -as an array isn't an object -*/ - -// Acceptance criteria: - -// Given a contains function -// When passed an object and a property name -// Then it should return true if the object contains the property, false otherwise - -// Given an empty object -// When passed to contains -// Then it should return false test("contains on empty object returns false", () => { expect(contains({}, "a")).toBe(false); }); @@ -38,16 +15,3 @@ test("contains an object with missing property, return false", () => { test("contains throws for an array", () => { expect(() => contains([1, 2, 3], "a")).toThrow("contains requires an object"); }); -// Given an object with properties -// When passed to contains with an existing property name -// Then it should return true - -// Given an object with properties -// When passed to contains with a non-existent property name -// Then it should return false - -// Given a value that isn't an object - an array, a string, a number, -// null, or no argument at all -// When passed to contains -// Then it should throw Error("contains requires an object") -// (careful: typeof [] and typeof null are both "object") From c39280d895647ffec1e38c59cdd2f6861b8e2c46 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 12:36:12 +0000 Subject: [PATCH 16/43] implement test for createLookup function to validate country-currency pairs --- Sprint-2/implement/lookup.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..2c37940ed 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,6 +1,8 @@ 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"]])).toEqual() +}); /* From 80034abc956fe68f8b33e0ceb136a019c21c3b65 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 12:43:48 +0000 Subject: [PATCH 17/43] fix: update test to validate correct output for createLookup function --- Sprint-2/implement/lookup.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 2c37940ed..196b5b8f5 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,7 +1,7 @@ const createLookup = require("./lookup.js"); test("creates a country currency code lookup for multiple codes", () => { - expect(createLookup([["US", "USD"], ["CA", "CAD"]])).toEqual() + expect(createLookup([["US", "USD"], ["CA", "CAD"]])).toEqual({US: "USD", CA: "CAD"}) }); /* From 8c1878d5e4d96193c053504de77458bc0ae4d005 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 12:43:54 +0000 Subject: [PATCH 18/43] implement createLookup function to map country-currency pairs --- Sprint-2/implement/lookup.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..cdd6788c0 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,9 @@ -function createLookup() { - // implementation here +function createLookup(countryCurrencyPairs) { + const lookup = {}; + for (const [country, currency] of countryCurrencyPairs) { + lookup[country] = currency; + } + return lookup } module.exports = createLookup; From 62d2398f3ad5e1409c009440bc0286380b33e156 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 12:47:47 +0000 Subject: [PATCH 19/43] refactor: improve formatting of createLookup test and remove redundant comments --- Sprint-2/implement/lookup.test.js | 39 +++++-------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 196b5b8f5..342c7d398 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,37 +1,10 @@ const createLookup = require("./lookup.js"); test("creates a country currency code lookup for multiple codes", () => { - expect(createLookup([["US", "USD"], ["CA", "CAD"]])).toEqual({US: "USD", CA: "CAD"}) + expect( + createLookup([ + ["US", "USD"], + ["CA", "CAD"], + ]) + ).toEqual({ US: "USD", CA: "CAD" }); }); - -/* - -Create a lookup object of key value pairs from an array of code pairs - -Acceptance Criteria: - -Given - - An array of arrays representing country code and currency code pairs - e.g. [['US', 'USD'], ['CA', 'CAD']] - -When - - createLookup function is called with the country-currency array as an argument - -Then - - It should return an object where: - - The keys are the country codes - - The values are the corresponding currency codes - -Example -Given: [['US', 'USD'], ['CA', 'CAD']] - -When -createLookup(countryCurrencyPairs) is called - -Then -It should return: - { - 'US': 'USD', - 'CA': 'CAD' - } -*/ From b1fdc4db2eba7111044139fb4620559ecac150e8 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 14:36:18 +0000 Subject: [PATCH 20/43] refactor: simplify parseQueryString function by removing redundant checks and comments --- Sprint-2/implement/querystring.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..efae7b914 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,14 +1,21 @@ function parseQueryString(queryString) { const queryParams = {}; - if (queryString.length === 0) { - return queryParams; - } - const keyValuePairs = queryString.split("&"); - for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); + for (const pair of queryString.split("&")) { + const eq = pair.indexOf("="); + const key = eq === -1 ? pair : pair.slice(0, eq); + const value = eq === -1 ? undefined : pair.slice(eq + 1); queryParams[key] = value; } + // if (queryString.length === 0) { + // return queryParams; + // } + // const keyValuePairs = queryString.split("&"); + + // for (const pair of keyValuePairs) { + // const [key, value] = pair.split("="); + // queryParams[key] = value; + // } return queryParams; } From 05ccd8ccaac58f6882015e4930ef83872fe6ffd7 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 14:41:38 +0000 Subject: [PATCH 21/43] refactor: clean up parseQueryString function by removing unnecessary comments and whitespace --- Sprint-2/implement/querystring.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index efae7b914..3bb581195 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -2,11 +2,19 @@ function parseQueryString(queryString) { const queryParams = {}; for (const pair of queryString.split("&")) { + if (pair === "") continue; + const eq = pair.indexOf("="); const key = eq === -1 ? pair : pair.slice(0, eq); const value = eq === -1 ? undefined : pair.slice(eq + 1); queryParams[key] = value; } + + + + + + // if (queryString.length === 0) { // return queryParams; // } From fe222e0b6b64314859923c9fb003a43f486fa4c3 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 14:46:06 +0000 Subject: [PATCH 22/43] fix: correct value assignment in parseQueryString and decode URI components --- Sprint-2/implement/querystring.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 3bb581195..77d00fe09 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -3,11 +3,14 @@ function parseQueryString(queryString) { for (const pair of queryString.split("&")) { if (pair === "") continue; - + const eq = pair.indexOf("="); const key = eq === -1 ? pair : pair.slice(0, eq); - const value = eq === -1 ? undefined : pair.slice(eq + 1); + const value = eq === -1 ? "" : pair.slice(eq + 1); queryParams[key] = value; + + const key = decodeURIComponent(eq === -1 ? : pair.slice(0, eq)); + const value = eq === -1 ? "" : decodeURIComponent(pair.slice(eq + 1)); } From 89d8fda6f633981eafc818767823be6e7bb2a491 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 14:48:23 +0000 Subject: [PATCH 23/43] fix: decode URI components in parseQueryString function --- Sprint-2/implement/querystring.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 77d00fe09..a8b0a49f8 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -8,16 +8,8 @@ function parseQueryString(queryString) { const key = eq === -1 ? pair : pair.slice(0, eq); const value = eq === -1 ? "" : pair.slice(eq + 1); queryParams[key] = value; - - const key = decodeURIComponent(eq === -1 ? : pair.slice(0, eq)); - const value = eq === -1 ? "" : decodeURIComponent(pair.slice(eq + 1)); } - - - - - // if (queryString.length === 0) { // return queryParams; // } From 17adfe97f6931bffcd8382fe2daf9804a7b2649e Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 14:56:20 +0000 Subject: [PATCH 24/43] fix: decode URI components in parseQueryString function --- Sprint-2/implement/querystring.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index a8b0a49f8..201bf8849 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -7,7 +7,11 @@ function parseQueryString(queryString) { const eq = pair.indexOf("="); const key = eq === -1 ? pair : pair.slice(0, eq); const value = eq === -1 ? "" : pair.slice(eq + 1); - queryParams[key] = value; + + const k = decodeURIComponent(key.replace(/+/g, "")); + const v = decodeURIComponent(value.replace(/+/g, "")); + + } // if (queryString.length === 0) { From 4918e8517630e5afca4ce4e39cf6b25e5f58a2ea Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 15:23:05 +0000 Subject: [PATCH 25/43] refactor: improve key and value decoding in parseQueryString function --- Sprint-2/implement/querystring.js | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 201bf8849..cb391d9e1 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -7,23 +7,20 @@ function parseQueryString(queryString) { const eq = pair.indexOf("="); const key = eq === -1 ? pair : pair.slice(0, eq); const value = eq === -1 ? "" : pair.slice(eq + 1); - - const k = decodeURIComponent(key.replace(/+/g, "")); - const v = decodeURIComponent(value.replace(/+/g, "")); - - } - - // if (queryString.length === 0) { - // return queryParams; - // } - // const keyValuePairs = queryString.split("&"); - - // for (const pair of keyValuePairs) { - // const [key, value] = pair.split("="); - // queryParams[key] = value; - // } + const k = decodeURIComponent(key.split("+").join(" ")); + const v = decodeURIComponent(value.split("+").join(" ")); + if (k in queryParams) { + if (Array.isArray(queryParams[k])) { + queryParams[k].push(v); + } else { + queryParams[k] = [queryParams[k], v]; + } + } else { + queryParams[k] = v; + } + } return queryParams; } From f57327351f4e33ac4357987594218dbd41c64dac Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 15:27:34 +0000 Subject: [PATCH 26/43] test: add test for handling empty query string --- Sprint-2/implement/querystring.test.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 328b8df61..1b0bfca2e 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -37,12 +37,13 @@ test("should replace '+' by ' '", () => { }); }); -// Stretch exercise: Handling query strings that contain identical keys - -// Delete this test if you are not working on this optional case test("should store values of a key in an array when the key has 2 or more values", () => { expect(parseQueryString("key=value1&key=value2&key=value3&foo=bar")).toEqual({ key: ["value1", "value2", "value3"], foo: "bar", }); }); + +test("returns an empty query string", () => { + expect(parseQueryString("")).toEqual({}); +}); From 05ee028da0db7d43856f6ff3ef301ff410b8635e Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 15:30:16 +0000 Subject: [PATCH 27/43] test: add test for handling values with both + and percent-encoding --- Sprint-2/implement/querystring.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 1b0bfca2e..1ffb17a7f 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -47,3 +47,7 @@ test("should store values of a key in an array when the key has 2 or more values test("returns an empty query string", () => { expect(parseQueryString("")).toEqual({}); }); + +test("handles a value with both + and percent-encoding", () => { + expect(parseQueryString("q=a+b%26c")).toEqual({q: "a b&c"}); +}); \ No newline at end of file From 15fe8297ae109c1c1eedc1086da4916e666ca4ad Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 15:32:17 +0000 Subject: [PATCH 28/43] test: implement test for tally function with an empty array --- Sprint-2/implement/tally.test.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index ca763c296..3f143e585 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -23,7 +23,10 @@ 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 8eb4f2df10de0ee40983c4d38e24cc33484bf723 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 15:34:15 +0000 Subject: [PATCH 29/43] test: fix indentation in tally test cases --- Sprint-2/implement/tally.test.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 3f143e585..01cf1a72b 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -24,9 +24,12 @@ const tally = require("./tally.js"); // When passed to tally // Then it should return an empty object test("tally on an empty array returns an empty object", () => { - expect(tally([])).toEqual({}); + expect(tally([])).toEqual({}); }); +test("tally counts duplicate items", () => { + expect(tally(["a", "a", "a"])).toEqual({ a: 3 }); +}); // Given an array with duplicate items // When passed to tally From 967cdf663df2a238d8f71c1ae9cad3ad8835de43 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 15:35:57 +0000 Subject: [PATCH 30/43] test: add assertion for counting unique items in tally function --- Sprint-2/implement/tally.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 01cf1a72b..aba0c7fd0 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -29,6 +29,7 @@ test("tally on an empty array returns an empty object", () => { test("tally counts duplicate items", () => { expect(tally(["a", "a", "a"])).toEqual({ a: 3 }); + expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 1 }); }); // Given an array with duplicate items From 1492450412abd3a30a9c73a8614fe43974e0dc48 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 15:39:49 +0000 Subject: [PATCH 31/43] test: add tests for handling invalid input in tally function --- Sprint-2/implement/tally.test.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index aba0c7fd0..47fa848d4 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -32,6 +32,12 @@ test("tally counts duplicate items", () => { expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 1 }); }); +test("tally throws for invalid input", () => { + expect(() => tally("banana")).toThrow("tally requires an array"); + expect(() => tally(42)).toThrow("tally requires an array"); + expect(() => tally()).toThrow("tally requires an array"); +}); + // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item From d2fb2602858de70184a0ef554db4484e6e130b35 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 15:40:17 +0000 Subject: [PATCH 32/43] refactor: remove unnecessary comments and documentation from tally test file --- Sprint-2/implement/tally.test.js | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 47fa848d4..c3b2efd54 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -1,28 +1,6 @@ const tally = require("./tally.js"); -/** - * tally array - * - * In this task, you'll need to implement a function called tally - * that will take a list of items and count the frequency of each item - * in an array - * - * For example: - * - * tally(['a']), target output: { a: 1 } - * tally(['a', 'a', 'a']), target output: { a: 3 } - * tally(['a', 'a', 'b', 'c']), target output: { a : 2, b: 1, c: 1 } - */ -// Acceptance criteria: - -// Given a function called tally -// When passed an array of items -// Then it should return an object containing the count for each unique item - -// Given an empty array -// When passed to tally -// Then it should return an empty object test("tally on an empty array returns an empty object", () => { expect(tally([])).toEqual({}); }); @@ -37,11 +15,3 @@ test("tally throws for invalid input", () => { expect(() => tally(42)).toThrow("tally requires an array"); expect(() => tally()).toThrow("tally requires an array"); }); - -// Given an array with duplicate items -// When passed to tally -// Then it should return counts for each unique item - -// Given an invalid input like a string, a number, or no argument at all -// When passed to tally -// Then it should throw Error("tally requires an array") From 77dc8de87ad725a9c2eceee951f857288bad87c4 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 15:48:11 +0000 Subject: [PATCH 33/43] feat: implement tally function to count occurrences in an array --- Sprint-2/implement/tally.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..1e0a1fee6 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,14 @@ -function tally() {} +function tally(list) { + if (Array.isArray(list)) { + throw new Error("tally requires an array"); + } + + const counts = {}; + + for (const item of list) { + counts[item] = (counts[item] || 0) + 1; + } + return counts; +} module.exports = tally; From 5cb05eeaa896751b17bba48c0dba3b6e28c9756d Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 15:49:38 +0000 Subject: [PATCH 34/43] fix: correct condition to check if input is an array in tally function --- Sprint-2/implement/tally.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 1e0a1fee6..380da62f5 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,5 +1,5 @@ function tally(list) { - if (Array.isArray(list)) { + if (!Array.isArray(list)) { throw new Error("tally requires an array"); } From ef80285df3e2f027ec782ae685c976224d94505d Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 20:51:28 +0000 Subject: [PATCH 35/43] fix: correct implementation of invert function to properly swap keys and values --- Sprint-2/interpret/invert.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..782c12f53 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,7 +10,7 @@ function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; + invertedObj[value] = key; } return invertedObj; From d2795ffc27c1dffb0d10c93ffb15a5511bcb6dd8 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 20:56:57 +0000 Subject: [PATCH 36/43] fix: update module export for invert function --- Sprint-2/interpret/invert.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index 782c12f53..1c06bfd8b 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -16,7 +16,10 @@ function invert(obj) { return invertedObj; } +module.exports = invert; + // a) What is the current return value when invert is called with { a : 1 } +// Answer: {key: 1} // b) What is the current return value when invert is called with { a: 1, b: 2 } From 6eff4d90a25fda39f9f4e0a3477f633000740aab Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 21:11:50 +0000 Subject: [PATCH 37/43] fix: update comments in invert function to clarify expected behavior and return values --- Sprint-2/interpret/invert.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index 1c06bfd8b..62616fc6d 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -19,14 +19,26 @@ function invert(obj) { module.exports = invert; // a) What is the current return value when invert is called with { a : 1 } + // Answer: {key: 1} // b) What is the current return value when invert is called with { a: 1, b: 2 } +// Answer: {key: 2} + // c) What is the target return value when invert is called with {a : 1, b: 2} +// Answer: target is {"1": "a", "2": "b"} + // c) What does Object.entries return? Why is it needed in this program? +// Answer: Object.entries returns an array of [key, value] pairs, like [["a", 1]], ["b", 2], so the loop can grab both at once + // d) Explain why the current return value is different from the target output +// Answer: invertedObj.key = value writes a property literally named "key" on - +// every pass, so each pairs overwrites the same one and only the last value survives + // e) Fix the implementation of invert (and write tests to prove it's fixed!) + +// Answer: use brackets so the value becomes the new key: invertedObj[value] = key \ No newline at end of file From ad4efb5f22328a68831f80c526c95459069c686f Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 21:22:44 +0000 Subject: [PATCH 38/43] test: add unit test for invert function to verify key-value swapping --- Sprint-2/interpret/invert.test.js | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Sprint-2/interpret/invert.test.js diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js new file mode 100644 index 000000000..6f0b2d9de --- /dev/null +++ b/Sprint-2/interpret/invert.test.js @@ -0,0 +1,5 @@ +const invert = require("./invert.js"); + +test("swaps key with values", () => { + expect(invert({x: 1})).toEqual(({"10": "x", "20": "y"})); +}); \ No newline at end of file From e18c645d7e850d0702253cd618b1b82f45524e84 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 21:25:09 +0000 Subject: [PATCH 39/43] fix: add missing newline and correct syntax in invert test cases --- Sprint-2/interpret/invert.test.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js index 6f0b2d9de..8f2c57adb 100644 --- a/Sprint-2/interpret/invert.test.js +++ b/Sprint-2/interpret/invert.test.js @@ -2,4 +2,8 @@ const invert = require("./invert.js"); test("swaps key with values", () => { expect(invert({x: 1})).toEqual(({"10": "x", "20": "y"})); -}); \ No newline at end of file +}); + +test("handles single entry", () => { + expect(invert({a: 1})).toEqual({"1": "a"}); +}): \ No newline at end of file From 3deb65ce758d1aabb87f8a292eb7a01ca2b36c6a Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 21:25:27 +0000 Subject: [PATCH 40/43] fix: correct formatting and add missing newline in invert test cases --- Sprint-2/interpret/invert.test.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js index 8f2c57adb..7618c6907 100644 --- a/Sprint-2/interpret/invert.test.js +++ b/Sprint-2/interpret/invert.test.js @@ -1,9 +1,10 @@ const invert = require("./invert.js"); test("swaps key with values", () => { - expect(invert({x: 1})).toEqual(({"10": "x", "20": "y"})); + expect(invert({ x: 1 })).toEqual({ 10: "x", 20: "y" }); }); test("handles single entry", () => { - expect(invert({a: 1})).toEqual({"1": "a"}); -}): \ No newline at end of file + expect(invert({ a: 1 })).toEqual({ 1: "a" }); +}); + From 8ad64941925f07791f43c55102a1619bad987085 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 21:27:53 +0000 Subject: [PATCH 41/43] test: add unit test for handling empty object in invert function --- Sprint-2/interpret/invert.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js index 7618c6907..b2a310d72 100644 --- a/Sprint-2/interpret/invert.test.js +++ b/Sprint-2/interpret/invert.test.js @@ -8,3 +8,6 @@ test("handles single entry", () => { expect(invert({ a: 1 })).toEqual({ 1: "a" }); }); +test("handles an empty object", () => { + expect(invert({})).toEqual({}); +}); From 4476d4a6d123deae8658a79b8a577e1f995138b5 Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 21:31:50 +0000 Subject: [PATCH 42/43] fix: correct expected output for key-value swapping test case --- Sprint-2/interpret/invert.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js index b2a310d72..8228996f0 100644 --- a/Sprint-2/interpret/invert.test.js +++ b/Sprint-2/interpret/invert.test.js @@ -1,7 +1,7 @@ const invert = require("./invert.js"); test("swaps key with values", () => { - expect(invert({ x: 1 })).toEqual({ 10: "x", 20: "y" }); + expect(invert({ x: 10, y: 20 })).toEqual({ 10: "x", 20: "y" }); }); test("handles single entry", () => { From 5ab6b3e85504d9f0d7741be24a18b601644a9c2a Mon Sep 17 00:00:00 2001 From: MattCarolus10 Date: Fri, 6 Nov 2026 21:59:50 +0000 Subject: [PATCH 43/43] Remove prep files from sprint branch --- Sprint-2/prep/ordered-data.js | 18 ---------------- Sprint-2/prep/parse-query-string.js | 15 ------------- Sprint-2/prep/parse-query-string.test.js | 27 ------------------------ prep/doubleAllNumbers.js | 13 ------------ 4 files changed, 73 deletions(-) delete mode 100644 Sprint-2/prep/ordered-data.js delete mode 100644 Sprint-2/prep/parse-query-string.js delete mode 100644 Sprint-2/prep/parse-query-string.test.js delete mode 100644 prep/doubleAllNumbers.js diff --git a/Sprint-2/prep/ordered-data.js b/Sprint-2/prep/ordered-data.js deleted file mode 100644 index 016c7f9b2..000000000 --- a/Sprint-2/prep/ordered-data.js +++ /dev/null @@ -1,18 +0,0 @@ -// const profileData = { -// firstName: "Franceso", -// lastName: "Leoni", -// age: 33, -// } - -// // console.log(profileData.cityOfResidence); -// profileData.cityOfResidence = "Manchester" -// console.log(profileData.cityOfResidence); - -const object1 = { - firstName: "Franceso", - lastName: "Leoni", -} - -const object2 = {}; -object2.firstName = "Franceso"; -object2.lastName = "Leoni"; \ No newline at end of file diff --git a/Sprint-2/prep/parse-query-string.js b/Sprint-2/prep/parse-query-string.js deleted file mode 100644 index 41c0b1f8b..000000000 --- a/Sprint-2/prep/parse-query-string.js +++ /dev/null @@ -1,15 +0,0 @@ -function parseQueryString(queryString) { - const queryParams = {}; - if (queryString.length === 0) { - return queryParams; - } - const keyValuePairs = queryString.split("&"); - - for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); - queryParams[key] = value; - } - - return queryParams; -} -module.exports = parseQueryString; diff --git a/Sprint-2/prep/parse-query-string.test.js b/Sprint-2/prep/parse-query-string.test.js deleted file mode 100644 index 639d4baa5..000000000 --- a/Sprint-2/prep/parse-query-string.test.js +++ /dev/null @@ -1,27 +0,0 @@ -const parseQueryString = require("./parse-query-string.js"); - -test("given a query string with no query parameter, return an empty object", () => { - const input = ""; - const currentOutput = parseQueryString(input); - const targetOutput = {}; - - expect(currentOutput).toEqual(targetOutput); -}); - -test("given a query string with one pair of query params, return them in object form", function () { - const input = "fruit=banana"; - const currentOutput = parseQueryString(input); - const targetOutput = { fruit: "banana"}; - - expect(currentOutput).toEqual(targetOutput); - -}); - -test("given a query string with multiple key-value pairs, returns them in object form", function () { - const input = "sort=lowest&colour=yellow"; - const currentOutput = parseQueryString(input); - const targetOutput = { sort: "lowest", colour: "yellow" }; - - expect(currentOutput).toEqual(targetOutput); -}); - diff --git a/prep/doubleAllNumbers.js b/prep/doubleAllNumbers.js deleted file mode 100644 index 58045564e..000000000 --- a/prep/doubleAllNumbers.js +++ /dev/null @@ -1,13 +0,0 @@ -function doubleAllNumbers() { - let doubledNumbers; - - for (let n of numbers) { - doubledNumbers.push(n * 2); - } - - return doubledNumbers; -} - -const myNums = [10, 20, 30]; -doubleAllNumbers(myNums); -console.log(myNums);