Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
8531191
object prep
MattCarolus10 Nov 5, 2026
037311d
fix houseNumber error
MattCarolus10 Nov 6, 2026
13f83e1
fix author object iteration
MattCarolus10 Nov 6, 2026
3d72ba1
add tests for parseQueryString function to validate query string parsing
MattCarolus10 Nov 6, 2026
454659b
add function to double all numbers in an array
MattCarolus10 Nov 6, 2026
af702ab
fix formatting in address.js comments for clarity
MattCarolus10 Nov 6, 2026
e6ed80a
fix recipe logging to display ingredients correctly
MattCarolus10 Nov 6, 2026
e80fd6f
fix comments in recipe.js to clarify logging functionality
MattCarolus10 Nov 6, 2026
74c65b7
implement test for contains function to check empty object case
MattCarolus10 Nov 6, 2026
c61f58e
implement contains function to check if property exists in object
MattCarolus10 Nov 6, 2026
438293b
refactor contains.test.js to improve test structure and formatting
MattCarolus10 Nov 6, 2026
4e217bc
add test for contains function to verify behavior with missing property
MattCarolus10 Nov 6, 2026
b72528b
add test to ensure contains function throws error for array input
MattCarolus10 Nov 6, 2026
e8cf923
refactor contains function to validate input type before checking pro…
MattCarolus10 Nov 6, 2026
8e89f1d
remove redundant comments and acceptance criteria from contains.test.js
MattCarolus10 Nov 6, 2026
c39280d
implement test for createLookup function to validate country-currency…
MattCarolus10 Nov 6, 2026
80034ab
fix: update test to validate correct output for createLookup function
MattCarolus10 Nov 6, 2026
8c1878d
implement createLookup function to map country-currency pairs
MattCarolus10 Nov 6, 2026
62d2398
refactor: improve formatting of createLookup test and remove redundan…
MattCarolus10 Nov 6, 2026
b1fdc4d
refactor: simplify parseQueryString function by removing redundant ch…
MattCarolus10 Nov 6, 2026
05ccd8c
refactor: clean up parseQueryString function by removing unnecessary …
MattCarolus10 Nov 6, 2026
fe222e0
fix: correct value assignment in parseQueryString and decode URI comp…
MattCarolus10 Nov 6, 2026
89d8fda
fix: decode URI components in parseQueryString function
MattCarolus10 Nov 6, 2026
17adfe9
fix: decode URI components in parseQueryString function
MattCarolus10 Nov 6, 2026
4918e85
refactor: improve key and value decoding in parseQueryString function
MattCarolus10 Nov 6, 2026
f573273
test: add test for handling empty query string
MattCarolus10 Nov 6, 2026
05ee028
test: add test for handling values with both + and percent-encoding
MattCarolus10 Nov 6, 2026
15fe829
test: implement test for tally function with an empty array
MattCarolus10 Nov 6, 2026
8eb4f2d
test: fix indentation in tally test cases
MattCarolus10 Nov 6, 2026
967cdf6
test: add assertion for counting unique items in tally function
MattCarolus10 Nov 6, 2026
1492450
test: add tests for handling invalid input in tally function
MattCarolus10 Nov 6, 2026
d2fb260
refactor: remove unnecessary comments and documentation from tally te…
MattCarolus10 Nov 6, 2026
77dc8de
feat: implement tally function to count occurrences in an array
MattCarolus10 Nov 6, 2026
5cb05ee
fix: correct condition to check if input is an array in tally function
MattCarolus10 Nov 6, 2026
ef80285
fix: correct implementation of invert function to properly swap keys …
MattCarolus10 Nov 6, 2026
d2795ff
fix: update module export for invert function
MattCarolus10 Nov 6, 2026
6eff4d9
fix: update comments in invert function to clarify expected behavior …
MattCarolus10 Nov 6, 2026
ad4efb5
test: add unit test for invert function to verify key-value swapping
MattCarolus10 Nov 6, 2026
e18c645
fix: add missing newline and correct syntax in invert test cases
MattCarolus10 Nov 6, 2026
3deb65c
fix: correct formatting and add missing newline in invert test cases
MattCarolus10 Nov 6, 2026
8ad6494
test: add unit test for handling empty object in invert function
MattCarolus10 Nov 6, 2026
4476d4a
fix: correct expected output for key-value swapping test case
MattCarolus10 Nov 6, 2026
5ab6b3e
Remove prep files from sprint branch
MattCarolus10 Nov 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Predict and explain first...

// This code should log out the houseNumber from the address object
// but it isn't working...
// Fix anything that isn't working
// Answer:
// The address in the code is an object not an array,
// it wont log out because we try to use the array syntax instead of the object syntax

const address = {
houseNumber: 42,
Expand All @@ -12,4 +12,4 @@ const address = {
postcode: "XYZ 123",
};

console.log(`My house number is ${address[0]}`);
console.log(`My house number is ${address.houseNumber}`);
6 changes: 3 additions & 3 deletions Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Predict and explain 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
// Answer:
// A plain object is not iterable, so 'for...of cannot loop over author directly

const author = {
firstName: "Zadie",
Expand All @@ -11,6 +11,6 @@ const author = {
alive: true,
};

for (const value of author) {
for (const value of Object.values(author)) {
console.log(value);
}
8 changes: 4 additions & 4 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Predict and explain first...

// 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?
// The program won't print the ingredients because it wasn't called on line 14


const recipe = {
title: "bruschetta",
Expand All @@ -12,4 +11,5 @@ const recipe = {

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
${recipe.ingredients.join("\n")}`);

7 changes: 6 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
function contains() {}
function contains(object, property) {
if (typeof object !== "object" || object === null || Array.isArray(object)) {
throw new Error("contains requires an object");
}
return property in object;
}

module.exports = contains;
47 changes: 12 additions & 35 deletions Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,17 @@
const contains = require("./contains.js");

/*
Implement a function called contains that checks an object contains a
particular property
test("contains on empty object returns false", () => {
expect(contains({}, "a")).toBe(false);
});

E.g. contains({a: 1, b: 2}, 'a') // returns true
as the object contains a key of 'a'
test("contains an object with existing property, return true", () => {
expect(contains({ a: 1, b: 2 }, "a")).toBe(true);
});

E.g. contains({a: 1, b: 2}, 'c') // returns false
as the object doesn't contains a key of 'c'
test("contains an object with missing property, return false", () => {
expect(contains({ a: 1, b: 2 }, "c")).toBe(false);
});

E.g. contains([1, 2, 3], 'a') throws Error("contains requires an object")
as an array isn't an object
*/

// 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 a value that isn't an object - an array, a string, a number,
// null, or no argument at all
// When passed to contains
// Then it should throw Error("contains requires an object")
// (careful: typeof [] and typeof null are both "object")
test("contains throws for an array", () => {
expect(() => contains([1, 2, 3], "a")).toThrow("contains requires an object");
});
8 changes: 6 additions & 2 deletions Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
function createLookup() {
// implementation here
function createLookup(countryCurrencyPairs) {
const lookup = {};
for (const [country, currency] of countryCurrencyPairs) {
lookup[country] = currency;
}
return lookup
}

module.exports = createLookup;
41 changes: 8 additions & 33 deletions Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
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'
}
*/
test("creates a country currency code lookup for multiple codes", () => {
expect(
createLookup([
["US", "USD"],
["CA", "CAD"],
])
).toEqual({ US: "USD", CA: "CAD" });
});
27 changes: 19 additions & 8 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
function parseQueryString(queryString) {
const queryParams = {};
if (queryString.length === 0) {
return queryParams;
}
const keyValuePairs = queryString.split("&");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
queryParams[key] = value;
}
for (const pair of queryString.split("&")) {
if (pair === "") continue;

const eq = pair.indexOf("=");
const key = eq === -1 ? pair : pair.slice(0, eq);
const value = eq === -1 ? "" : pair.slice(eq + 1);

const k = decodeURIComponent(key.split("+").join(" "));
const v = decodeURIComponent(value.split("+").join(" "));

if (k in queryParams) {
if (Array.isArray(queryParams[k])) {
queryParams[k].push(v);
} else {
queryParams[k] = [queryParams[k], v];
}
} else {
queryParams[k] = v;
}
}
return queryParams;
}

Expand Down
11 changes: 8 additions & 3 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,17 @@ 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",
});
});

test("returns an empty query string", () => {
expect(parseQueryString("")).toEqual({});
});

test("handles a value with both + and percent-encoding", () => {
expect(parseQueryString("q=a+b%26c")).toEqual({q: "a b&c"});
});
13 changes: 12 additions & 1 deletion Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
function tally() {}
function tally(list) {
if (!Array.isArray(list)) {
throw new Error("tally requires an array");
}

const counts = {};

for (const item of list) {
counts[item] = (counts[item] || 0) + 1;
}
return counts;
}

module.exports = tally;
41 changes: 12 additions & 29 deletions Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,17 @@
const tally = require("./tally.js");

/**
* tally array
*
* In this task, you'll need to implement a function called tally
* that will take a list of items and count the frequency of each item
* in an array
*
* For example:
*
* tally(['a']), target output: { a: 1 }
* tally(['a', 'a', 'a']), target output: { a: 3 }
* tally(['a', 'a', 'b', 'c']), target output: { a : 2, b: 1, c: 1 }
*/

// Acceptance criteria:
test("tally on an empty array returns an empty object", () => {
expect(tally([])).toEqual({});
});

// Given a function called tally
// When passed an array of items
// Then it should return an object containing the count for each unique item
test("tally counts duplicate items", () => {
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");

// Given an array with duplicate items
// When passed to tally
// Then it should return counts for each unique item

// Given an invalid input like a string, a number, or no argument at all
// When passed to tally
// Then it should throw Error("tally requires an array")
test("tally throws for invalid input", () => {
expect(() => tally("banana")).toThrow("tally requires an array");
expect(() => tally(42)).toThrow("tally requires an array");
expect(() => tally()).toThrow("tally requires an array");
});
17 changes: 16 additions & 1 deletion Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,35 @@ 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 }

// Answer: {key: 1}

// b) What is the current return value when invert is called with { a: 1, b: 2 }

// Answer: {key: 2}

// c) What is the target return value when invert is called with {a : 1, b: 2}

// Answer: target is {"1": "a", "2": "b"}

// c) What does Object.entries return? Why is it needed in this program?

// Answer: Object.entries returns an array of [key, value] pairs, like [["a", 1]], ["b", 2], so the loop can grab both at once

// d) Explain why the current return value is different from the target output

// Answer: invertedObj.key = value writes a property literally named "key" on -
// every pass, so each pairs overwrites the same one and only the last value survives

// e) Fix the implementation of invert (and write tests to prove it's fixed!)

// Answer: use brackets so the value becomes the new key: invertedObj[value] = key
13 changes: 13 additions & 0 deletions Sprint-2/interpret/invert.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const invert = require("./invert.js");

test("swaps key with values", () => {
expect(invert({ x: 10, y: 20 })).toEqual({ 10: "x", 20: "y" });
});

test("handles single entry", () => {
expect(invert({ a: 1 })).toEqual({ 1: "a" });
});

test("handles an empty object", () => {
expect(invert({})).toEqual({});
});
Loading