Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
@@ -1,4 +1,6 @@
// Predict and explain first...
/* To specify house number the console.log should use. address.houseNumber.
without it, It would show as undefined */

// This code should log out the houseNumber from the address object
// but it isn't working...
Expand All @@ -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}`);
10 changes: 9 additions & 1 deletion Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
// 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

/* The code wants to log the property value and is using a for...of loop
to make sure it logs everything, however Objects aren't in order and Javascript
doesn't know what you want. Author is an Object and objects are not
iterable which is the error. To fix this change (const value of author) to
(const value of object.values(author)) to specify we want the values (not properties)
in the Object which is 'author'. Using a loop allows up to add information in author
without needing to make changes anywhere else while getting an updated log */

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

for (const value of author) {
for (const value of Object.values(author)) {
console.log(value);
}
12 changes: 9 additions & 3 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// Predict and explain first...
/* In the console.log the {recipe} doesn't specify ingredients so it will
show up as undefined. Changing it to {recipe.ingredients} should fix that issue.
To log each ingredient on a new line you can use (.join("\n")) which
separate the code by line */


// This program should log out the title, how many it serves and the ingredients.
// Each ingredient should be logged on a new line
Expand All @@ -10,6 +15,7 @@ const recipe = {
ingredients: ["olive oil", "tomatoes", "salt", "pepper"],
};

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nice logic here

8 changes: 7 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
function contains() {}
function contains(object, property) {
if (Array.isArray(object)) {
throw new Error("Invalid parameter");
}

return property in object;
}

module.exports = contains;
21 changes: 20 additions & 1 deletion Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,39 @@ as the object doesn't contains a key of 'c'
// 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
test("contains a passed object should return true, false otherwise",() => {
expect(contains({a: 1, b: 2}, 2)).toEqual(false);
expect(contains({a: 1, b: 2}, 'b')).toEqual(true);
});

// 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({})).toEqual(false);
});

// Given an object with properties
// When passed to contains with an existing property name
// Then it should return true
test("contains object with properties, return true when passed with existing property name",() => {
expect(contains({name: 'alice'}, 'name')).toEqual(true);
});


// Given an object with properties
// When passed to contains with a non-existent property name
// Then it should return false
test("contains a passed object with non-existent property names return false",() => {
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("contains passed invalid parameters like an array to throw error", () => {
expect(() => contains(['horse', 'dog', 'fish'], 'fish'))
.toThrow("Invalid parameter");
});

10 changes: 8 additions & 2 deletions Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
function createLookup() {
// implementation here
function createLookup(countryCurrencyPairs) {
const lookup = {};

countryCurrencyPairs.forEach((pair) => {
lookup[pair[0]] = pair[1];
});

return lookup;
}

module.exports = createLookup;
14 changes: 13 additions & 1 deletion Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
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 countryCurrencyPairs = [
["US", "USD"],
["CA", "CAD"],
["EN", "GBP"],
];

expect(createLookup(countryCurrencyPairs)).toEqual({
US: "USD",
CA: "CAD",
EN: "GBP",
});
});

/*

Expand Down
14 changes: 12 additions & 2 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@ function parseQueryString(queryString) {
if (queryString.length === 0) {
return queryParams;
}
const keyValuePairs = queryString.split("&");
let keyValuePairs = queryString.split("&");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
if (!pair) continue; // continue is to skip empty strings
let [key, ...values] = pair.split("=");

key = decodeURIComponent(key.replace(/\+/g, " "));
const value = decodeURIComponent(values.join("=").replace(/\+/g, " "));

/* decodeURIComponent function decodes percent encoded characters
"replace" swaps one character with another
(/../) means the begining and end of a regex pattern (better for characters)
'\+' is an escaped '+' because it has its own function in coding */

queryParams[key] = value;
}

Expand Down
5 changes: 3 additions & 2 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ test("should decode percent-encoded characters", () => {
});
});

test("should replace '+' by ' '", () => {
test("should replace '+' by ' '", () => {
expect(parseQueryString("full+name=John+Doe")).toEqual({
"full name": "John Doe",
});
});

// Stretch exercise: Handling query strings that contain identical keys
/* 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", () => {
Expand All @@ -46,3 +46,4 @@ test("should store values of a key in an array when the key has 2 or more values
foo: "bar",
});
});
*/
22 changes: 21 additions & 1 deletion Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
function tally() {}
function tally(array) {
if (!Array.isArray(array)) {
throw new Error("Input must be an array");
}

if (array.length === 0) {
return {};
}

const result = {};

for (const item of array) {
if (result[item]) {
result[item]++;
} else {
result[item] = 1;
}
}

return result;
}

module.exports = tally;
13 changes: 12 additions & 1 deletion Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,27 @@ const tally = require("./tally.js");
// 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 should return an count of each item passed through an array ", () => {
expect(tally(["a", "b", "c"])).toEqual({ a: 1, 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 on an array with duplicate items return a count for each item ", () => {
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("tally with a invalid string should throw an error", () => {
expect(() => tally("car")).toThrow("Input must be an array");
});
11 changes: 9 additions & 2 deletions Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,29 @@

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?
// Object Entries return an array of key value pairs and it's needed so the for...of loop goes through each key and value individually

// d) Explain why the current return value is different from the target output
// The current return value only shows {key: 2}. It doesn't show the first key and value only the second,
// and it doesn't specify the second key. Its just defined as 'key'. It also doesn't swap the key and value around as intended

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This part is missing - your current test suite doesn't correctly test the behaviour of invert - check the example given in the top comment above again. You also haven't built the test suite up - start with a small example and build up to a bigger object. Please amend


module.exports = invert;
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("when passed invert swaps single key-value pair", () => {
expect(invert({ a: 1 })).toEqual({ "1": "a" });
});

test("When invert is passed, multiple keys and values in the object should be swapped ", () => {
expect(invert({ x: 10, y: 20 })).toEqual({ "10": "x", "20": "y" })
});

test("when passed invert swaps string values", () => {
expect(invert({ first: "hello",second: "world" })).toEqual({ hello: "first", world: "second" });
});
Loading