Skip to content
Open
6 changes: 5 additions & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
// Predict and explain first...
// This will print My house number is undefined
// Because the template literal tries to access the number like it is an array,
// But this is incorrect as it is an object which uses a different way to access
// elements

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

console.log(`My house number is ${address[0]}`);
console.log(`My house number is ${address.houseNumber}`);
6 changes: 4 additions & 2 deletions Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Predict and explain first...
// Throw error because I don't think for of works like that for objects

// 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
// Doesn't work because author isn't an iterable, so it can't be looped over

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

for (const value of author) {
console.log(value);
for (const [key, value] of Object.entries(author)) {
console.log(`${key}: ${value}`);
}
6 changes: 3 additions & 3 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Predict and explain first...

// This will print "bruschetta serves 2
// ingredients: " Then not sure, but definitely not the ingredients
// 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 @@ -11,5 +12,4 @@ const recipe = {
};

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
ingredients:\n\t${recipe.ingredients.join("\n\t")}`);
16 changes: 15 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
function contains() {}
function checkIfObj(objToCheck) {
if (
typeof objToCheck !== "object" ||
objToCheck === null ||
(Object.getPrototypeOf(objToCheck) !== Object.prototype &&
Object.getPrototypeOf(objToCheck) !== null)
) {
throw new Error("contains requires an object");
}
}

function contains(objToCheck, keyToSearch) {
checkIfObj(objToCheck);
return Object.keys(objToCheck).includes(keyToSearch);
}

module.exports = contains;
17 changes: 15 additions & 2 deletions Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,31 @@ as an array isn't an object
// 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({})).toEqual(false);
});

// Given an object with properties
// When passed to contains with an existing property name
// Then it should return true
// Then it should return true#
test("given object with properties, and wanted property exists, returns true", () => {
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 object with properties, and wanted property doesn't exist, returns false", () => {
expect(contains({ a: 1, b: 2 }, "c")).toEqual(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("given something that isn't an object, throw error", () => {
expect(() => contains([1,2,5])).toThrow(
Error("contains requires an object")
);
});
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 objCountryCurrencyPairs = {};

for (const pair of countryCurrencyPairs) {
objCountryCurrencyPairs[pair[0]] = pair[1];
}

return objCountryCurrencyPairs;
}

module.exports = createLookup;
12 changes: 11 additions & 1 deletion Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
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", () => {
expect(
createLookup([
["US", "USD"],
["CA", "CAD"],
])
).toEqual({
US: "USD",
CA: "CAD",
});
});

/*

Expand Down
29 changes: 26 additions & 3 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,33 @@ function parseQueryString(queryString) {
const keyValuePairs = queryString.split("&");

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

if (!pair.includes("=")) {
const key = decodeURIComponent(pair).replace("+", " ");
queryParams[key] = "";
} else {
const key = decodeURIComponent(pair.slice(0, pair.indexOf("="))).replace(
"+",
" "
);
const value = decodeURIComponent(
pair.slice(pair.indexOf("=") + 1)
).replace("+", " ");

if (Object.keys(queryParams).includes(key)) {
if (Array.isArray(queryParams[key])) {
queryParams[key].push(value);
} else {
queryParams[key] = [queryParams[key], value];
}
} else {
queryParams[key] = value;
}
}
}
return queryParams;
}

Expand Down
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(itemList) {
if (!Array.isArray(itemList)) {
throw new Error("tally requires an array");
}
const talliedItems = {};
for (const item of itemList) {
if (!Object.keys(talliedItems).includes(item)) {
talliedItems[item] = 1;
} else {
talliedItems[item] += 1;
}
}
return talliedItems;
}

module.exports = tally;
18 changes: 17 additions & 1 deletion 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
test("Given an array of items, return object contain count for each unique item", () => {
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");
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 items with duplicates, return object contain count for each unique item", () => {
expect(tally(["a", "a", "b", "c", "d", "b", "a"])).toEqual({
a: 3,
b: 2,
c: 1,
d: 1,
});
});

// 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("Given something that is not an array, throws error", () => {
expect(() => tally("Not an array")).toThrow(Error("tally requires an array"));
});
11 changes: 10 additions & 1 deletion Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,29 @@ 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 }
// {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?
// An array of the objects key-value pairs. Used here so we can for loop over all key-value pairs in the object

// d) Explain why the current return value is different from the target output
// because the key is a variable, bracket notations has to be used. with .notation it uses the word, not the variable so in this case the
// key is the word 'key'. Also the key and value are the wrong way round, the key of the original object is being given the value of the
// original object, essentially doing nothing

// e) Fix the implementation of invert (and write tests to prove it's fixed!)
5 changes: 5 additions & 0 deletions Sprint-2/interpret/invert.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const invert = require("./invert.js");

test("Given object, returns object with inverted values and keys", () => {
expect(invert({ a: 8, b: 2 })).toEqual({ 8: "a", 2: "b" });
});
Loading