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
7 changes: 6 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
// but it isn't working...
// Fix anything that isn't working

/*
When we test the file without fixing we get "My house number is [object Object]"
We need to properly export the house number: adress.houseNumber.
*/

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

console.log(`My house number is ${address[0]}`);
console.log(`My house number is ${address.houseNumber}`);
8 changes: 7 additions & 1 deletion Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// Predict and explain first...

/*
TypeError: author is not iterable
The way the code is written is that author is an object.

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

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

for (const value of author) {
for (const value of Object.values(author)) {
// gives you an array of all the values
console.log(value);
}
10 changes: 9 additions & 1 deletion Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
// Predict and explain first...

/*
First of all the output will not give us the proper ingredients. We will again get [object Object].
We can fix this by using the correct array object recipe.ingredients.

Secondly we don't loop through the ingredients and create a new line \n after each ingredient.

*/

// 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?
Expand All @@ -12,4 +20,4 @@ const recipe = {

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
${recipe.ingredients.join("\n")}`); //You can do this by joining the array with \n (newline)
24 changes: 23 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
function contains() {}
function contains(objectToCheck, propertyName) {
if (Array.isArray(objectToCheck)) {
throw new Error("Invalid parameter, No arrays allowed");
}
if (typeof objectToCheck !== "object" || objectToCheck === null) {
return false;
}
return propertyName in objectToCheck;
}

module.exports = contains;

/*
If the first argument is an array
Throw an error: "Invalid parameter, No arrays allowed"

If the first argument is not an object
Return false

If the object has the property (second argument)
Return true

Otherwise
Return false
*/
15 changes: 14 additions & 1 deletion Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,29 @@ 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 on empty object returns false", () => {
expect(contains({}, "a")).toBe(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 that are included, return true", () => {
expect(contains({ a: 1, b: 2 }, "a")).toBe(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 that are NON included, return false", () => {
expect(contains({ a: 1, b: 2 }, "c")).toBe(false);
});

// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error
test("Given an object with invalid properties such as arrays, trow error", () => {
expect(() => contains([1, 2, 3])).toThrow(
"Invalid parameter, No arrays allowed"
);
});
18 changes: 16 additions & 2 deletions Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
function createLookup() {
// implementation here
function createLookup(countryCurrencyPairs) {
return Object.fromEntries(countryCurrencyPairs);
}

module.exports = createLookup;

/*
The Object.fromEntries() static method transforms a list of key-value pairs into an object.

const entries = new Map([
["foo", "bar"],
["baz", 42],
]);

const obj = Object.fromEntries(entries);

console.log(obj);
// Expected output: Object { foo: "bar", baz: 42 }
*/
22 changes: 20 additions & 2 deletions Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
const createLookup = require("./lookup.js");

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

test("Given an array of code pairs, create a lookup object representing country code", () => {
expect(createLookup([["US", "USD"]])).toEqual({ US: "USD" });
});

test("Given an array of code pairs CA - CAD, create a lookup object representing country code", () => {
expect(createLookup([["CA", "CAD"]])).toEqual({ CA: "CAD" });
});

test("Given 2 arrays of code pairs, create a lookup object with 2 object pairs", () => {
expect(
createLookup([
["US", "USD"],
["CA", "CAD"],
])
).toEqual({ US: "USD", CA: "CAD" });
});

test("Given an empty array of code pairs, we should return an empty object", () => {
expect(createLookup([])).toEqual({});
});
/*

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

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
queryParams[key] = value;
const whereIs = pair.indexOf("=");
if (whereIs === -1) {
queryParams[pair] = "";
} else {
const key = pair.slice(0, whereIs);
const value = pair.slice(whereIs + 1);
queryParams[key] = value;
}
}

return queryParams;
Expand Down
61 changes: 58 additions & 3 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,65 @@
// Below is one test case for an edge case the implementation doesn't handle well.
// Fix the implementation for this test, 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("parses querystring values containing =", () => {
test("parses a value that contains =", () => {
expect(parseQueryString("equation=x=y+1")).toEqual({
"equation": "x=y+1",
equation: "x=y+1",
});
});

// Empty string edge case:
test("returns an empty object for an empty string", () => {
expect(parseQueryString("")).toEqual({});
});

// Key with empty value:
test("parses a key with an empty value", () => {
expect(parseQueryString("Key=")).toEqual({ Key: "" });
});

// Value with an empty key:
test("parses a value with an empty key", () => {
expect(parseQueryString("=Value")).toEqual({ "": "Value" });
});

// When there's no = in the Querystring:
test("parses a query string without = as an empty value", () => {
expect(parseQueryString("nothingToSeeHere")).toEqual({
nothingToSeeHere: "",
});
});

// Multiple pairs per Querystring:
test("parses multiple key-value pairs", () => {
expect(parseQueryString("name=Ben&city=Amsterdam")).toEqual({
name: "Ben",
city: "Amsterdam",
});
});

// Multiple pairs with missing values:
test("parses multiple pairs when one value is missing", () => {
expect(parseQueryString("name=Ben&city=&country=Netherlands")).toEqual({
name: "Ben",
city: "",
country: "Netherlands",
});
});

// Pairs with a missing key:
test("parses multiple pairs when one key is missing", () => {
expect(parseQueryString("name=Ben&=Amsterdam")).toEqual({
name: "Ben",
"": "Amsterdam",
});
});

// Multiple pairs where one value contains =:
test("parses multiple pairs when one value contains =", () => {
expect(parseQueryString("equation=x=y+1&answer=42")).toEqual({
equation: "x=y+1",
answer: "42",
});
});
25 changes: 24 additions & 1 deletion Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
function tally() {}
function tally(arrayItems) {
if (!Array.isArray(arrayItems)) {
throw new Error("The input is not an Array");
}
// Createa an empty object to store the counted value appears in the array.
const counter = {};
for (const item of arrayItems) {
if (counter[item]) {
counter[item] += 1;
} else {
counter[item] = 1;
}
}
return counter;
}

module.exports = tally;

/*
If the input is not an array, throw an error.
Make an empty object called counts.
For each item in the array:
If the item is already in counts, add 1 to its value.
If the item is not in counts, set its value to 1.
Return the counts object.
*/
28 changes: 27 additions & 1 deletion Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,38 @@ 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({});
});

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

test("Given an array of duplicate items, return counts for each unique item", () => {
expect(tally(["a", "a", "b", "b", "c"])).toEqual({ a: 2, b: 2, c: 1 });
});

// Test with 1 value in the array
test("Given an array of duplicate items, return counts for each unique item", () => {
expect(tally(["a"])).toEqual({ a: 1 });
});

// Given an invalid input like a string
// When passed to tally
// Then it should throw an error

test("Given an invalid input like string, trow error: The input is not an Array", () => {
expect(() => tally("Malakia not a string")).toThrow(
"The input is not an Array"
);
});

/*
Remember: “toThrow needs a function, toEqual needs a value.
If you want to test for an error, always wrap the function call in another function.

expect(() => myFunc(badInput)).toThrow();

*/
19 changes: 18 additions & 1 deletion Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,37 @@ function invert(obj) {
const invertedObj = {};

for (const [key, value] of Object.entries(obj)) {
invertedObj.key = value;
// Use the old value as the "new" key, and the "old" key as the new value.
// invertedObj.key = value; => This always creates a property called "key" not the value of "key"
invertedObj[value] = key;
}

return invertedObj;
}

// a) What is the current return value when invert is called with { a : 1 }
// Current return value: { key: 1 }
// It used the word `key` as the property name.

// b) What is the current return value when invert is called with { a: 1, b: 2 }
// Current return value: { key: 2 }
// The second loop overwrites the first one.

// c) What is the target return value when invert is called with {a : 1, b: 2}
// Target return value: { 1: "a", 2: "b" }
// The old values become keys, and the old keys become values.

// c) What does Object.entries return? Why is it needed in this program?
// `Object.entries(obj)` returns an array of key-value pairs.
// Example: `Object.entries({ a: 1, b: 2 })` becomes `[["a", 1], ["b", 2]]`.
// We use it to get both the key and value while looping.
// MDN: Object.entries()
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

// d) Explain why the current return value is different from the target output
// `invertedObj.key` always makes a property called `key`.
// We need `invertedObj[value]` so JavaScript uses the real value as the property name.

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

module.exports = invert;
29 changes: 29 additions & 0 deletions Sprint-2/interpret/invert.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const invert = require("./invert.js");

// When the object has one key-value pair:
test("swaps the key and value in an object with one property", () => {
expect(invert({ a: 1 })).toEqual({
1: "a",
});
});

// When the object has multiple key-value pairs:
test("swaps all keys and values in an object with multiple properties", () => {
expect(invert({ a: 1, b: 2 })).toEqual({
1: "a",
2: "b",
});
});

// When the object is empty:
test("returns an empty object when given an empty object", () => {
expect(invert({})).toEqual({});
});

// When the values are strings:
test("uses the original string values as keys in the new object", () => {
expect(invert({ first: "Benzaki", second: "BenziMou" })).toEqual({
Benzaki: "first",
BenziMou: "second",
});
});