From 3b1edc021120f746cab9d4a6ca01d6d68303d180 Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Wed, 12 Nov 2025 13:23:05 +0100 Subject: [PATCH 01/12] Update address.js files modified --- Sprint-2/debug/address.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..0a63bf437 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -12,4 +12,8 @@ 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}`); + + From 9b84a4eefe61d8b7e95fba9cb88efa43301833c8 Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Wed, 12 Nov 2025 13:35:28 +0100 Subject: [PATCH 02/12] Update author.js files modified --- Sprint-2/debug/author.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..ddd731645 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -11,6 +11,11 @@ const author = { alive: true, }; -for (const value of author) { +/*for (const value of author) { + console.log(value); +}*/ + +for (const value of Object.values(author)) { console.log(value); } + From 7b8ebf7e163a1482f3c073f2830a540bc0185011 Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Thu, 13 Nov 2025 10:36:09 +0100 Subject: [PATCH 03/12] Update recipe.js added properties --- 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..6f64e73dd 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}`);*/ //incomplete instructions, To show data inside we need to add more properties +${recipe.ingredients.join(", ")}`); From 20d889c7803bd76d72051396d818758a5b7d8dd8 Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Thu, 20 Nov 2025 12:38:18 +0100 Subject: [PATCH 04/12] Update contains.js completed the code --- Sprint-2/implement/contains.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..b45ce2bed 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,8 @@ -function contains() {} +function contains(obj, property) { + if (obj === null || typeof obj !== "object" || Array.isArray(obj)) { + return false; + } + return Object.hasOwn(obj, property); +} module.exports = contains; From 39f150f36e3aedad5f54e7c73f0d950aa9015bf2 Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Thu, 20 Nov 2025 22:06:49 +0100 Subject: [PATCH 05/12] Update contains.test.js added tests --- Sprint-2/implement/contains.test.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..cea8af07b 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -16,20 +16,40 @@ 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("returns true when object contains the property", () => { + expect(contains({ a: 1, b: 2 }, "a")).toBe(true); + expect(contains({ name: "Alice", age: 25 }, "age")).toBe(true); + expect(contains({ g: "p", m: 1 }, "t")).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({}, "a")).toBe(false); +}); // Given an object with properties // When passed to contains with an existing property name // Then it should return true +test("returns true for existing property", () => { + expect(contains({ a: 1, b: 2, c: 3 }, "c")).toBe(true); +}); // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +test("returns false for non-existent property", () => { + expect(contains({ a: 1, b: 2 }, "z")).toBe(false); +}); // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error + +test("returns false for invalid parameters", () => { + expect(contains([], "a")).toBe(false); + expect(contains(null, "a")).toBe(false); + expect(contains(undefined, "a")).toBe(false); + expect(contains(42, "a")).toBe(false); + expect(contains("notAnObject", "a")).toBe(false); +}); From b1d213249446f9db5e03821fdd1f4ab513145a2f Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Thu, 20 Nov 2025 22:09:07 +0100 Subject: [PATCH 06/12] Update lookup.js code completed --- 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..bec9555db 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,9 @@ -function createLookup() { - // implementation here +function createLookup(pairs) { + if (!Array.isArray(pairs)) { + throw new Error("Input must be an array of pairs"); + } + + return Object.fromEntries(pairs); } module.exports = createLookup; From 8f726b2d9057231dc77fbd408f1b2e42029e372b Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Thu, 20 Nov 2025 22:10:30 +0100 Subject: [PATCH 07/12] Update lookup.test.js test cases created --- Sprint-2/implement/lookup.test.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..332f7dce5 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,6 +1,6 @@ const createLookup = require("./lookup.js"); -test.todo("creates a country currency code lookup for multiple codes"); +//test.todo("creates a country currency code lookup for multiple codes"); /* @@ -33,3 +33,26 @@ It should return: 'CA': 'CAD' } */ + +test("creates a country currency code lookup for multiple codes", () => { + const pairs = [ + ["US", "USD"], + ["CA", "CAD"], + ]; + + const expected = { + US: "USD", + CA: "CAD", + }; + + expect(createLookup(pairs)).toEqual(expected); +}); + +test("returns an empty object for an empty array", () => { + expect(createLookup([])).toEqual({}); +}); + +test("throws an error for invalid input", () => { + expect(() => createLookup(null)).toThrow(Error); + expect(() => createLookup("not an array")).toThrow(Error); +}); From 11325dabf80dbf1ad246655aac879001b35e4988 Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Thu, 20 Nov 2025 22:22:57 +0100 Subject: [PATCH 08/12] Update querystring.js code completed --- Sprint-2/implement/querystring.js | 41 +++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..e28c03121 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,16 +1,31 @@ -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; +function parseQueryString(query) { + const result = {}; + if (!query) return result; + + if (query.startsWith("?")) query = query.slice(1); + if (!query) return result; + + query.split("&").forEach(pair => { + if (!pair) return; + + const [key, value = ""] = pair.split("="); + const k = key.replace(/\+/g, " "); + const v = value.replace(/\+/g, " "); + + if (result[k]) { + result[k] = [].concat(result[k], v); + } else { + result[k] = v; + } + }); + + return result; +} + +module.exports = parseQueryString; + + + return result; } module.exports = parseQueryString; From 0b755856e218663523d4b51fd668d64d4631f671 Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Thu, 20 Nov 2025 23:40:17 +0100 Subject: [PATCH 09/12] Update querystring.test.js added different test cases. --- Sprint-2/implement/querystring.test.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 3e218b789..32ea8cd78 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -10,3 +10,23 @@ test("parses querystring values containing =", () => { "equation": "x=y+1", }); }); + +test("parses multiple key-value pairs", () => { + expect(parseQueryString("a=1&b=2")).toEqual({ a: "1", b: "2" }); +}); + +test("handles empty query string", () => { + expect(parseQueryString("")).toEqual({}); +}); + +test("handles values with multiple =", () => { + expect(parseQueryString("formula=a=b=c=d")).toEqual({ formula: "a=b=c=d" }); +}); + +test("handles keys with no value", () => { + expect(parseQueryString("flag")).toEqual({ flag: "" }); +}); + +test("handles multiple & with some empty pairs", () => { + expect(parseQueryString("a=1&&b=2&c")).toEqual({ a: "1", b: "2", c: "" }); +}); From e8cd3de3b4fe0270d7dcf79e93f0b9433078bd0a Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Thu, 20 Nov 2025 23:43:04 +0100 Subject: [PATCH 10/12] Update tally.js tally code created --- 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..a8259b828 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,9 @@ -function tally() {} +function tally(arr) { + const result = {}; + for (const item of arr) { + result[item] = (result[item] || 0) + 1; + } + return result; +} module.exports = tally; From 73e6d0811437addd9c3926b0d4eb5ff05b394b01 Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Thu, 20 Nov 2025 23:55:59 +0100 Subject: [PATCH 11/12] Update tally.test.js added test cases --- Sprint-2/implement/tally.test.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..bf662820d 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -20,15 +20,35 @@ const tally = require("./tally.js"); // When passed an array of items // Then it should return an object containing the count for each unique item +test("returns an object with counts for each unique item", () => { + expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 1 }); + expect(tally(["cow", "goat", "cow", "fox"])).toEqual({ + cow: 2,goat: 1,fox: 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("tally returns counts for each unique item", () => { + expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 1 }); + expect(tally(["x", "x", "x"])).toEqual({ x: 3 }); +}); + // Given an invalid input like a string // When passed to tally // Then it should throw an error + +test("throws an error for invalid input", () => { + expect(() => tally("not an array")).toThrow("Input must be an array"); + expect(() => tally(123)).toThrow("Input must be an array"); +}); From 584a87bd1ecf5cbfbb4e074b5afcd4f9d080769d Mon Sep 17 00:00:00 2001 From: Preeti Tyagi <68293926+preeti-t@users.noreply.github.com> Date: Fri, 21 Nov 2025 00:11:19 +0100 Subject: [PATCH 12/12] Update invert.js test cases added and invert code created --- Sprint-2/interpret/invert.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..a425c8a44 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,20 +10,30 @@ function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; + invertedObj[value] = key; } return invertedObj; } +module.exports = invert; + +const invert = require("./invert.js"); + // a) What is the current return value when invert is called with { a : 1 } +{ key: 1 } + // b) What is the current return value when invert is called with { a: 1, b: 2 } +{ key: 2 } + // c) What is the target return value when invert is called with {a : 1, b: 2} +{ "1": "a", "2": "b" } // c) What does Object.entries return? Why is it needed in this program? - +returns an array of [key, value] pairs // d) Explain why the current return value is different from the target output // e) Fix the implementation of invert (and write tests to prove it's fixed!) +console.log(invert({ a: 1, b: 2 }));