From bd846e8a910bec155d542667f1133ae272acd196 Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 00:58:36 +0100 Subject: [PATCH 01/14] debugged address.js --- 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 940a6af83..54aa0c02a 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,4 +1,5 @@ // Predict and explain first... +// This will fail because to parse from an object requires a key, not an index value // This code should log out the houseNumber from the address object // but it isn't working... @@ -12,4 +13,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address.street}, ${address.city}, ${address.country}, ${address.postcode}`); From dc61f913aa7f3bc316dd79ebdaf8904424e4ca1f Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 01:04:01 +0100 Subject: [PATCH 02/14] debugged author.js --- Sprint-2/debug/author.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..eb6208ac2 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,4 +1,5 @@ // Predict and explain first... +// the for loop it the syntax for an array, I'm not sure it will work with an object // This program attempts to log out all the property values in the object. // But it isn't working. Explain why first and then fix the problem @@ -11,6 +12,6 @@ const author = { alive: true, }; -for (const value of author) { +for (const value of Object.values(author)) { console.log(value); } From 5761063572afc6425739d2a1be45a58d6f94472f Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 01:12:46 +0100 Subject: [PATCH 03/14] debugged recipe.js --- Sprint-2/debug/recipe.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..eb835edea 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,4 +1,6 @@ // Predict and explain first... +// the title and serves looks like it would work, the ingredients list is just calling the recipe object +// that won't list any values and may return an error or undefined. // This program should log out the title, how many it serves and the ingredients. // Each ingredient should be logged on a new line @@ -11,5 +13,5 @@ const recipe = { }; console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); +ingredients: +${recipe.ingredients.join("\n")}`); From 3ff26b115a9b2322c81baa4b1fc115c376e947b7 Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 01:32:08 +0100 Subject: [PATCH 04/14] contains.test.js tests written --- Sprint-2/implement/contains.js | 4 +++- Sprint-2/implement/contains.test.js | 24 ++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..3de7795ed 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,5 @@ -function contains() {} +function contains() { + return true +} module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..3fc401aca 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -12,24 +12,44 @@ as the object doesn't contains a key of 'c' */ // 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 +describe("contains", () =>{ // Given an empty object // When passed to contains // Then it should return false -test.todo("contains on empty object returns false"); +it("contains on empty object returns false", () => { + const object = {}; + const property = 'a' + expect(contains(object, property)).toEqual(false) +}); // Given an object with properties // When passed to contains with an existing property name // Then it should return true +it("object contains property returns true", () => { + const object = {a: 1, b: 2}; + const property = 'a' + expect(contains(object, property)).toEqual(true) +}); // Given an object with properties // When passed to contains with a non-existent property name // Then it should return false +it("object does not contain property returns false", () => { + const object = {a: 1, b: 2}; + const property = 'c' + expect(contains(object, property)).toEqual(false) +}); // Given invalid parameters like an array // When passed to contains // Then it should return false or throw an error +it("given invalid parameter (an array) returns false or throws an error", () => { + const object = []; + const property = []; + expect(contains(object, property)).toEqual(false) +}); +}); \ No newline at end of file From 59b776367b8c97540efcd1c32d89e6519f4e4d3a Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 01:43:38 +0100 Subject: [PATCH 05/14] added solution to contains.js --- Sprint-2/implement/contains.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 3de7795ed..749dc3269 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,5 +1,8 @@ -function contains() { - return true +function contains(object, property) { + if (typeof object !== 'object' || Array.isArray(object)) {return false;} + if (typeof property !== 'string') {return false;} + + return Object.hasOwn(object, property) } module.exports = contains; From 40a2e863dec3f68a6ab70b6c62586466a18cad16 Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 01:51:00 +0100 Subject: [PATCH 06/14] written test for lookup.test.js --- Sprint-2/implement/contains.test.js | 2 +- Sprint-2/implement/lookup.js | 2 +- Sprint-2/implement/lookup.test.js | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 3fc401aca..4ae4376d0 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -16,7 +16,7 @@ as the object doesn't contains a key of 'c' // When passed an object and a property name // Then it should return true if the object contains the property, false otherwise -describe("contains", () =>{ +describe("contains", () => { // Given an empty object // When passed to contains // Then it should return false diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..7864587e2 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,5 @@ function createLookup() { - // implementation here + return {'US': 'USD', 'CA': 'CAD', 'UK': 'GBP'} } module.exports = createLookup; diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..8852123ed 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,6 +1,11 @@ const createLookup = require("./lookup.js"); -test.todo("creates a country currency code lookup for multiple codes"); +describe("createLookup", () => { + it("creates a country currency code lookup for multiple codes", () => { + const arrayOfArrays = [['US', 'USD'], ['CA', 'CAD'], ['UK', 'GBP']] + expect(createLookup(arrayOfArrays)).toEqual( {'US': 'USD', 'CA': 'CAD', 'UK': 'GBP'}) + }) +}); /* From 556787567fef6c47edefa3c4c143d2cb7d201202 Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 01:58:28 +0100 Subject: [PATCH 07/14] added solution to lookup.js --- 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 7864587e2..ec1a751f6 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,9 @@ -function createLookup() { - return {'US': 'USD', 'CA': 'CAD', 'UK': 'GBP'} +function createLookup(arrayOfArrays) { + const lookup = {} + for (array of arrayOfArrays) { + lookup[array[0]] = array[1]; + } + return lookup } module.exports = createLookup; From f928482bcd57d69823d7c02c72b6a02133a22c63 Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 02:36:23 +0100 Subject: [PATCH 08/14] added solution to tally.js --- Sprint-2/implement/tally.js | 11 ++++++++++- Sprint-2/implement/tally.test.js | 18 +++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..2ce89ada6 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,12 @@ -function tally() {} +function tally(array) { + if (!Array.isArray(array)) {throw new Error("Invalid array");} + tally = {} + array.forEach((item) =>{ + if (item in tally) {tally[item] += 1} + else tally[item] = 1; + }) + return tally +} module.exports = tally; + diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..406b004e5 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -20,15 +20,31 @@ const tally = require("./tally.js"); // When passed an array of items // Then it should return an object containing the count for each unique item +describe("tally", () => { // 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"); +it("tally on an empty array returns an empty object", () => { + const array = []; + expect(tally(array)).toEqual({}) +}); + // Given an array with duplicate items // When passed to tally // Then it should return counts for each unique item +it("tally returns counts for each unique item", () => { + const array = ['a', 'a', 'b', 'c']; + expect(tally(array)).toEqual({ a : 2, b: 1, c: 1 }) +}); + // Given an invalid input like a string // When passed to tally // Then it should throw an error +it("tally on an empty array returns an empty object", () => { + const array = "string"; + expect(() => {tally(array);}).toThrow("Invalid array") +}); +}); + From 3b915141b8bc25f34ccb9fb59a73a90c7bd17a8e Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 03:38:45 +0100 Subject: [PATCH 09/14] completed querystring.js --- Sprint-2/implement/querystring.js | 28 +++++++++++++++++++++++++- Sprint-2/implement/querystring.test.js | 2 ++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..9f7827a7b 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -3,14 +3,40 @@ function parseQueryString(queryString) { if (queryString.length === 0) { return queryParams; } + + // Adds percentage-encoded characters + queryString = changePEC(queryString) + + // Replaces + with space + queryString = queryString.replaceAll("+", " ") + const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); + if (pair !== "") { + let index = pair.indexOf("=") + if (!pair.includes("=")) {index = pair.length} + const [key, value] = [pair.slice(0, index), pair.slice(index + 1)] queryParams[key] = value; + } + else {}; } return queryParams; } +// this function below can have the object PEC expanded to include all percentage-encoded characters +// currently without adding this database, an unknown PEC could cause the code to get stuck in an infinite loop + +function changePEC(string) { + const PEC = {"%24": "$", "%2F": "/"} + while (string.includes("%")) { + const index = string.indexOf("%"); + const code = string.slice(index, index + 3); + if (PEC[code]) {string = string.replace(code, PEC[code]);} + else {break;} + } + return string +} + module.exports = parseQueryString; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 328b8df61..a3b3605a2 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -40,9 +40,11 @@ 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", }); }); +*/ \ No newline at end of file From 352aef984c37e7048a4d4fbb33e48c28c7967ba4 Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 03:59:14 +0100 Subject: [PATCH 10/14] completed invert.js --- Sprint-2/interpret/invert.js | 16 ++++++++++++++-- Sprint-2/interpret/invert.test.js | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 Sprint-2/interpret/invert.test.js diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..27ac09bdd 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -6,24 +6,36 @@ // E.g. invert({x : 10, y : 20}), target output: {"10": "x", "20": "y"} +invert({ a: 1, b: 2 }) + function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; + invertedObj[value] = key } - + console.log(invertedObj) return invertedObj; } + // a) What is the current return value when invert is called with { a : 1 } +// { key: 1 } // b) What is the current return value when invert is called with { a: 1, b: 2 } +// { key: 2 } // c) What is the target return value when invert is called with {a : 1, b: 2} +// {"1": "a", "2": "b"} // c) What does Object.entries return? Why is it needed in this program? +// It turns the object into an array of arrays +// It's needed so the for..of loop can access the key:value pairs // d) Explain why the current return value is different from the target output +// invertedObj.key = value; +// this line of code sets the key to "key" +// even if that worked as intended, the key and value haven't been swapped // e) Fix the implementation of invert (and write tests to prove it's fixed!) +module.exports = invert; \ No newline at end of file diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js new file mode 100644 index 000000000..5e59c375e --- /dev/null +++ b/Sprint-2/interpret/invert.test.js @@ -0,0 +1,14 @@ +const invert = require("./invert.js"); + +describe("invert", () => { +it("object returns inverted object", () => { + +// a) What is the current return value when invert is called with { a : 1 } + let object = { a : 1 }; + expect(invert(object)).toEqual({1: "a"}) + +// b) What is the current return value when invert is called with { a: 1, b: 2 } + object = { a: 1, b: 2 }; + expect(invert(object)).toEqual({1: "a", 2: "b"}) +}); +}); \ No newline at end of file From 66a45541cf3abf12b5f55fd93333d53d1ade14af Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 03:59:52 +0100 Subject: [PATCH 11/14] changes added that weren't saved to last commit --- 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 27ac09bdd..0161fc9b9 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -26,7 +26,7 @@ function invert(obj) { // { key: 2 } // c) What is the target return value when invert is called with {a : 1, b: 2} -// {"1": "a", "2": "b"} +// {1: a, 2: b} // c) What does Object.entries return? Why is it needed in this program? // It turns the object into an array of arrays From 6cb0fe27ba0d816f05de1fce84e68ef19bf8527a Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 17:28:58 +0100 Subject: [PATCH 12/14] added tests to ensure contains does not allow arrays and null, fixed lookup --- Sprint-2/debug/address.js | 4 +- Sprint-2/implement/contains.js | 10 ++-- Sprint-2/implement/contains.test.js | 75 ++++++++++++++------------ Sprint-2/implement/lookup.js | 6 +-- Sprint-2/implement/lookup.test.js | 14 +++-- Sprint-2/implement/querystring.js | 29 +++++----- Sprint-2/implement/querystring.test.js | 4 +- Sprint-2/implement/tally.js | 18 ++++--- Sprint-2/implement/tally.test.js | 47 ++++++++-------- Sprint-2/interpret/invert.js | 9 ++-- Sprint-2/interpret/invert.test.js | 17 +++--- 11 files changed, 129 insertions(+), 104 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 54aa0c02a..22b116672 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -13,4 +13,6 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address.street}, ${address.city}, ${address.country}, ${address.postcode}`); +console.log( + `My house number is ${address.houseNumber}, ${address.street}, ${address.city}, ${address.country}, ${address.postcode}` +); diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 749dc3269..f837505ae 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,8 +1,12 @@ function contains(object, property) { - if (typeof object !== 'object' || Array.isArray(object)) {return false;} - if (typeof property !== 'string') {return false;} + if (typeof object !== "object" || !object || Array.isArray(object)) { + return false; + } + if (typeof property !== "string" || !object) { + return false; + } - return Object.hasOwn(object, property) + return Object.hasOwn(object, property); } module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 4ae4376d0..6d5f04426 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -17,39 +17,46 @@ as the object doesn't contains a key of 'c' // Then it should return true if the object contains the property, false otherwise describe("contains", () => { -// Given an empty object -// When passed to contains -// Then it should return false -it("contains on empty object returns false", () => { + // Given an empty object + // When passed to contains + // Then it should return false + it("contains on empty object returns false", () => { const object = {}; - const property = 'a' - expect(contains(object, property)).toEqual(false) + const property = "a"; + expect(contains(object, property)).toEqual(false); + }); + + // Given an object with properties + // When passed to contains with an existing property name + // Then it should return true + it("object contains property returns true", () => { + const object = { a: 1, b: 2 }; + const property = "a"; + expect(contains(object, property)).toEqual(true); + }); + + // Given an object with properties + // When passed to contains with a non-existent property name + // Then it should return false + it("object does not contain property returns false", () => { + const object = { a: 1, b: 2 }; + const property = "c"; + expect(contains(object, property)).toEqual(false); + }); + + // Given invalid parameters like an array + // When passed to contains + // Then it should return false or throw an error + it("given invalid parameter (an array) returns false or throws an error", () => { + expect(contains([], [])).toEqual(false); + expect(contains(["a", 1], "a")).toEqual(false); + expect(contains({ a: 1, b: 2 }, ["a"])).toEqual(false); + expect(contains(["a", 1], ["a"])).toEqual(false); + }); + + it("given null returns false", () => { + expect(contains(null, "a")).toEqual(false); + expect(contains({ a: 1, b: 2 }, null)).toEqual(false); + expect(contains(null, null)).toEqual(false); + }); }); - -// Given an object with properties -// When passed to contains with an existing property name -// Then it should return true -it("object contains property returns true", () => { - const object = {a: 1, b: 2}; - const property = 'a' - expect(contains(object, property)).toEqual(true) -}); - -// Given an object with properties -// When passed to contains with a non-existent property name -// Then it should return false -it("object does not contain property returns false", () => { - const object = {a: 1, b: 2}; - const property = 'c' - expect(contains(object, property)).toEqual(false) -}); - -// Given invalid parameters like an array -// When passed to contains -// Then it should return false or throw an error -it("given invalid parameter (an array) returns false or throws an error", () => { - const object = []; - const property = []; - expect(contains(object, property)).toEqual(false) -}); -}); \ No newline at end of file diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index ec1a751f6..7d4439d0f 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,9 +1,9 @@ function createLookup(arrayOfArrays) { - const lookup = {} - for (array of arrayOfArrays) { + const lookup = {}; + for (const array of arrayOfArrays) { lookup[array[0]] = array[1]; } - return lookup + return lookup; } module.exports = createLookup; diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 8852123ed..8ee5bf26f 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -2,9 +2,17 @@ const createLookup = require("./lookup.js"); describe("createLookup", () => { it("creates a country currency code lookup for multiple codes", () => { - const arrayOfArrays = [['US', 'USD'], ['CA', 'CAD'], ['UK', 'GBP']] - expect(createLookup(arrayOfArrays)).toEqual( {'US': 'USD', 'CA': 'CAD', 'UK': 'GBP'}) - }) + const arrayOfArrays = [ + ["US", "USD"], + ["CA", "CAD"], + ["UK", "GBP"], + ]; + expect(createLookup(arrayOfArrays)).toEqual({ + US: "USD", + CA: "CAD", + UK: "GBP", + }); + }); }); /* diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 9f7827a7b..632407834 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -5,21 +5,23 @@ function parseQueryString(queryString) { } // Adds percentage-encoded characters - queryString = changePEC(queryString) + queryString = changePEC(queryString); // Replaces + with space - queryString = queryString.replaceAll("+", " ") - + queryString = queryString.replaceAll("+", " "); + const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { if (pair !== "") { - let index = pair.indexOf("=") - if (!pair.includes("=")) {index = pair.length} - const [key, value] = [pair.slice(0, index), pair.slice(index + 1)] - queryParams[key] = value; + let index = pair.indexOf("="); + if (!pair.includes("=")) { + index = pair.length; + } + const [key, value] = [pair.slice(0, index), pair.slice(index + 1)]; + queryParams[key] = value; + } else { } - else {}; } return queryParams; @@ -29,14 +31,17 @@ function parseQueryString(queryString) { // currently without adding this database, an unknown PEC could cause the code to get stuck in an infinite loop function changePEC(string) { - const PEC = {"%24": "$", "%2F": "/"} + const PEC = { "%24": "$", "%2F": "/" }; while (string.includes("%")) { const index = string.indexOf("%"); const code = string.slice(index, index + 3); - if (PEC[code]) {string = string.replace(code, PEC[code]);} - else {break;} + if (PEC[code]) { + string = string.replace(code, PEC[code]); + } else { + break; + } } - return string + return string; } module.exports = parseQueryString; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index a3b3605a2..c992e40f5 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({ @@ -47,4 +47,4 @@ test("should store values of a key in an array when the key has 2 or more values foo: "bar", }); }); -*/ \ No newline at end of file +*/ diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 2ce89ada6..82a3d35ab 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,12 +1,14 @@ function tally(array) { - if (!Array.isArray(array)) {throw new Error("Invalid array");} - tally = {} - array.forEach((item) =>{ - if (item in tally) {tally[item] += 1} - else tally[item] = 1; - }) - return tally + if (!Array.isArray(array)) { + throw new Error("Invalid array"); + } + tally = {}; + array.forEach((item) => { + if (item in tally) { + tally[item] += 1; + } else tally[item] = 1; + }); + return tally; } module.exports = tally; - diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 406b004e5..c9d5167fc 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -21,30 +21,29 @@ const tally = require("./tally.js"); // Then it should return an object containing the count for each unique item describe("tally", () => { -// Given an empty array -// When passed to tally -// Then it should return an empty object -it("tally on an empty array returns an empty object", () => { + // Given an empty array + // When passed to tally + // Then it should return an empty object + it("tally on an empty array returns an empty object", () => { const array = []; - expect(tally(array)).toEqual({}) -}); - - -// Given an array with duplicate items -// When passed to tally -// Then it should return counts for each unique item -it("tally returns counts for each unique item", () => { - const array = ['a', 'a', 'b', 'c']; - expect(tally(array)).toEqual({ a : 2, b: 1, c: 1 }) -}); - - -// Given an invalid input like a string -// When passed to tally -// Then it should throw an error -it("tally on an empty array returns an empty object", () => { + expect(tally(array)).toEqual({}); + }); + + // Given an array with duplicate items + // When passed to tally + // Then it should return counts for each unique item + it("tally returns counts for each unique item", () => { + const array = ["a", "a", "b", "c"]; + expect(tally(array)).toEqual({ a: 2, b: 1, c: 1 }); + }); + + // Given an invalid input like a string + // When passed to tally + // Then it should throw an error + it("tally on an empty array returns an empty object", () => { const array = "string"; - expect(() => {tally(array);}).toThrow("Invalid array") + expect(() => { + tally(array); + }).toThrow("Invalid array"); + }); }); -}); - diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index 0161fc9b9..49a737a4a 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -6,19 +6,18 @@ // E.g. invert({x : 10, y : 20}), target output: {"10": "x", "20": "y"} -invert({ a: 1, b: 2 }) +invert({ a: 1, b: 2 }); function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj[value] = key + invertedObj[value] = key; } - console.log(invertedObj) + console.log(invertedObj); return invertedObj; } - // a) What is the current return value when invert is called with { a : 1 } // { key: 1 } @@ -38,4 +37,4 @@ function invert(obj) { // even if that worked as intended, the key and value haven't been swapped // e) Fix the implementation of invert (and write tests to prove it's fixed!) -module.exports = invert; \ No newline at end of file +module.exports = invert; diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js index 5e59c375e..6343dd396 100644 --- a/Sprint-2/interpret/invert.test.js +++ b/Sprint-2/interpret/invert.test.js @@ -1,14 +1,13 @@ const invert = require("./invert.js"); describe("invert", () => { -it("object returns inverted object", () => { - -// a) What is the current return value when invert is called with { a : 1 } - let object = { a : 1 }; - expect(invert(object)).toEqual({1: "a"}) + it("object returns inverted object", () => { + // a) What is the current return value when invert is called with { a : 1 } + let object = { a: 1 }; + expect(invert(object)).toEqual({ 1: "a" }); -// b) What is the current return value when invert is called with { a: 1, b: 2 } - object = { a: 1, b: 2 }; - expect(invert(object)).toEqual({1: "a", 2: "b"}) + // b) What is the current return value when invert is called with { a: 1, b: 2 } + object = { a: 1, b: 2 }; + expect(invert(object)).toEqual({ 1: "a", 2: "b" }); + }); }); -}); \ No newline at end of file From 193230c734c46c12b24bb300ac6c9e969222c6cb Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 17:30:51 +0100 Subject: [PATCH 13/14] remove erroneous 'else' --- Sprint-2/implement/querystring.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 632407834..1e0cac42b 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -20,7 +20,6 @@ function parseQueryString(queryString) { } const [key, value] = [pair.slice(0, index), pair.slice(index + 1)]; queryParams[key] = value; - } else { } } From 8427bfd3f636fc598748f6ddea4caf1509e8d28b Mon Sep 17 00:00:00 2001 From: Alex Jamshidi Date: Wed, 13 May 2026 17:32:55 +0100 Subject: [PATCH 14/14] updated code to use decodeURIcomponent --- Sprint-2/implement/querystring.js | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 1e0cac42b..1c0491e34 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -5,7 +5,7 @@ function parseQueryString(queryString) { } // Adds percentage-encoded characters - queryString = changePEC(queryString); + queryString = decodeURIComponent(queryString); // Replaces + with space queryString = queryString.replaceAll("+", " "); @@ -26,21 +26,4 @@ function parseQueryString(queryString) { return queryParams; } -// this function below can have the object PEC expanded to include all percentage-encoded characters -// currently without adding this database, an unknown PEC could cause the code to get stuck in an infinite loop - -function changePEC(string) { - const PEC = { "%24": "$", "%2F": "/" }; - while (string.includes("%")) { - const index = string.indexOf("%"); - const code = string.slice(index, index + 3); - if (PEC[code]) { - string = string.replace(code, PEC[code]); - } else { - break; - } - } - return string; -} - module.exports = parseQueryString;