From 8a1272c3d733e07d4811e19d5b0d566b87621d3b Mon Sep 17 00:00:00 2001 From: Samreen0192 Date: Sun, 26 Jul 2026 01:11:58 +0100 Subject: [PATCH 1/2] Add Module Data Groups Sprint 2 exercises --- Sprint-2/debug/address.js | 4 +- Sprint-2/debug/author.js | 5 +- Sprint-2/debug/recipe.js | 12 +++- Sprint-2/implement/contains.js | 6 +- Sprint-2/implement/contains.test.js | 78 ++++++++++++----------- Sprint-2/implement/lookup.js | 8 ++- Sprint-2/implement/lookup.test.js | 46 +++++--------- Sprint-2/implement/querystring.js | 21 ++++++- Sprint-2/implement/querystring.test.js | 85 +++++++++++--------------- Sprint-2/implement/tally.js | 14 ++++- Sprint-2/implement/tally.test.js | 27 ++++++-- Sprint-2/interpret/invert.js | 12 +++- 12 files changed, 184 insertions(+), 134 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..0516f8de0 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,5 +1,7 @@ // 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... // Fix anything that isn't working @@ -12,4 +14,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address.houseNumber}`); \ No newline at end of file diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..3d8b7645f 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,4 +1,5 @@ // Predict and explain first... +// The for...of loop only works with iterable objects, such as arrays // 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); -} +} \ No newline at end of file diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 6cbdd22cd..094249db5 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,5 +1,13 @@ // Predict and explain first... +//The program will not display the ingredients correctly. Instead, it will show something like: +//bruschetta serves 2 +//ingredients: +//[object Object] + +//The issue is that `recipe` is an object. JavaScript cannot display the whole object inside a string, so it shows `[object Object]`. You need to access the specific values you want, like the ingredients array, and format them separately. + + // This program should log out the title, how many it serves and the ingredients. // Each ingredient should be logged on a new line // How can you fix it? @@ -11,5 +19,5 @@ const recipe = { }; console.log(`${recipe.title} serves ${recipe.serves} - ingredients: -${recipe}`); +ingredients: +${recipe.ingredients.join("\n")}`); \ No newline at end of file diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index cd779308a..963173d04 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,3 +1,5 @@ -function contains() {} +function contains(array, target) { + return array.includes(target); +} -module.exports = contains; +module.exports = contains; \ No newline at end of file diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 326bdb1f2..85da48426 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -1,35 +1,43 @@ -const contains = require("./contains.js"); - -/* -Implement a function called contains that checks an object contains a -particular property - -E.g. contains({a: 1, b: 2}, 'a') // returns true -as the object contains a key of 'a' - -E.g. contains({a: 1, b: 2}, 'c') // returns false -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 - -// 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 + 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", () => { + expect(contains([], [])).toEqual(false); + expect(contains(["a", 1], 1)).toEqual(false); + expect(contains({ a: 1, b: 2 }, ["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); + }); +}); \ No newline at end of file diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index a6746e07f..7d4439d0f 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,5 +1,9 @@ -function createLookup() { - // implementation here +function createLookup(arrayOfArrays) { + const lookup = {}; + for (const array of arrayOfArrays) { + lookup[array[0]] = array[1]; + } + return lookup; } module.exports = createLookup; diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 547e06c5a..1ba2a7efb 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,35 +1,17 @@ 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 - -Acceptance Criteria: - -Given - - An array of arrays representing country code and currency code pairs - e.g. [['US', 'USD'], ['CA', 'CAD']] - -When - - createLookup function is called with the country-currency array as an argument - -Then - - It should return an object where: - - The keys are the country codes - - The values are the corresponding currency codes - -Example -Given: [['US', 'USD'], ['CA', 'CAD']] - -When -createLookup(countryCurrencyPairs) is called - -Then -It should return: - { - 'US': 'USD', - 'CA': 'CAD' - } -*/ +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", + }); + }); +}); \ No newline at end of file diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 45ec4e5f3..8ec5c116a 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -3,14 +3,29 @@ function parseQueryString(queryString) { if (queryString.length === 0) { return queryParams; } + + // Replaces + with space + queryString = queryString.replaceAll("+", " "); const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - const [key, value] = pair.split("="); - queryParams[key] = value; + f (pair !== "") { + let index = pair.indexOf("="); + if (!pair.includes("=")) { + index = pair.length; + } + const rawKey = pair.slice(0, index); + const rawValue = pair.slice(index + 1); + + // Remove percentage-encoded characters + const key = decodeURIComponent(rawKey); + const value = decodeURIComponent(rawValue); + + queryParams[key] = value; + } } return queryParams; } -module.exports = parseQueryString; + diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 328b8df61..4ddbf2fcb 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -1,48 +1,37 @@ -// In the prep, we implemented a function to parse query strings. -// Unfortunately, it contains several bugs! -// 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") - -test("should parse values containing '='", () => { - expect(parseQueryString("equation=a=b-2")).toEqual({ - equation: "a=b-2", - }); -}); - -test("should ignore empty key-value pairs", () => { - expect(parseQueryString("key1=value1&&key2=value2&")).toEqual({ - key1: "value1", - key2: "value2", - }); -}); - -test("should accept empty string as key or as value", () => { - expect(parseQueryString("=value")).toEqual({ "": "value" }); - expect(parseQueryString("key")).toEqual({ key: "" }); - expect(parseQueryString("key=")).toEqual({ key: "" }); - expect(parseQueryString("=")).toEqual({ "": "" }); -}); - -test("should decode percent-encoded characters", () => { - expect(parseQueryString("%24half=1%2F2")).toEqual({ - $half: "1/2", - }); -}); - -test("should replace '+' by ' '", () => { - expect(parseQueryString("full+name=John+Doe")).toEqual({ - "full name": "John Doe", - }); -}); - -// 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", - }); -}); +function parseQueryString(queryString) { + const queryParams = {}; + + if (queryString.length === 0) { + return queryParams; + } + + const keyValuePairs = queryString.split("&"); + + for (const pair of keyValuePairs) { + if (pair === "") { + continue; + } + + const equalIndex = pair.indexOf("="); + + let key; + let value; + + if (equalIndex === -1) { + key = pair; + value = ""; + } else { + key = pair.slice(0, equalIndex); + value = pair.slice(equalIndex + 1); + } + + key = decodeURIComponent(key.replaceAll("+", " ")); + value = decodeURIComponent(value.replaceAll("+", " ")); + + queryParams[key] = value; + } + + return queryParams; +} + +module.exports = parseQueryString; \ No newline at end of file diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index f47321812..9e407c456 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,3 +1,13 @@ -function tally() {} - +function tally(array) { + if (!Array.isArray(array)) { + throw new Error("Invalid array"); + } + const count = Object.create(null); + array.forEach((item) => { + if (item in count) { + count[item] += 1; + } else count[item] = 1; + }); + return count; +} module.exports = tally; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 2ceffa8dd..38f2fd2a4 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -20,15 +20,34 @@ const tally = require("./tally.js"); // 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"); +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", () => { + 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", () => { + expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 1 }); + expect(tally(["toString", "toString"])).toEqual({ toString: 2 }); + }); + + + // 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"); + }); +}); \ No newline at end of file diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index bb353fb1f..29b855cc0 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; } + // 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 From 246d9748dcc077ab18d57df4af25166b7bf4975a Mon Sep 17 00:00:00 2001 From: Samreen0192 Date: Sun, 26 Jul 2026 01:24:03 +0100 Subject: [PATCH 2/2] Add alarm clock exercise --- Sprint-2/debug/address.js | 4 +- Sprint-2/debug/author.js | 5 +- Sprint-2/debug/recipe.js | 12 +--- Sprint-2/implement/contains.js | 6 +- Sprint-2/implement/contains.test.js | 78 +++++++++++------------ Sprint-2/implement/lookup.js | 8 +-- Sprint-2/implement/lookup.test.js | 46 +++++++++----- Sprint-2/implement/querystring.js | 21 +------ Sprint-2/implement/querystring.test.js | 85 +++++++++++++++----------- Sprint-2/implement/tally.js | 14 +---- Sprint-2/implement/tally.test.js | 27 ++------ Sprint-2/interpret/invert.js | 12 +--- Sprint-3/alarmclock/alarmclock.js | 4 +- Sprint-3/alarmclock/index.html | 4 +- 14 files changed, 139 insertions(+), 187 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 0516f8de0..940a6af83 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -1,7 +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... // Fix anything that isn't working @@ -14,4 +12,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address.houseNumber}`); \ No newline at end of file +console.log(`My house number is ${address[0]}`); diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 3d8b7645f..8c2125977 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -1,5 +1,4 @@ // Predict and explain first... -// The for...of loop only works with iterable objects, such as arrays // 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 @@ -12,6 +11,6 @@ const author = { alive: true, }; -for (const value of Object.values(author)) { +for (const value of author) { console.log(value); -} \ No newline at end of file +} diff --git a/Sprint-2/debug/recipe.js b/Sprint-2/debug/recipe.js index 094249db5..6cbdd22cd 100644 --- a/Sprint-2/debug/recipe.js +++ b/Sprint-2/debug/recipe.js @@ -1,13 +1,5 @@ // Predict and explain first... -//The program will not display the ingredients correctly. Instead, it will show something like: -//bruschetta serves 2 -//ingredients: -//[object Object] - -//The issue is that `recipe` is an object. JavaScript cannot display the whole object inside a string, so it shows `[object Object]`. You need to access the specific values you want, like the ingredients array, and format them separately. - - // This program should log out the title, how many it serves and the ingredients. // Each ingredient should be logged on a new line // How can you fix it? @@ -19,5 +11,5 @@ const recipe = { }; console.log(`${recipe.title} serves ${recipe.serves} -ingredients: -${recipe.ingredients.join("\n")}`); \ No newline at end of file + ingredients: +${recipe}`); diff --git a/Sprint-2/implement/contains.js b/Sprint-2/implement/contains.js index 963173d04..cd779308a 100644 --- a/Sprint-2/implement/contains.js +++ b/Sprint-2/implement/contains.js @@ -1,5 +1,3 @@ -function contains(array, target) { - return array.includes(target); -} +function contains() {} -module.exports = contains; \ No newline at end of file +module.exports = contains; diff --git a/Sprint-2/implement/contains.test.js b/Sprint-2/implement/contains.test.js index 85da48426..326bdb1f2 100644 --- a/Sprint-2/implement/contains.test.js +++ b/Sprint-2/implement/contains.test.js @@ -1,43 +1,35 @@ -describe("contains", () => { - // 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); - }); - - // 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], 1)).toEqual(false); - expect(contains({ a: 1, b: 2 }, ["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); - }); -}); \ No newline at end of file +const contains = require("./contains.js"); + +/* +Implement a function called contains that checks an object contains a +particular property + +E.g. contains({a: 1, b: 2}, 'a') // returns true +as the object contains a key of 'a' + +E.g. contains({a: 1, b: 2}, 'c') // returns false +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 + +// 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 diff --git a/Sprint-2/implement/lookup.js b/Sprint-2/implement/lookup.js index 7d4439d0f..a6746e07f 100644 --- a/Sprint-2/implement/lookup.js +++ b/Sprint-2/implement/lookup.js @@ -1,9 +1,5 @@ -function createLookup(arrayOfArrays) { - const lookup = {}; - for (const array of arrayOfArrays) { - lookup[array[0]] = array[1]; - } - return lookup; +function createLookup() { + // implementation here } module.exports = createLookup; diff --git a/Sprint-2/implement/lookup.test.js b/Sprint-2/implement/lookup.test.js index 1ba2a7efb..547e06c5a 100644 --- a/Sprint-2/implement/lookup.test.js +++ b/Sprint-2/implement/lookup.test.js @@ -1,17 +1,35 @@ 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", - }); - }); -}); \ No newline at end of file +/* + +Create a lookup object of key value pairs from an array of code pairs + +Acceptance Criteria: + +Given + - An array of arrays representing country code and currency code pairs + e.g. [['US', 'USD'], ['CA', 'CAD']] + +When + - createLookup function is called with the country-currency array as an argument + +Then + - It should return an object where: + - The keys are the country codes + - The values are the corresponding currency codes + +Example +Given: [['US', 'USD'], ['CA', 'CAD']] + +When +createLookup(countryCurrencyPairs) is called + +Then +It should return: + { + 'US': 'USD', + 'CA': 'CAD' + } +*/ diff --git a/Sprint-2/implement/querystring.js b/Sprint-2/implement/querystring.js index 8ec5c116a..45ec4e5f3 100644 --- a/Sprint-2/implement/querystring.js +++ b/Sprint-2/implement/querystring.js @@ -3,29 +3,14 @@ function parseQueryString(queryString) { if (queryString.length === 0) { return queryParams; } - - // Replaces + with space - queryString = queryString.replaceAll("+", " "); const keyValuePairs = queryString.split("&"); for (const pair of keyValuePairs) { - f (pair !== "") { - let index = pair.indexOf("="); - if (!pair.includes("=")) { - index = pair.length; - } - const rawKey = pair.slice(0, index); - const rawValue = pair.slice(index + 1); - - // Remove percentage-encoded characters - const key = decodeURIComponent(rawKey); - const value = decodeURIComponent(rawValue); - - queryParams[key] = value; - } + const [key, value] = pair.split("="); + queryParams[key] = value; } return queryParams; } - +module.exports = parseQueryString; diff --git a/Sprint-2/implement/querystring.test.js b/Sprint-2/implement/querystring.test.js index 4ddbf2fcb..328b8df61 100644 --- a/Sprint-2/implement/querystring.test.js +++ b/Sprint-2/implement/querystring.test.js @@ -1,37 +1,48 @@ -function parseQueryString(queryString) { - const queryParams = {}; - - if (queryString.length === 0) { - return queryParams; - } - - const keyValuePairs = queryString.split("&"); - - for (const pair of keyValuePairs) { - if (pair === "") { - continue; - } - - const equalIndex = pair.indexOf("="); - - let key; - let value; - - if (equalIndex === -1) { - key = pair; - value = ""; - } else { - key = pair.slice(0, equalIndex); - value = pair.slice(equalIndex + 1); - } - - key = decodeURIComponent(key.replaceAll("+", " ")); - value = decodeURIComponent(value.replaceAll("+", " ")); - - queryParams[key] = value; - } - - return queryParams; -} - -module.exports = parseQueryString; \ No newline at end of file +// In the prep, we implemented a function to parse query strings. +// Unfortunately, it contains several bugs! +// 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") + +test("should parse values containing '='", () => { + expect(parseQueryString("equation=a=b-2")).toEqual({ + equation: "a=b-2", + }); +}); + +test("should ignore empty key-value pairs", () => { + expect(parseQueryString("key1=value1&&key2=value2&")).toEqual({ + key1: "value1", + key2: "value2", + }); +}); + +test("should accept empty string as key or as value", () => { + expect(parseQueryString("=value")).toEqual({ "": "value" }); + expect(parseQueryString("key")).toEqual({ key: "" }); + expect(parseQueryString("key=")).toEqual({ key: "" }); + expect(parseQueryString("=")).toEqual({ "": "" }); +}); + +test("should decode percent-encoded characters", () => { + expect(parseQueryString("%24half=1%2F2")).toEqual({ + $half: "1/2", + }); +}); + +test("should replace '+' by ' '", () => { + expect(parseQueryString("full+name=John+Doe")).toEqual({ + "full name": "John Doe", + }); +}); + +// 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", + }); +}); diff --git a/Sprint-2/implement/tally.js b/Sprint-2/implement/tally.js index 9e407c456..f47321812 100644 --- a/Sprint-2/implement/tally.js +++ b/Sprint-2/implement/tally.js @@ -1,13 +1,3 @@ -function tally(array) { - if (!Array.isArray(array)) { - throw new Error("Invalid array"); - } - const count = Object.create(null); - array.forEach((item) => { - if (item in count) { - count[item] += 1; - } else count[item] = 1; - }); - return count; -} +function tally() {} + module.exports = tally; diff --git a/Sprint-2/implement/tally.test.js b/Sprint-2/implement/tally.test.js index 38f2fd2a4..2ceffa8dd 100644 --- a/Sprint-2/implement/tally.test.js +++ b/Sprint-2/implement/tally.test.js @@ -20,34 +20,15 @@ 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 - it("tally on an empty array returns an empty object", () => { - const array = []; - expect(tally(array)).toEqual({}); - }); +// 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 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", () => { - expect(tally(["a", "a", "b", "c"])).toEqual({ a: 2, b: 1, c: 1 }); - expect(tally(["toString", "toString"])).toEqual({ toString: 2 }); - }); - - - // 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"); - }); -}); \ No newline at end of file diff --git a/Sprint-2/interpret/invert.js b/Sprint-2/interpret/invert.js index 29b855cc0..bb353fb1f 100644 --- a/Sprint-2/interpret/invert.js +++ b/Sprint-2/interpret/invert.js @@ -10,30 +10,20 @@ function invert(obj) { const invertedObj = {}; for (const [key, value] of Object.entries(obj)) { - invertedObj[value] = key; + invertedObj.key = value; } 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-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 6ca81cd3b..d4101d8cf 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,4 +1,6 @@ -function setAlarm() {} +function setAlarm() { + playAlarm(); +} // DO NOT EDIT BELOW HERE diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/index.html index 48e2e80d9..dd62d4acc 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/index.html @@ -1,10 +1,10 @@ - + - Title here + Alaram close app