From 387c8410f7829b70da9e8e8face4f4383a307764 Mon Sep 17 00:00:00 2001 From: Konvaly Date: Mon, 1 Dec 2025 01:05:40 +0000 Subject: [PATCH 1/8] Explained and fixed debug/address.js --- Sprint-2/debug/address.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..77b745042 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,4 +1,7 @@ // Predict and explain first... +//I guess that the code will log "My house number is undefined" because address[0] isn't a valid way +// to access the houseNumber property. When we do address[0], JS looks for a property literally +// named "0", because bracket notation treats 0 as the string "0" // This code should log out the houseNumber from the address object // but it isn't working... @@ -12,4 +15,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address["houseNumber"]}`); From 4fa4c91ab62df75b022ce68fe55e5baea6ab7279 Mon Sep 17 00:00:00 2001 From: Konvaly Date: Mon, 1 Dec 2025 01:13:28 +0000 Subject: [PATCH 2/8] Explained and fixed debug/author.js --- Sprint-2/debug/author.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..640912101 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,4 +1,6 @@ // Predict and explain first... +// for...of only works on arrays. An object isn’t an array, so we can’t loop over it directly. +// To find values from the object we need to convert it to an array of values 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 @@ -11,6 +13,6 @@ const author = { alive: true, }; -for (const value of author) { +for (const value of Object.values(author)) { console.log(value); } From c7e49b65d2e81e660b2639d99495d54c90b5c34c Mon Sep 17 00:00:00 2001 From: Konvaly Date: Mon, 1 Dec 2025 01:22:41 +0000 Subject: [PATCH 3/8] Explained and fixed debug/recipe.js --- Sprint-2/debug/recipe.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..9c4dddd50 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,4 +1,6 @@ // Predict and explain first... +// I think it incorrectly tries to log ingredients - this should be an array, +// but there's missed .ingredients after the object name, so it will likely log something like "[object Object]" instead of the actual ingredients. // This program should log out the title, how many it serves and the ingredients. // Each ingredient should be logged on a new line @@ -12,4 +14,4 @@ const recipe = { console.log(`${recipe.title} serves ${recipe.serves} ingredients: -${recipe}`); +${recipe.ingredients.join(", ")}`); From a2bb8bfacba0b4f62f775c53de039808e072bd71 Mon Sep 17 00:00:00 2001 From: Konvaly Date: Mon, 1 Dec 2025 01:43:47 +0000 Subject: [PATCH 4/8] Added tests and solved implement/contains.js --- Sprint-2/implement/contains.js | 5 +++- Sprint-2/implement/contains.test.js | 45 +++++++++++++++++++---------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..87192bc24 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,6 @@ -function contains() {} +function contains(obj, prop) { + if (Object.keys(obj).length === 0) return false; + return Object.prototype.hasOwnProperty.call(obj, prop); +} module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..60e332a3f 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -17,19 +17,32 @@ 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 -// Given an empty object -// When passed to contains -// Then it should return false -test.todo("contains on empty object returns false"); - -// 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 invalid parameters like an array -// When passed to contains -// Then it should return false or throw an error +describe("contains", () => { + // 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); + }); + + // Given an object with properties + // When passed to contains with an existing property name + // Then it should return true + test("contains on object with existing property returns true", () => { + expect(contains({ a: 1, d: 4 }, "d")).toBe(true); + }); + + // Given an object with properties + // When passed to contains with a non-existent property name + // Then it should return false + test("contains on object with non-existent property returns false", () => { + expect(contains({ a: 1, b: 4 }, "c")).toBe(false); + }); + + // Given invalid parameters like an array + // When passed to contains + // Then it should return false or throw an error + test("contains on invalid parameters returns false", () => { + expect(contains([], "a")).toBe(false); + }); +}); From 14562472bf0ec9eb9ca6d12d5842cd08fae83e61 Mon Sep 17 00:00:00 2001 From: Konvaly Date: Mon, 1 Dec 2025 01:55:51 +0000 Subject: [PATCH 5/8] Added tests and solved implement/lookup.js --- Sprint-2/implement/lookup.js | 8 ++++-- Sprint-2/implement/lookup.test.js | 41 +++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..737b41dbf 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,9 @@ -function createLookup() { - // implementation here +function createLookup(arr) { + const lookup = {}; + for (const [country, currency] of arr) { + lookup[country] = currency; + } + return lookup; } module.exports = createLookup; diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..d433e8dd3 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,7 +1,5 @@ const createLookup = require("./lookup.js"); -test.todo("creates a country currency code lookup for multiple codes"); - /* Create a lookup object of key value pairs from an array of code pairs @@ -33,3 +31,42 @@ It should return: 'CA': 'CAD' } */ + +describe("createLookup", () => { + test("should create a lookup object from country-currency pairs", () => { + const countryCurrencyPairs = [ + ["US", "USD"], + ["CA", "CAD"], + ["GB", "GBP"], + ["FR", "EUR"], + ]; + + const expectedLookup = { + US: "USD", + CA: "CAD", + GB: "GBP", + FR: "EUR", + }; + + const lookup = createLookup(countryCurrencyPairs); + expect(lookup).toEqual(expectedLookup); + }); + + test("should return an empty object when given an empty array", () => { + const countryCurrencyPairs = []; + const expectedLookup = {}; + + const lookup = createLookup(countryCurrencyPairs); + expect(lookup).toEqual(expectedLookup); + }); + + test("should handle single pair correctly", () => { + const countryCurrencyPairs = [["CA", "CAD"]]; + const expectedLookup = { + CA: "CAD", + }; + + const lookup = createLookup(countryCurrencyPairs); + expect(lookup).toEqual(expectedLookup); + }); +}); From ddfb5d715ab1abc63466e9baafc170b6c991cd25 Mon Sep 17 00:00:00 2001 From: Konvaly Date: Mon, 1 Dec 2025 02:16:28 +0000 Subject: [PATCH 6/8] Added tests and solved implement/tally.js --- Sprint-2/implement/tally.js | 12 +++++++++- Sprint-2/implement/tally.test.js | 40 +++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..5918e4b0e 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,13 @@ -function tally() {} +function tally(arr) { + if (!Array.isArray(arr)) { + throw new Error("Input must be an array"); + } + + const counts = {}; + for (const item of arr) { + counts[item] = (counts[item] || 0) + 1; + } + return counts; +} module.exports = tally; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..f4e6ffbf9 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -16,19 +16,33 @@ const tally = require("./tally.js"); // 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 +describe("tally", () => { + // 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.todo("tally on an empty array returns an empty object"); + // 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({}); + }); -// Given an array with duplicate items -// When passed to tally -// Then it should return counts for each unique item + // Given an array with duplicate items + // When passed to tally + // Then it should return counts for each unique item + test("tally counts duplicate items correctly", () => { + expect(tally(["a", "a", "g", "b", "a", "b", "a"])).toEqual({ + a: 4, + b: 2, + g: 1, + }); + }); -// Given an invalid input like a string -// When passed to tally -// Then it should throw an error + // Given an invalid input like a string + // When passed to tally + // Then it should throw an error + test("tally throws an error for invalid input", () => { + expect(() => tally({})).toThrow("Input must be an array"); + }); +}); From c5baf81ab7ed920b822f4055c8a7cad2471cc7c3 Mon Sep 17 00:00:00 2001 From: Konvaly Date: Mon, 1 Dec 2025 02:32:50 +0000 Subject: [PATCH 7/8] Added tests and solved implement/querystring.js --- Sprint-2/implement/querystring.js | 4 +-- Sprint-2/implement/querystring.test.js | 35 +++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..578ae0a7c 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -6,8 +6,8 @@ function parseQueryString(queryString) { const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); - queryParams[key] = value; + const [key, ...rest] = pair.split("="); + queryParams[key] = rest.join("="); } return queryParams; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 3e218b789..71e710764 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -3,10 +3,37 @@ // Below is one test case for an edge case the implementation doesn't handle well. // Fix the implementation for this test, 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("parses querystring values containing =", () => { - expect(parseQueryString("equation=x=y+1")).toEqual({ - "equation": "x=y+1", +describe("parseQueryString", () => { + test("parses querystring values containing =", () => { + expect(parseQueryString("equation=x=y+1")).toEqual({ + equation: "x=y+1", + }); + }); + + test("parses empty querystring", () => { + expect(parseQueryString("")).toEqual({}); + }); + + test("parses multiple key-value pairs", () => { + expect(parseQueryString("name=Jane&age=37&city=New+York")).toEqual({ + name: "Jane", + age: "37", + city: "New+York", + }); + }); + + test("parses key with empty value", () => { + expect(parseQueryString("key1=&key2=value2")).toEqual({ + key1: "", + key2: "value2", + }); + }); + + test("parses value with special characters", () => { + expect(parseQueryString("greeting=Hello%2C+World%21")).toEqual({ + greeting: "Hello%2C+World%21", + }); }); }); From e8054d37dc6ad2dc6ea4bed845d66f09f27a04d6 Mon Sep 17 00:00:00 2001 From: Konvaly Date: Mon, 1 Dec 2025 02:49:38 +0000 Subject: [PATCH 8/8] Added tests and solved invert.js --- Sprint-2/interpret/invert.js | 10 +++++++- Sprint-2/interpret/invert.test.js | 38 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) 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..4d69c4ce7 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,20 +10,28 @@ 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 } +// I think its { key: 1 } // b) What is the current return value when invert is called with { a: 1, b: 2 } +// I think it should be { key: 2 } // c) What is the target return value when invert is called with {a : 1, b: 2} +// my suggestion is { '1': 'a', '2': 'b' } // c) What does Object.entries return? Why is it needed in this program? +// Object.entries returns an array of a given object's own enumerable string-keyed property [key, value] pairs. +// It is needed in this program to iterate over the key-value pairs of the object to swap them. // d) Explain why the current return value is different from the target output +// I think its different because in the line invertedObj.key = value; +// the key is being set as the string "key" instead of using the variable key. // e) Fix the implementation of invert (and write tests to prove it's fixed!) diff --git a/Sprint-2/interpret/invert.test.js b/Sprint-2/interpret/invert.test.js new file mode 100644 index 000000000..719e408fd --- /dev/null +++ b/Sprint-2/interpret/invert.test.js @@ -0,0 +1,38 @@ +const invert = require("./invert.js"); + +describe("invert", () => { + // Given an object with one key-value pair + // When invert is called with this object + // Then it should return an object with the key and value swapped + test("invert swaps key and value for single pair", () => { + expect(invert({ a: 1 })).toEqual({ 1: "a" }); + }); + + // Given an object with multiple key-value pairs + // When invert is called with this object + // Then it should return an object with the keys and values swapped + test("invert swaps keys and values for multiple pairs", () => { + expect(invert({ a: 1, b: 2 })).toEqual({ 1: "a", 2: "b" }); + }); + + // Given an object with string values + // When invert is called with this object + // Then it should return an object with the keys and values swapped + test("invert swaps keys and values for string values", () => { + expect(invert({ x: "apple", y: "banana" })).toEqual({ + apple: "x", + banana: "y", + }); + }); + + // Given an object with mixed value types + // When invert is called with this object + // Then it should return an object with the keys and values swapped + test("invert swaps keys and values for mixed value types", () => { + expect(invert({ a: 1, b: "two", c: 3 })).toEqual({ + 1: "a", + two: "b", + 3: "c", + }); + }); +});