Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 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
5 changes: 4 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// Predict and explain first...

// address[0] will not work here as we have an object of key-value pairs. instead of square bracket notation we need the dot notation with the key
// I would think it returns undefined.

// This code should log out the houseNumber from the address object
// but it isn't working...
// Fix anything that isn't working
Expand All @@ -12,4 +15,4 @@ const address = {
postcode: "XYZ 123",
};

console.log(`My house number is ${address[0]}`);
console.log(`My house number is ${address.houseNumber}`);
13 changes: 10 additions & 3 deletions Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
// Predict and explain first...
// author is an object. It cannot be accessed through its values, maybe through its key, value pairs instead of "value" -

//update on explanation: objects could be accessed through 3 methods, depending on whether we want the property name or property value, or the pair. :
//1. Object.keys() collects into an array the keys (property names) ignoring the values
//2. Object.values() collects into an array the values ignoring the property names
//3. Object.entries() collects an array of arrays of key-value pairs

// 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
Expand All @@ -11,6 +17,7 @@ const author = {
alive: true,
};

for (const value of author) {
console.log(value);
}
console.log(Object.values(author));
// for (const value of author) {
// console.log(value);
// }
21 changes: 18 additions & 3 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Predict and explain first...
//in the template literal the ${recipe}`is referring to the whole object, we want the items in the ingredients of the recipe object, listed line 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 +11,20 @@ const recipe = {
ingredients: ["olive oil", "tomatoes", "salt", "pepper"],
};

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
// const recipeKeys = Object.keys(recipe)
// // console.log(recipeKeys)

const recipeValues = Object.values(recipe);
// ["bruschetta", 2, ["olive oil", "tomatoes", "salt", "pepper"]]

const ingredients = recipeValues.slice(-1)[0];
// ["olive oil","tomatoes","salt","pepper"]

//create a function to log line by line the elements of an array
function logItemised(items) {
return items.join("\n");
}

console.log(
`${recipe.title} serves ${recipe.serves}${"\n"}ingredients:${"\n"}${logItemised(ingredients)}`
);
23 changes: 22 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
function contains() {}
function contains(object, propertyName) {
if (typeof object !== "object" || object === null || Array.isArray(object)) {
throw new Error("Input should be an object");
}
const keysInObject = Object.keys(object);
if (keysInObject.includes(propertyName)) {
return true;
} else {
return false;
}
}

module.exports = contains;

/*
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'
*/
30 changes: 29 additions & 1 deletion Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,23 @@ 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("when checking property existence", () => {
test("should return true if the object contains the property", () => {
expect(contains({ a: "apple", b: "hill" }, "a")).toBe(true);
});
test("should return false if the object does not contain the property", () => {
expect(contains({ a: "apple", b: "hill" }, "c")).toBe(false);
});
});

// Given an empty object
// When passed to contains
// Then it should return false
test.todo("contains on empty object returns false");
describe("given an empty object", () => {
test("should return false when passed to contains", () => {
expect(contains({}, "a").toBe(false));
});
});

// Given an object with properties
// When passed to contains with an existing property name
Expand All @@ -33,3 +46,18 @@ test.todo("contains on empty object returns false");
// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error
describe("when given invalid inputs", () => {
test("should throw an error if the input is not an object", () => {
expect(() => contains([true, 2, "hill"], "2")).toThrow(
"Input should be an object"
);
});

test("should throw an error if the input is not an object", () => {
expect(() => contains(null, "hi")).toThrow("Input should be an object");
});

test("should throw an error if the input is not an object", () => {
expect(() => contains("apple", "a")).toThrow("Input should be an object");
});
});
51 changes: 49 additions & 2 deletions Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,52 @@
function createLookup() {
// implementation here
function createLookup(countryCurrencyPairs) {
//if countryCurrencyPairs is not an array, throw error
if (!Array.isArray(countryCurrencyPairs)) {
throw new Error("Invalid input. It should be an array");
}
//if it is an empty array, throw error
if (countryCurrencyPairs.length === 0) {
throw new Error("Input should not be an empty array");
}

//if not all elements are an array in the array, throw an error
if (!countryCurrencyPairs.every(Array.isArray)) {
throw new Error("Invalid input. All elements should be arrays");
}

return Object.fromEntries(countryCurrencyPairs);
}

module.exports = createLookup;

// console.log(
// createLookup([
// ["US", "USD"],
// ["CA", "CAD"],
// ])
// );

// console.log(createLookup([]));

/*
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'
}

*/
39 changes: 37 additions & 2 deletions Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@
const createLookup = require("./lookup.js");

test.todo("creates a country currency code lookup for multiple codes");
describe("when given invalid inputs", () => {
test("should return invalid input error, if the input is an empty array", () => {
expect(() => createLookup([])).toThrow(
"Input should not be an empty array"
);
});
test("should return invalid input error, if the input isn't an array of arrays", () => {
expect(() => createLookup(["hi", "hello"])).toThrow(
"Invalid input. All elements should be arrays"
);
});
test("should return invalid input error, if the input isn't an array of arrays", () => {
expect(() => createLookup("hi")).toThrow(
"Invalid input. It should be an array"
);
});
test("should return invalid input error, if the input isn't an array of arrays", () => {
expect(() => createLookup(2)).toThrow(
"Invalid input. It should be an array"
);
});
});

describe("when given valid inputs", () => {
test("should return an object where (Input ==> Output): keys:values ==> country code: corresponding currency", () => {
expect(
createLookup([
["US", "USD"],
["CA", "CAD"],
])
).toEqual({
US: "USD",
CA: "CAD",
});
});
});

/*

Expand All @@ -9,7 +44,7 @@ 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
- An array of arrays representing when given invalid inputs code pairs
e.g. [['US', 'USD'], ['CA', 'CAD']]

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

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
queryParams[key] = value;
//replace initial "?" if present
if (queryString.startsWith("?")) {
queryString = queryString.replace("?", "");
}
//replace encoded characters
queryString = decodeURIComponent(queryString);

//replace "+" with " "
queryString = queryString.replaceAll("+", " ");

const keyValuePairs = queryString.split("&");

//filter out empty strings from the keyValuePairs array of strings
let filteredKeyValuePairs = keyValuePairs.filter(
(keyValuePair) => keyValuePair.length > 0
);

//assign key value pairs created by separating on the first "=" sign
filteredKeyValuePairs.forEach((str) => {
//if no "=", then the string should be the key
if (!str.includes("=")) {
const key = str;
queryParams[key] = "";
} else {
const indexOfFirstEqual = str.indexOf("=");
const key = str.slice(0, indexOfFirstEqual);
const value = str.slice(indexOfFirstEqual + 1);
queryParams[key] = value;
}
});

return queryParams;
}
Expand Down
19 changes: 11 additions & 8 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// 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")
const parseQueryString = require("./querystring.js");

test("should parse values containing '='", () => {
expect(parseQueryString("equation=a=b-2")).toEqual({
Expand Down Expand Up @@ -37,12 +37,15 @@ test("should replace '+' by ' '", () => {
});
});

test("should delete accidental '?' if first char by accident", () => {
expect(parseQueryString("?colour=teal")).toEqual({ colour: "teal" });
});
// 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",
});
});
// // 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",
// });
// });
17 changes: 16 additions & 1 deletion Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
function tally() {}
function tally(array) {
if (typeof array === "string") {
throw new Error("Input should be an array");
}

let tallySet = {};

for (let item of array) {
if (!tallySet[item]) {
tallySet[item] = 1;
} else {
tallySet[item] += 1;
}
}
return tallySet;
}

module.exports = tally;
40 changes: 28 additions & 12 deletions Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,32 @@ 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
describe("tally()", () => {
// Given an array with duplicate items
// When passed to tally
// Then it should return counts for each unique item
describe("when given an array with duplicate items", () => {
test("should return an object with counts for each unique item", () => {
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
describe("when given an empty array", () => {
test("should return an empty object", () => {
expect(tally([])).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

// Given an invalid input like a string
// When passed to tally
// Then it should throw an error
// Given an invalid input like a string
// When passed to tally
// Then it should throw an error
describe("when given invalid input such as a string", () => {
test("should throw an error", () => {
expect(() => tally("apple")).toThrow("Input should be an array");
});
});
});
Loading
Loading