Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ const address = {
country: "England",
postcode: "XYZ 123",
};
// not an array so an index number doesn't work
console.log(`My house number is ${address.houseNumber}`);


console.log(`My house number is ${address[0]}`);
3 changes: 2 additions & 1 deletion Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const author = {
alive: true,
};

for (const value of author) {
for (const value of Object.values(author)) {
console.log(value);
}
//"author" is not iterable. for...of is for arrays, not for objects
5 changes: 4 additions & 1 deletion Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ const recipe = {

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

// the ${recipe} tries to log everything into one string (and fails).
// used join to list them separately and on new lines
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(obj, property) {
if (Array.isArray(obj) || typeof obj !== "object" || obj === null) {
return false;
}
return obj.hasOwnProperty(property);
}

module.exports = contains;
14 changes: 13 additions & 1 deletion Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,28 @@ 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 an empty object returns false", () => {
expect(contains({}, "a")).toEqual(false);
});

// Given an object with properties
// When passed to contains with an existing property name
// Then it should return true
test("given an object with properties, returns true for existing property", () => {
expect(contains({a: 1, b: 2}, "a")).toEqual(true);
});

// Given an object with properties
// When passed to contains with a non-existent property name
// Then it should return false
test("given an object with properties, returns false for non-existent property", () => {
expect(contains({a: 1, b: 2}, "c")).toEqual(false);
});

// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error
test("given invalid parameters like an array, returns false", () => {
expect(contains([1, 2, 3], "a")).toEqual(false);
});
Comment on lines 42 to +47
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your function is correct, but we should prepare tests not only to verify our current implementation, but also to ensure that future changes do not alter the function's expected behavior.

This test cannot yet confirm that the function correctly returns false when the first argument is an array.
This is because contains([1, 2, 3], "a") could also return false simply because "a" is not a key of the array.

Arrays are objects, with their indices acting as keys. A proper test should use a valid key to ensure the function returns false specifically because the input is an array, not because the key is missing.

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(pairs) {
const lookup = {};
for (const [country, currency] of pairs) {
lookup[country] = currency;
}
return lookup;
}

module.exports = createLookup;
27 changes: 25 additions & 2 deletions Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
const createLookup = require("./lookup.js");

test.todo("creates a country currency code lookup for multiple codes");

test("returns an empty object for an empty array", () => {
expect(createLookup([])).toEqual({});
});

test("creates a country currency code lookup for multiple codes", () => {
expect(createLookup([['US', 'USD'], ['CA', 'CAD']])).toEqual({
'US': 'USD',
'CA': 'CAD'
});
});

test("creates a lookup for a single pair", () => {
expect(createLookup([['GB', 'GBP']])).toEqual({ 'GB': 'GBP' });
});

test("creates a lookup for multiple European countries with EUR", () => {
expect(createLookup([['NLD', 'EUR'], ['GER', 'EUR'], ['BEL', 'EUR'], ['FRA', 'EUR'], ['ESP', 'EUR'], ['POR', 'EUR']])).toEqual({
'NLD': 'EUR',
'GER': 'EUR',
'BEL': 'EUR',
'FRA': 'EUR',
'ESP': 'EUR',
'POR': 'EUR'
});
});
/*

Create a lookup object of key value pairs from an array of code pairs
Expand Down
4 changes: 3 additions & 1 deletion Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ function parseQueryString(queryString) {
const keyValuePairs = queryString.split("&");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
const index = pair.indexOf("=");
const key = pair.slice(0, index);
const value = pair.slice(index + 1);
Comment on lines +9 to +11
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For each of the following function calls, does your function return the value you expect?
Note: These arguments are valid query strings.

parseQueryString("key1=value1&=&key2=value2")
parseQueryString("key=")                                   
parseQueryString("key1=value1&key2")
parseQueryString("=value")
parseQueryString("key1=value1&&key2=value2")

queryParams[key] = value;
}

Expand Down
23 changes: 21 additions & 2 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ const parseQueryString = require("./querystring.js")

test("parses querystring values containing =", () => {
expect(parseQueryString("equation=x=y+1")).toEqual({
"equation": "x=y+1",
});
"equation": "x=y+1" });
});

test("parses empty querystring", () => {
expect(parseQueryString("")).toEqual({});
});

test("parses querystring with empty value", () => {
expect(parseQueryString("name=")).toEqual({ name: "" });
});

test("parses querystring values containing =", () => {
expect(parseQueryString("equation=x=y+1")).toEqual({ equation: "x=y+1" });
});

test("parses single key value pair", () => {
expect(parseQueryString("name=Ntombi")).toEqual({ name: "Ntombi" });
});

test("parses multiple key value pairs", () => {
expect(parseQueryString("name=Ntombi&age=40")).toEqual({ name: "Ntombi", age: "40" });
});
15 changes: 14 additions & 1 deletion Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
function tally() {}
function tally(arr) {
if (!Array.isArray(arr)) {
throw new Error("Input must be an array");
}
const result = {};
for (const item of arr) {
if (result[item]) {
result[item]++;
} else {
result[item] = 1;
}
}
Comment on lines +5 to +12
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the following function call returns the value you expect?

tally(["toString", "toString"]);

Suggestion:

  • Look up an approach to create an empty object with no inherited properties, or
  • use Object.hasOwn() to check if result contains a specific key/item

return result;
}

module.exports = tally;
14 changes: 13 additions & 1 deletion Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@ const tally = require("./tally.js");
// 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({});
});

test("given an array with one item, returns count of 1", () => {
expect(tally(['a'])).toEqual({ a: 1 });
});

// Given an array with duplicate items
// When passed to tally
// Then it should return counts for each unique item
test("tally on an array with duplicate items returns counts for each type", () => {
expect(tally(['a', 'a', 'b', 'c'])).toEqual({ a: 2, b: 1, c: 1 });
});

// Given an invalid input like a string
// When passed to tally
// Then it should throw an error
test("given an invalid input like a string, throws an error", () => {
expect(() => tally("invalid")).toThrow();
});
39 changes: 32 additions & 7 deletions Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,49 @@

// E.g. invert({x : 10, y : 20}), target output: {"10": "x", "20": "y"}

function invert(obj) {
const invertedObj = {};
// leaving original code in for easier referral:

for (const [key, value] of Object.entries(obj)) {
invertedObj.key = value;
}
// function invert(obj) {
// const invertedObj = {};
//
// for (const [key, value] of Object.entries(obj)) {
// invertedObj.key = value;
// }
//
// return invertedObj;
//}

return invertedObj;
}

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

// b) What is the current return value when invert is called with { a: 1, b: 2 }
// the current return value is {key : 2} because the key is overwritten and
// only the last value is stored

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

// c) What does Object.entries return? Why is it needed in this program?
// Object.entries converts an object into an array of [key, value] pairs. it is needed because
// for...of needs an array to work with

// d) Explain why the current return value is different from the target output
// invertedObj.key = value creates a literal string with the name "key" instead of the value key.
// also, the current code assigns "value" to the new property instead of "key"

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

function invert(obj) {
const invertedObj = {};

for (const [key, value] of Object.entries(obj)) {
invertedObj[value] = key;
}

return invertedObj;
}

// Tests
console.log(invert({ a: 1 })); // Expected output: { "1": "a" }
console.log(invert({ a: 1, b: 2 })); // Expected output: { "1": "a", "2": "b" }
Loading