From 4b7a603e92de89316c37f61d977c9a1cdfb8d9d1 Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:14:19 +0100 Subject: [PATCH 01/13] Fixed address function --- Sprint-2/debug/address.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..36d2f865d 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -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 1b6c8afd9f41a83153e00419e7ebf07c4388c2af Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:15:45 +0100 Subject: [PATCH 02/13] Fixed author () --- Sprint-2/debug/author.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..5059a5a2a 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -2,6 +2,9 @@ // 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 +// To loop over object keys we use for in loop.In this case we declared a variable `value` +// to hold the property name. In this case we use bracket notation instead of dot notation to +// access property value. const author = { firstName: "Zadie", @@ -11,6 +14,6 @@ const author = { alive: true, }; -for (const value of author) { - console.log(value); +for (const value in author) { + console.log(author[value]); } From 62eb30bf9a525bd3e227b1f559058530ab5bcf29 Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:16:34 +0100 Subject: [PATCH 03/13] Fixed recipe ingredients --- 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..40e6d85c7 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -11,5 +11,5 @@ const recipe = { }; console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); + ingredients: +${recipe.ingredients.join("\n")}`); From b770df8de6af057dec4de50bef29dc1fb091701c Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:18:19 +0100 Subject: [PATCH 04/13] Implemented contains() --- 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..d27076be7 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,7 @@ -function contains() {} +function contains(object, propertyName) { + if (Object.hasOwn(object, propertyName)) { + return true; + } else return false; +} module.exports = contains; From d3ad67e711585eeeed1d3cdec8bdc3cc977a0d7a Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:18:39 +0100 Subject: [PATCH 05/13] Added tests for contains () --- Sprint-2/implement/contains.test.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..d8fbc12ed 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -16,20 +16,39 @@ as the object doesn't contains a key of 'c' // 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 +test("given an object with property, should return true if contains the property otherwise false", () => { + expect(contains({ a: 1, b: 2 }, "a")).toBe(true); + expect(contains({ a: 1, b: 2 }, "c")).toBe(false); +}); // 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({})).toBe(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 property, should return true if contains the property", () => { + expect( + contains({ firstName: "Chris", surname: "Marin", age: 21 }, "firstName") + ).toBe(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 property, should return false if does not contains the property", () => { + expect( + contains({ firstName: "Chris", surname: "Marin", age: 21 }, "job") + ).toBe(false); +}); // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error + +test("given an array, should return false", () => { + expect(contains([1, 2, 3], "a")).toBe(false); +}); From 9c6a37b4e6e33d90badb594dcae4016e0e1a8e68 Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:19:20 +0100 Subject: [PATCH 06/13] Implemented createLookup() --- Sprint-2/implement/lookup.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..737d3996e 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,10 @@ -function createLookup() { +function createLookup(data) { // implementation here + const newObject = {}; + for (const [country, currency] of data) { + newObject[country] = currency; + } + return newObject; } module.exports = createLookup; From 917a7a1f1b83610cdcf1ff17586a3f763648f22a Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:20:20 +0100 Subject: [PATCH 07/13] Add tests for createLookup() --- Sprint-2/implement/lookup.test.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..e5bc5f4de 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,6 +1,16 @@ 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({ + US: "USD", + CA: "CAD", + }); +}); /* From f029adad29ed32dc662dc176594c5368c7ee440e Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:20:45 +0100 Subject: [PATCH 08/13] Implemented parseQueryString() --- Sprint-2/implement/querystring.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..b073c5937 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -6,10 +6,26 @@ function parseQueryString(queryString) { const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); + if (pair === "") { + continue; + } + const equalIndex = pair.indexOf("="); + let key; + let value; + + if (equalIndex === -1) { + key = pair.slice(0); + value = ""; + } else { + key = pair.slice(0, equalIndex); + value = pair.slice(equalIndex + 1); + } + key = key.replace(/\+/g, " "); + value = value.replace(/\+/g, " "); + key = decodeURIComponent(key); + value = decodeURIComponent(value); queryParams[key] = value; } - return queryParams; } From 7d913accb12e7488d0d583899537dcd572c94e82 Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:21:11 +0100 Subject: [PATCH 09/13] Added tests for parseQueryString() --- Sprint-2/implement/querystring.test.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 328b8df61..c42fc8fdf 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -3,7 +3,7 @@ // Below are some test cases the implementation doesn't handle well. // Fix the implementation for these tests, 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"); test("should parse values containing '='", () => { expect(parseQueryString("equation=a=b-2")).toEqual({ @@ -39,10 +39,10 @@ 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", - }); -}); +// // 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", +// }); +// }); From a0bf22b11f5b71cfb86c8d87294c5f3b429f6afc Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:21:26 +0100 Subject: [PATCH 10/13] Implemented tally() --- 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..5fdfeb1de 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,14 @@ -function tally() {} +function tally(items) { + if (!Array.isArray(items)) { + throw new Error("Invalid input"); + } + const itemsObj = {}; + for (const item of items) { + if (itemsObj[item] === undefined) { + itemsObj[item] = 1; + } else itemsObj[item]++; + } + return itemsObj; +} module.exports = tally; From 16e03684dda69831c66edcfe52c56b59d94cf015 Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:21:47 +0100 Subject: [PATCH 11/13] Added tests for tally() --- Sprint-2/implement/tally.test.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..00f8536c3 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -11,7 +11,7 @@ const tally = require("./tally.js"); * * 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 } + * tally([c]), target output: { a : 2, b: 1, c: 1 } */ // Acceptance criteria: @@ -19,16 +19,27 @@ const tally = require("./tally.js"); // Given a function called tally // When passed an array of items // Then it should return an object containing the count for each unique item +test("Given an array of items, should return an object containing the count for each unique item", () => { + expect(tally(["a", "b", "c", "d"])).toEqual({ a: 1, b: 1, c: 1, d: 1 }); +}); // 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("Given an array with duplicate items, should return counts for each unique item", () => { + expect(tally(["a", "a", "a", "b", "b", "c"])).toEqual({ a: 3, b: 2, c: 1 }); +}); // Given an invalid input like a string // When passed to tally // Then it should throw an error +test("Given an invalid input like a string, it should throw an error", () => { + expect(() => tally("hello")).toThrow(); +}); From 67163fd4569141bb415cc721e8abe5e94ecea6d1 Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:22:14 +0100 Subject: [PATCH 12/13] implemented invert() --- Sprint-2/interpret/invert.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..43641335e 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,20 +10,26 @@ function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; + invertedObj[value] = key; } - return invertedObj; } +module.exports = invert; // a) What is the current return value when invert is called with { a : 1 } +// The current return value when inverted is called with { a: 1 } is{ key: 1 } // b) What is the current return value when invert is called with { a: 1, b: 2 } +// The current return value when inverted is called with { a: 1, b: 2 } is { key: 2 } // c) What is the target return value when invert is called with {a : 1, b: 2} +// The target return value when invert is called with { a : 1, b: 2 } is { 1 : a, 2: b } // c) What does Object.entries return? Why is it needed in this program? +// Object.entries return an array where each element of array is a pair key-value. It is needed in this program because an object can not be looped with for...of. -// d) Explain why the current return value is different from the target output +// d) Explain why the current return value is different from the target output. +// The current return value is different from the target output because when we apply +//invertedObj.key = value we are declaring a new key and assigning the value // e) Fix the implementation of invert (and write tests to prove it's fixed!) From 32248d6d6d2da977f2b2c769e9a2c4ab1a2c4600 Mon Sep 17 00:00:00 2001 From: dona-shehu Date: Thu, 23 Jul 2026 17:22:35 +0100 Subject: [PATCH 13/13] Added tests for invert() --- Sprint-2/interpret/invert.test.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 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..e252c936a --- /dev/null +++ b/Sprint-2/interpret/invert.test.js @@ -0,0 +1,26 @@ +const invert = require("./invert.js"); + +// Given an empty object +// When invert is passed this object +// Then it should return an empty object. +test("Given an empty object,should return an empty object", () => { + expect(invert({})).toEqual({}); +}); + +// Given an object +// When invert is passed this object +// Then it should swap the keys and values in the object +test("Given an object, should swap the keys and values in the object", () => { + expect(invert({ a: 1 })).toEqual({ 1: "a" }); + expect(invert({ a: 1, b: 2 })).toEqual({ 1: "a", 2: "b" }); + expect(invert({ a: 1, b: 2, c: 3, d: 4 })).toEqual({ + 1: "a", + 2: "b", + 3: "c", + 4: "d", + }); +}); + +test("Given an empty object, should swap the keys and values in the object", () => {}); + +test("Given an object, should swap the keys and values in the object", () => {});