From 7f411c4964d2793c670bce6771baf034a875a50f Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Tue, 7 Oct 2025 16:20:55 +0100 Subject: [PATCH 01/17] question answered and code fixed --- 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..7236aa64a 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,4 +1,8 @@ // Predict and explain first... +/* address[0] does not access the houseNumber property of the address object. In JavaScript, objects are +accessed using their property names, not numerical indices. Therefore, address[0] is undefined because +there is no property with the key '0' in the address object. To access the houseNumber property, we should +use address.houseNumber or address['houseNumber']. */ // This code should log out the houseNumber from the address object // but it isn't working... @@ -12,4 +16,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address.houseNumber}`); From 3bd2fa840e4337cb5f0db02082da970fef8ac31b Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Tue, 7 Oct 2025 16:44:26 +0100 Subject: [PATCH 02/17] question answered and code fixed --- Sprint-2/debug/author.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..6e61e0641 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,4 +1,8 @@ // Predict and explain first... +/* In JavaScript, objects are not iterable by default, which means you cannot use a for...of loop directly on an object. +The for...of loop is designed to work with iterable objects like arrays, strings, maps, and sets. Since the 'author' object +is not iterable, attempting to use for...of on it will result in a TypeError. To iterate over the properties of an object, +we can use Object.keys(), Object.values(), or Object.entries().*/ // 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 +15,6 @@ const author = { alive: true, }; -for (const value of author) { +for (const value of Object.values(author)) { console.log(value); } From 6f677424b048ab1a70760aaacf521b51b6d42d7c Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Tue, 7 Oct 2025 16:55:59 +0100 Subject: [PATCH 03/17] question answered and code fixed to log ingredients --- Sprint-2/debug/recipe.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..d0aed33c6 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,4 +1,8 @@ // Predict and explain first... +/* In JavaScript, when you try to log an object directly within a template literal, it doesn't automatically +format the object in a readable way. Instead, it converts the object to a string, which results in "[object Object]". +To properly display the ingredients on new lines, we need to join the array elements into a single string with +newline characters in between.*/ // 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 +15,8 @@ const recipe = { }; console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); +Ingredients: +${recipe.ingredients.map(ingredients => `-${ingredients}`).join("\n")}`); +// Using map to format each ingredient and join to create a single string with new lines +// between each ingredient. + From e384e28a1d30123a878c8ac12ce87275d23356f6 Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Tue, 28 Oct 2025 11:05:18 +0000 Subject: [PATCH 04/17] updates --- Sprint-2/implement/contains.js | 14 +++++++++++++- Sprint-2/implement/contains.test.js | 10 +++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..2d4124ccb 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,15 @@ -function contains() {} +function contains(obj, key) { + /** + * Checks if the given array contains the specified value. + * @param {Array} arr - The array to check. + * @param {*} value - The value to search for. + * @returns {boolean} - Returns true if the value is found, otherwise false. + */ + if (obj === null || typeof obj !== "object" || Array.isArray(obj)) { + throw new TypeError("First argument must be a non-null object"); + } + + return Object.prototype.hasOwnProperty.call(obj, key); +} module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..ce917ea0a 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -20,15 +20,23 @@ as the object doesn't contains a key of 'c' // 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("contains on object with existing property returns true", () => { + expect(contains({ a: 1, b: 2 }, "a")).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: 2 }, "c")).toBe(false); +}); // Given invalid parameters like an array // When passed to contains From 5aeb9476350387cdfe45caa1d77691b68f3cc2ca Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Thu, 30 Oct 2025 10:38:26 +0000 Subject: [PATCH 05/17] function fixed with test-cases --- Sprint-2/implement/contains.js | 3 ++- Sprint-2/implement/contains.test.js | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 2d4124ccb..e354f632f 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -6,10 +6,11 @@ function contains(obj, key) { * @returns {boolean} - Returns true if the value is found, otherwise false. */ if (obj === null || typeof obj !== "object" || Array.isArray(obj)) { - throw new TypeError("First argument must be a non-null object"); + return false; } return Object.prototype.hasOwnProperty.call(obj, key); } module.exports = contains; + diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index ce917ea0a..d7cb15dcb 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -41,3 +41,8 @@ test("contains on object with non-existent property returns 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); + expect(contains(null, "a")).toBe(false); + expect(contains(undefined, "a")).toBe(false); +}); From 97a9291a39230ef514b567a3778be085a8ace468 Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Thu, 30 Oct 2025 10:47:55 +0000 Subject: [PATCH 06/17] created function and testcases for lookups --- Sprint-2/implement/lookup.js | 16 ++++++++++++++-- Sprint-2/implement/lookup.test.js | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..4d0442bdf 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,17 @@ -function createLookup() { - // implementation here +function createLookup(pairs) { + /** + * Creates a lookup object from an array of [key, value] pairs. + * @param {Array>} pairs - An array of [countryCode, currencyCode] pairs. + * @returns {Object} - A lookup object mapping country codes to currency codes. + */ + if (!Array.isArray(pairs)) { + throw new TypeError("Argument must be an array of pairs"); + } + + return pairs.reduce((lookup, [country, currency]) => { + 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..d60bcd832 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,7 +1,19 @@ 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", () => { + const input = [ + ["US", "USD"], + ["CA", "CAD"], + ["JP", "JPY"], + ]; + const expected = { + US: "USD", + CA: "CAD", + JP: "JPY", + }; + + expect(createLookup(input)).toEqual(expected); +}); /* Create a lookup object of key value pairs from an array of code pairs From c7188a01e48d5b3aa06be67ff54161525ef910eb Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Thu, 30 Oct 2025 10:56:14 +0000 Subject: [PATCH 07/17] fixed function to work with all the test-cases in querystring --- Sprint-2/implement/querystring.js | 14 ++++++-- Sprint-2/implement/querystring.test.js | 48 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..120cc2172 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -1,13 +1,21 @@ function parseQueryString(queryString) { const queryParams = {}; - if (queryString.length === 0) { + if (!queryString || queryString.length === 0) { return queryParams; } + const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); - queryParams[key] = value; + if (!pair) continue; // skip empty entries (e.g. trailing &) + const [key, ...rest] = pair.split("="); + const value = rest.length > 0 ? rest.join("=") : null; + + // Decode URI components + const decodedKey = decodeURIComponent(key); + const decodedValue = value === null ? null : decodeURIComponent(value); + + queryParams[decodedKey] = decodedValue; } return queryParams; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 3e218b789..cd675b06b 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -10,3 +10,51 @@ test("parses querystring values containing =", () => { "equation": "x=y+1", }); }); + +// Additional test cases to cover more edge cases +// query strings with multiple key-value pairs +test("parses querystring with multiple & and =", () => { + expect(parseQueryString("a=1&b=2&c=3")).toEqual({ + "a": "1", + "b": "2", + "c": "3", + }); +}); + +// query strings with empty keys +test("parses querystring with empty value", () => { + expect(parseQueryString("key=")).toEqual({ + "key": "", + }); +}); + +// query strings with no value +test("parses querystring with no value", () => { + expect(parseQueryString("flag")).toEqual({ + "flag": null, + }); +}); + +// query strings with encoded characters +test("parses querystring with encoded characters", () => { + expect(parseQueryString("name=John%20Doe&city=New%20York")).toEqual({ + "name": "John Doe", + "city": "New York", + }); +}); + +// query strings with repeated keys +test("parses querystring with repeated keys", () => { + expect(parseQueryString("key=1&key=2")).toEqual({ + "key": "2", // assuming last value wins + }); +}); + +// query strings with trailing & +test("parses querystring with trailing &", () => { + expect(parseQueryString("key1=value1&key2=value2&")).toEqual({ + "key1": "value1", + "key2": "value2", + }); +}); + From e90d9dd16de5d68acaa6609b0559c94a44db80d1 Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Thu, 30 Oct 2025 11:00:59 +0000 Subject: [PATCH 08/17] fixed function and added test-cases for tally --- Sprint-2/implement/tally.js | 17 ++++++++++++++++- Sprint-2/implement/tally.test.js | 16 +++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..434c32cac 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,18 @@ -function tally() {} +function tally(items) { + if (!Array.isArray(items)) { + throw new Error("Input must be an array"); + } + const result = {}; + + for (const item of items) { + if (result[item]) { + result[item]++; + } else { + result[item] = 1; + } + } + + return result; +} module.exports = tally; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..1bc673eea 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -20,15 +20,29 @@ 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("tally counts unique items in an array", () => { + expect(tally(["a"])).toEqual({ a: 1 }); + expect(tally(["a", "a", "a"])).toEqual({ a: 3 }); + expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 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 counts duplicates correctly", () => { + expect(tally(["apple", "banana", "apple"])).toEqual({ apple: 2, banana: 1 }); +}); // Given an invalid input like a string // When passed to tally // Then it should throw an error +test("tally throws error for non-array input", () => { + expect(() => tally("not an array")).toThrow("Input must be an array"); +}); From 01d2170e4d709fadb6fafa521818b4c250c0e4cc Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Thu, 30 Oct 2025 11:17:15 +0000 Subject: [PATCH 09/17] function fixed and testcases created and tested to pass. --- Sprint-2/interpret/invert.js | 16 +++++++++++++++- Sprint-2/interpret/inverts.test.js | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 Sprint-2/interpret/inverts.test.js diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..a3ea0d144 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,20 +10,34 @@ function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj.key = value; + invertedObj[value] = key; } return invertedObj; } // a) What is the current return value when invert is called with { a : 1 } +// a) Current return value: { key: 1 } +// a) Target return value: { 1: "a" } // b) What is the current return value when invert is called with { a: 1, b: 2 } +// b) Current return value: { key: 2 } +// b) Target return value: { 1: "a", 2: "b" } // c) What is the target return value when invert is called with {a : 1, b: 2} +// c) Current return value: { key: 2 } +// c) Target return value: { 1: "a", 2: "b" } // c) What does Object.entries return? Why is it needed in this program? +// c) Object.entries returns an array of a given object's own enumerable string-keyed property [key, value] pairs. +// c) It is needed in this program to iterate over each key-value pair in the input object so that we can swap them and build the inverted object. // d) Explain why the current return value is different from the target output +// d) The current return value is different from the target output because the implementation incorrectly assigns the value to a fixed key 'key' +// in the inverted object, rather than using the actual value from the original object as the key in the inverted object. This results in only the +// last processed value being stored under the same key 'key', overwriting any previous entries. // e) Fix the implementation of invert (and write tests to prove it's fixed!) +// e) Fixed implementation is provided above. Below are the test cases in a separate file. + +module.exports = invert; \ No newline at end of file diff --git a/Sprint-2/interpret/inverts.test.js b/Sprint-2/interpret/inverts.test.js new file mode 100644 index 000000000..a120bcc59 --- /dev/null +++ b/Sprint-2/interpret/inverts.test.js @@ -0,0 +1,26 @@ +const invert = require("./invert"); + +// Test cases for single key-value pair +test("inverts a single key-value pair", () => { + expect(invert({ a: 1 })).toEqual({ 1: "a" }); +}); + +// Test cases for multiple key-value pairs +test("inverts multiple key-value pairs", () => { + expect(invert({ a: 1, b: 2 })).toEqual({ 1: "a", 2: "b" }); +}); + +// Test cases for string values +test("inverts string values", () => { + expect(invert({ a: "x", b: "y" })).toEqual({ x: "a", y: "b" }); +}); + +// Test cases for mixed value types +test("overwrites keys when values are not unique", () => { + expect(invert({ a: 1, b: 1 })).toEqual({ 1: "b" }); // last one wins +}); + +// Test cases for empty object +test("inverts an empty object", () => { + expect(invert({})).toEqual({}); +}); From 8aee17ec34671a25b196236efc7e9af24c47892f Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Sun, 16 Nov 2025 10:49:55 +0000 Subject: [PATCH 10/17] element name fixed --- Sprint-2/debug/recipe.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index d0aed33c6..324a827fa 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -16,7 +16,7 @@ const recipe = { console.log(`${recipe.title} serves ${recipe.serves} Ingredients: -${recipe.ingredients.map(ingredients => `-${ingredients}`).join("\n")}`); +${recipe.ingredients.map(ingredient => `-${ingredient}`).join("\n")}`); // Using map to format each ingredient and join to create a single string with new lines // between each ingredient. From c8e50b387fcab3fc07c56d77e87105b5b3523467 Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Sun, 16 Nov 2025 11:05:07 +0000 Subject: [PATCH 11/17] contains-test fixed --- Sprint-2/implement/contains.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index d7cb15dcb..94e9dd96f 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -21,7 +21,9 @@ as the object doesn't contains a key of 'c' // When passed to contains // Then it should return false test("contains on empty object returns false", () => { - expect(contains({}, "a")).toBe(false); + expect(contains(null, "a")).toBe(false); + expect(contains(123, "a")).toBe(false); + expect(contains("not array", "a")).toBe(false); }); // Given an object with properties From 9d158ec59bfd09284c4b1f3402b0ed3fcfb1a4ca Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Wed, 19 Nov 2025 11:19:09 +0000 Subject: [PATCH 12/17] fixed contains function and contains-test --- Sprint-2/implement/contains.js | 10 ++--- Sprint-2/implement/contains.test.js | 63 +++++++++++++++-------------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index e354f632f..634912f7d 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,16 +1,12 @@ -function contains(obj, key) { +function contains(arr, value) { /** * Checks if the given array contains the specified value. * @param {Array} arr - The array to check. * @param {*} value - The value to search for. * @returns {boolean} - Returns true if the value is found, otherwise false. */ - if (obj === null || typeof obj !== "object" || Array.isArray(obj)) { - return false; - } - - return Object.prototype.hasOwnProperty.call(obj, key); + if (!Array.isArray(arr)) return false; + return arr.includes(value); } module.exports = contains; - diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 94e9dd96f..146d145de 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -17,34 +17,37 @@ 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("contains on empty object returns false", () => { - expect(contains(null, "a")).toBe(false); - expect(contains(123, "a")).toBe(false); - expect(contains("not array", "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, b: 2 }, "a")).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: 2 }, "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); - expect(contains(null, "a")).toBe(false); - expect(contains(undefined, "a")).toBe(false); +describe("contains (array-only version)", () => { + // Given an empty object + // When passed to contains + // Then it should return false + test("returns false for an empty object", () => { + expect(contains({}, "anything")).toBe(false); + }); + + // Given an object with properties + // When passed to contains with an existing property name + // Then it should return false + test("returns false even if object has that property", () => { + expect(contains({ a: 1, b: 2 }, "a")).toBe(false); + }); + + // 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 key on object", () => { + 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 inputs", () => { + expect(contains(null, "a")).toBe(false); + expect(contains(undefined, "a")).toBe(false); + expect(contains(123, "a")).toBe(false); + expect(contains("string", "s")).toBe(false); + expect(contains(true, true)).toBe(false); + }); }); +// Note: The contains function implemented in contains.js only works for arrays. \ No newline at end of file From 83214e4a6db68c95e2862755011db329dba46063 Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Wed, 19 Nov 2025 11:31:57 +0000 Subject: [PATCH 13/17] fixed prototype issue --- 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 434c32cac..80f6bf5f5 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -3,7 +3,7 @@ function tally(items) { throw new Error("Input must be an array"); } - const result = {}; + const result = Object.create(null); // Create a clean object with no prototype for (const item of items) { if (result[item]) { From 5cf0ffbad72fb32e41c75d17ae39bc6407dc9a58 Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Wed, 19 Nov 2025 11:50:01 +0000 Subject: [PATCH 14/17] changed parameter --- Sprint-2/implement/contains.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 634912f7d..6b5c6a99d 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,12 +1,12 @@ -function contains(arr, value) { +function contains(arr, item) { /** * Checks if the given array contains the specified value. * @param {Array} arr - The array to check. - * @param {*} value - The value to search for. + * @param {*} item - The item to search for. * @returns {boolean} - Returns true if the value is found, otherwise false. */ if (!Array.isArray(arr)) return false; - return arr.includes(value); + return arr.includes(item); } module.exports = contains; From 295d8fa34a4542b56e35e7958826aeb18c666e93 Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Wed, 19 Nov 2025 12:42:57 +0000 Subject: [PATCH 15/17] chnaged the contains function --- Sprint-2/implement/contains.js | 22 ++++++---- Sprint-2/implement/contains.test.js | 65 ++++++++++++++--------------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 6b5c6a99d..f02d93a97 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,12 +1,16 @@ -function contains(arr, item) { - /** - * Checks if the given array contains the specified value. - * @param {Array} arr - The array to check. - * @param {*} item - The item to search for. - * @returns {boolean} - Returns true if the value is found, otherwise false. - */ - if (!Array.isArray(arr)) return false; - return arr.includes(item); +// function that checks if a given property exists in an object +function contains(obj, property) { + // Check if the input is a valid object and not null or an array + if ( + typeof obj === "object" && + obj !== null && + !Array.isArray(obj) && + property in obj + ) { + return true; + } else { + return false; + } } module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 146d145de..c3ed0cd2e 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -17,37 +17,36 @@ 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 (array-only version)", () => { - // Given an empty object - // When passed to contains - // Then it should return false - test("returns false for an empty object", () => { - expect(contains({}, "anything")).toBe(false); - }); - - // Given an object with properties - // When passed to contains with an existing property name - // Then it should return false - test("returns false even if object has that property", () => { - expect(contains({ a: 1, b: 2 }, "a")).toBe(false); - }); - - // 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 key on object", () => { - 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 inputs", () => { - expect(contains(null, "a")).toBe(false); - expect(contains(undefined, "a")).toBe(false); - expect(contains(123, "a")).toBe(false); - expect(contains("string", "s")).toBe(false); - expect(contains(true, true)).toBe(false); - }); +// When passed an empty object +// Then it should return false +test("contains on empty object returns false", () => { + const emptyObject = {}; + expect(contains(emptyObject, "key")).toBe(false); }); -// Note: The contains function implemented in contains.js only works for arrays. \ No newline at end of file + +// When passed a non-object value (e.g., array, string, number, null, undefined) +// Then it should return false +test("Checks if an object contains the specified property", () => { + const obj1 = { name: "Alice", age: 30 }; + expect(contains(obj1, "name")).toBe(true); // The property "name" exists + expect(contains(obj1, "city")).toBe(false); // The property "city" does not exist +}); + +// contains({ a: 1, b: 2 }, 'a') // returns true +test("Checks if an object contains the specified property", () => { + const obj1 = { a: 1, b: 2 }; + expect(contains(obj1, "a")).toBe(true); // The property "name" exists +}); + +// contains({ a: 1, b: 2 }, 'c') // returns false +test("Checks if an object contains the specified property", () => { + const obj1 = { a: 1, b: 2 }; + expect(contains(obj1, "c")).toBe(false); // The property "c" does not exist +}); + +// when given an array instead of an object returns false +test(" when given an array instead of an object returns false", () => { + const arrayInput = ["value1", "value2"]; + expect(contains(arrayInput, "key")).toBe(false); // The property "key" does not exist +}); + From 5d258821900ea022fba435eb008b51a8cd5addff Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Thu, 20 Nov 2025 10:05:41 +0000 Subject: [PATCH 16/17] fixed --- Sprint-2/implement/contains.js | 4 ++-- Sprint-2/implement/contains.test.js | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index f02d93a97..780befb78 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -5,8 +5,8 @@ function contains(obj, property) { typeof obj === "object" && obj !== null && !Array.isArray(obj) && - property in obj - ) { + Object.hasOwn(obj, property + )) { return true; } else { return false; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index c3ed0cd2e..3d9042cee 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -32,18 +32,14 @@ test("Checks if an object contains the specified property", () => { expect(contains(obj1, "city")).toBe(false); // The property "city" does not exist }); -// contains({ a: 1, b: 2 }, 'a') // returns true +// contains({ a: 1, b: 2 }, 'a') // returns true and contains({ a: 1, b: 2 }, 'c') // returns false test("Checks if an object contains the specified property", () => { const obj1 = { a: 1, b: 2 }; expect(contains(obj1, "a")).toBe(true); // The property "name" exists -}); - -// contains({ a: 1, b: 2 }, 'c') // returns false -test("Checks if an object contains the specified property", () => { - const obj1 = { a: 1, b: 2 }; expect(contains(obj1, "c")).toBe(false); // The property "c" does not exist }); + // when given an array instead of an object returns false test(" when given an array instead of an object returns false", () => { const arrayInput = ["value1", "value2"]; From 131159ad1e6d1402c1a4315213e520fa120eaf47 Mon Sep 17 00:00:00 2001 From: AdnaanA Date: Thu, 20 Nov 2025 10:06:12 +0000 Subject: [PATCH 17/17] updated --- Sprint-2/implement/contains.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 780befb78..0cfd61835 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -5,8 +5,8 @@ function contains(obj, property) { typeof obj === "object" && obj !== null && !Array.isArray(obj) && - Object.hasOwn(obj, property - )) { + Object.hasOwn(obj, property) + ) { return true; } else { return false;