Skip to content

Commit 246d974

Browse files
committed
Add alarm clock exercise
1 parent 8a1272c commit 246d974

14 files changed

Lines changed: 139 additions & 187 deletions

File tree

‎Sprint-2/debug/address.js‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
// Predict and explain first...
22

3-
// This will fail because to parse from an object requires a key, not an index value
4-
53
// This code should log out the houseNumber from the address object
64
// but it isn't working...
75
// Fix anything that isn't working
@@ -14,4 +12,4 @@ const address = {
1412
postcode: "XYZ 123",
1513
};
1614

17-
console.log(`My house number is ${address.houseNumber}`);
15+
console.log(`My house number is ${address[0]}`);

‎Sprint-2/debug/author.js‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// Predict and explain first...
2-
// The for...of loop only works with iterable objects, such as arrays
32

43
// This program attempts to log out all the property values in the object.
54
// But it isn't working. Explain why first and then fix the problem
@@ -12,6 +11,6 @@ const author = {
1211
alive: true,
1312
};
1413

15-
for (const value of Object.values(author)) {
14+
for (const value of author) {
1615
console.log(value);
17-
}
16+
}

‎Sprint-2/debug/recipe.js‎

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
// Predict and explain first...
22

3-
//The program will not display the ingredients correctly. Instead, it will show something like:
4-
//bruschetta serves 2
5-
//ingredients:
6-
//[object Object]
7-
8-
//The issue is that `recipe` is an object. JavaScript cannot display the whole object inside a string, so it shows `[object Object]`. You need to access the specific values you want, like the ingredients array, and format them separately.
9-
10-
113
// This program should log out the title, how many it serves and the ingredients.
124
// Each ingredient should be logged on a new line
135
// How can you fix it?
@@ -19,5 +11,5 @@ const recipe = {
1911
};
2012

2113
console.log(`${recipe.title} serves ${recipe.serves}
22-
ingredients:
23-
${recipe.ingredients.join("\n")}`);
14+
ingredients:
15+
${recipe}`);

‎Sprint-2/implement/contains.js‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
function contains(array, target) {
2-
return array.includes(target);
3-
}
1+
function contains() {}
42

5-
module.exports = contains;
3+
module.exports = contains;
Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,35 @@
1-
describe("contains", () => {
2-
// Given an empty object
3-
// When passed to contains
4-
// Then it should return false
5-
it("contains on empty object returns false", () => {
6-
const object = {};
7-
const property = "a";
8-
expect(contains(object, property)).toEqual(false);
9-
});
10-
11-
// Given an object with properties
12-
// When passed to contains with an existing property name
13-
// Then it should return true
14-
it("object contains property returns true", () => {
15-
const object = { a: 1, b: 2 };
16-
const property = "a";
17-
expect(contains(object, property)).toEqual(true);
18-
});
19-
20-
// Given an object with properties
21-
// When passed to contains with a non-existent property name
22-
// Then it should return false
23-
it("object does not contain property returns false", () => {
24-
const object = { a: 1, b: 2 };
25-
const property = "c";
26-
expect(contains(object, property)).toEqual(false);
27-
});
28-
29-
// Given invalid parameters like an array
30-
// When passed to contains
31-
// Then it should return false or throw an error
32-
it("given invalid parameter (an array) returns false or throws an error", () => {
33-
expect(contains([], [])).toEqual(false);
34-
expect(contains(["a", 1], 1)).toEqual(false);
35-
expect(contains({ a: 1, b: 2 }, ["a"])).toEqual(false);
36-
});
37-
38-
it("given null returns false", () => {
39-
expect(contains(null, "a")).toEqual(false);
40-
expect(contains({ a: 1, b: 2 }, null)).toEqual(false);
41-
expect(contains(null, null)).toEqual(false);
42-
});
43-
});
1+
const contains = require("./contains.js");
2+
3+
/*
4+
Implement a function called contains that checks an object contains a
5+
particular property
6+
7+
E.g. contains({a: 1, b: 2}, 'a') // returns true
8+
as the object contains a key of 'a'
9+
10+
E.g. contains({a: 1, b: 2}, 'c') // returns false
11+
as the object doesn't contains a key of 'c'
12+
*/
13+
14+
// Acceptance criteria:
15+
16+
// Given a contains function
17+
// When passed an object and a property name
18+
// Then it should return true if the object contains the property, false otherwise
19+
20+
// Given an empty object
21+
// When passed to contains
22+
// Then it should return false
23+
test.todo("contains on empty object returns false");
24+
25+
// Given an object with properties
26+
// When passed to contains with an existing property name
27+
// Then it should return true
28+
29+
// Given an object with properties
30+
// When passed to contains with a non-existent property name
31+
// Then it should return false
32+
33+
// Given invalid parameters like an array
34+
// When passed to contains
35+
// Then it should return false or throw an error

‎Sprint-2/implement/lookup.js‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
function createLookup(arrayOfArrays) {
2-
const lookup = {};
3-
for (const array of arrayOfArrays) {
4-
lookup[array[0]] = array[1];
5-
}
6-
return lookup;
1+
function createLookup() {
2+
// implementation here
73
}
84

95
module.exports = createLookup;

‎Sprint-2/implement/lookup.test.js‎

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,35 @@
11
const createLookup = require("./lookup.js");
22

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

4-
describe("createLookup", () => {
5-
it("creates a country currency code lookup for multiple codes", () => {
6-
const arrayOfArrays = [
7-
["US", "USD"],
8-
["CA", "CAD"],
9-
["UK", "GBP"],
10-
];
11-
expect(createLookup(arrayOfArrays)).toEqual({
12-
US: "USD",
13-
CA: "CAD",
14-
UK: "GBP",
15-
});
16-
});
17-
});
5+
/*
6+
7+
Create a lookup object of key value pairs from an array of code pairs
8+
9+
Acceptance Criteria:
10+
11+
Given
12+
- An array of arrays representing country code and currency code pairs
13+
e.g. [['US', 'USD'], ['CA', 'CAD']]
14+
15+
When
16+
- createLookup function is called with the country-currency array as an argument
17+
18+
Then
19+
- It should return an object where:
20+
- The keys are the country codes
21+
- The values are the corresponding currency codes
22+
23+
Example
24+
Given: [['US', 'USD'], ['CA', 'CAD']]
25+
26+
When
27+
createLookup(countryCurrencyPairs) is called
28+
29+
Then
30+
It should return:
31+
{
32+
'US': 'USD',
33+
'CA': 'CAD'
34+
}
35+
*/

‎Sprint-2/implement/querystring.js‎

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,14 @@ function parseQueryString(queryString) {
33
if (queryString.length === 0) {
44
return queryParams;
55
}
6-
7-
// Replaces + with space
8-
queryString = queryString.replaceAll("+", " ");
96
const keyValuePairs = queryString.split("&");
107

118
for (const pair of keyValuePairs) {
12-
f (pair !== "") {
13-
let index = pair.indexOf("=");
14-
if (!pair.includes("=")) {
15-
index = pair.length;
16-
}
17-
const rawKey = pair.slice(0, index);
18-
const rawValue = pair.slice(index + 1);
19-
20-
// Remove percentage-encoded characters
21-
const key = decodeURIComponent(rawKey);
22-
const value = decodeURIComponent(rawValue);
23-
24-
queryParams[key] = value;
25-
}
9+
const [key, value] = pair.split("=");
10+
queryParams[key] = value;
2611
}
2712

2813
return queryParams;
2914
}
3015

31-
16+
module.exports = parseQueryString;
Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,48 @@
1-
function parseQueryString(queryString) {
2-
const queryParams = {};
3-
4-
if (queryString.length === 0) {
5-
return queryParams;
6-
}
7-
8-
const keyValuePairs = queryString.split("&");
9-
10-
for (const pair of keyValuePairs) {
11-
if (pair === "") {
12-
continue;
13-
}
14-
15-
const equalIndex = pair.indexOf("=");
16-
17-
let key;
18-
let value;
19-
20-
if (equalIndex === -1) {
21-
key = pair;
22-
value = "";
23-
} else {
24-
key = pair.slice(0, equalIndex);
25-
value = pair.slice(equalIndex + 1);
26-
}
27-
28-
key = decodeURIComponent(key.replaceAll("+", " "));
29-
value = decodeURIComponent(value.replaceAll("+", " "));
30-
31-
queryParams[key] = value;
32-
}
33-
34-
return queryParams;
35-
}
36-
37-
module.exports = parseQueryString;
1+
// In the prep, we implemented a function to parse query strings.
2+
// Unfortunately, it contains several bugs!
3+
// Below are some test cases the implementation doesn't handle well.
4+
// Fix the implementation for these tests, and try to think of as many other edge cases as possible - write tests and fix those too.
5+
6+
const parseQueryString = require("./querystring.js")
7+
8+
test("should parse values containing '='", () => {
9+
expect(parseQueryString("equation=a=b-2")).toEqual({
10+
equation: "a=b-2",
11+
});
12+
});
13+
14+
test("should ignore empty key-value pairs", () => {
15+
expect(parseQueryString("key1=value1&&key2=value2&")).toEqual({
16+
key1: "value1",
17+
key2: "value2",
18+
});
19+
});
20+
21+
test("should accept empty string as key or as value", () => {
22+
expect(parseQueryString("=value")).toEqual({ "": "value" });
23+
expect(parseQueryString("key")).toEqual({ key: "" });
24+
expect(parseQueryString("key=")).toEqual({ key: "" });
25+
expect(parseQueryString("=")).toEqual({ "": "" });
26+
});
27+
28+
test("should decode percent-encoded characters", () => {
29+
expect(parseQueryString("%24half=1%2F2")).toEqual({
30+
$half: "1/2",
31+
});
32+
});
33+
34+
test("should replace '+' by ' '", () => {
35+
expect(parseQueryString("full+name=John+Doe")).toEqual({
36+
"full name": "John Doe",
37+
});
38+
});
39+
40+
// Stretch exercise: Handling query strings that contain identical keys
41+
42+
// Delete this test if you are not working on this optional case
43+
test("should store values of a key in an array when the key has 2 or more values", () => {
44+
expect(parseQueryString("key=value1&key=value2&key=value3&foo=bar")).toEqual({
45+
key: ["value1", "value2", "value3"],
46+
foo: "bar",
47+
});
48+
});

‎Sprint-2/implement/tally.js‎

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,3 @@
1-
function tally(array) {
2-
if (!Array.isArray(array)) {
3-
throw new Error("Invalid array");
4-
}
5-
const count = Object.create(null);
6-
array.forEach((item) => {
7-
if (item in count) {
8-
count[item] += 1;
9-
} else count[item] = 1;
10-
});
11-
return count;
12-
}
1+
function tally() {}
2+
133
module.exports = tally;

0 commit comments

Comments
 (0)