Skip to content

Commit 611d247

Browse files
committed
complted sprint-2 coursework
1 parent 2830956 commit 611d247

File tree

8 files changed

+260
-15
lines changed

8 files changed

+260
-15
lines changed

Sprint-2/implement/lookup.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
1-
function createLookup(countryCurrencyPairs) {
2-
return Object.fromEntries(countryCurrencyPairs);
1+
// the first element is the country code
2+
// the second array is the currency code of the country
3+
// the function should return an object
4+
// the keys of the object should be the first element of each inner array (country code)
5+
// the values of the object should be the second element of each inner array (currency code)
6+
7+
function Lookup(coCuPairs) {
8+
// check if the argument is an array of arrays
9+
if (
10+
Array.isArray(coCuPairs) &&
11+
// check if each inner array is an array.
12+
coCuPairs.every((pair) => Array.isArray(pair)) &&
13+
// check if each inner array has two elements.
14+
coCuPairs.every((pair) => pair.length === 2)
15+
// we can also use index to check the pair is an array as follows:
16+
// for (let i = 0; i < coCuPairs.length; i++)
17+
// return Array.isArray(coCuPairs[i])
18+
) {
19+
return Object.fromEntries(coCuPairs);
20+
}
21+
return "Invalid input: expected an array of arrays";
322
}
423

5-
module.exports = createLookup;
24+
module.exports = Lookup;

Sprint-2/implement/lookup.test.js

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1-
const createLookup = require("./lookup.js");
1+
const Lookup = require("./lookup.js");
22

3-
test.todo("creates a country currency code lookup for multiple codes");
3+
test("creates a country currency code lookup for multiple codes", () => {
4+
const input = [
5+
["DZ", "DZD"],
6+
["CA", "CAD"],
7+
["GB", "GBP"],
8+
];
9+
const result = {
10+
DZ: "DZD",
11+
CA: "CAD",
12+
GB: "GBP",
13+
};
14+
expect(Lookup(input)).toEqual(result);
15+
});
416

517
/*
618
@@ -24,7 +36,7 @@ Example
2436
Given: [['US', 'USD'], ['CA', 'CAD']]
2537
2638
When
27-
createLookup(countryCurrencyPairs) is called
39+
Lookup(coCuPairs) is called
2840
2941
Then
3042
It should return:
@@ -33,3 +45,29 @@ It should return:
3345
'CA': 'CAD'
3446
}
3547
*/
48+
// Given an invalid input (not an array of arrays),
49+
test('return "Invalid input: expected an array of arrays" for string input', () => {
50+
const input = "invalid input: expected an array of arrays";
51+
expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays");
52+
});
53+
54+
// Given an array where its elements are not arrays,
55+
test('return "Invalid input: expected an array of arrays" for non-array elements', () => {
56+
const input = [["US", "USD"], "CA"];
57+
expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays");
58+
});
59+
60+
// Given an array where its elements are arrays with more than two elements,
61+
test('return "Invalid input: expected an array of arrays" for arrays with too many elements', () => {
62+
const input = [
63+
["US", "USD", "flag"],
64+
["CA", "CAD"],
65+
];
66+
expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays");
67+
});
68+
69+
// Given an array where its elements are arrays with less than two elements,
70+
test('return "Invalid input: expected an array of arrays" for arrays with too few elements', () => {
71+
const input = [["US", "USD"], ["CA"]];
72+
expect(Lookup(input)).toEqual("Invalid input: expected an array of arrays");
73+
});

Sprint-2/implement/querystring.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1+
// the bug in the code is that it does not handle cases where the query string has two = signs or more between two parameters.
2+
// in this case we make sure to split the string only at the first = sign.
3+
// so we use the spread operator.
14
function parseQueryString(queryString) {
25
const queryParams = {};
6+
if (queryString === null || queryString === undefined) {
7+
return "invalid query string";
8+
}
39
if (queryString.length === 0) {
410
return queryParams;
511
}
612
const keyValuePairs = queryString.split("&");
713

814
for (const pair of keyValuePairs) {
9-
const [key, value] = pair.split("=");
10-
queryParams[key] = value;
15+
const [key, ...value] = pair.split("=");
16+
// we convert the value array back to a string and we get back the = signs by using it as separator.
17+
queryParams[key] = value.join("=");
1118
}
1219

1320
return queryParams;

Sprint-2/implement/querystring.test.js

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,85 @@
33
// Below is one test case for an edge case the implementation doesn't handle well.
44
// Fix the implementation for this test, and try to think of as many other edge cases as possible - write tests and fix those too.
55

6-
const parseQueryString = require("./querystring.js")
6+
const parseQueryString = require("./querystring.js");
77

8+
// testing when the query string with a value contains = signs
89
test("parses querystring values containing =", () => {
910
expect(parseQueryString("equation=x=y+1")).toEqual({
10-
"equation": "x=y+1",
11+
equation: "x=y+1",
12+
});
13+
});
14+
15+
// testing when the query string has multiple ampersands
16+
test("parses query string with multiple parameters", () => {
17+
expect(parseQueryString("name=Ben&age=45&city=new%20city")).toEqual({
18+
name: "Ben",
19+
age: "45",
20+
city: "new%20city",
21+
});
22+
});
23+
24+
// testing when the query string has two ampersands in a row
25+
test("parses query string with two ampersands in a row", () => {
26+
expect(parseQueryString("name=Ben&&age=45")).toEqual({
27+
name: "Ben",
28+
"": "",
29+
age: "45",
30+
});
31+
});
32+
33+
// testing when the query string has no ampersands
34+
test("parses query string with no ampersands", () => {
35+
expect(parseQueryString("name=Ben")).toEqual({
36+
name: "Ben",
37+
});
38+
});
39+
40+
// testing when the query string has no ampersands and no equal signs
41+
test("parses query string with no ampersands and no equal signs", () => {
42+
expect(parseQueryString("name")).toEqual({
43+
name: "",
44+
});
45+
});
46+
47+
// testing when the query string is empty
48+
test("parses query string with empty value", () => {
49+
expect(parseQueryString("")).toEqual({});
50+
});
51+
52+
// testing when the query string is null
53+
test("parses query string with null value", () => {
54+
expect(parseQueryString(null)).toEqual("invalid query string");
55+
});
56+
57+
// testing when the query string is undefined
58+
test("parses query string with undefined value", () => {
59+
expect(parseQueryString(undefined)).toEqual("invalid query string");
60+
});
61+
62+
// testing when a pair ends with equal sign (no value)
63+
test("parses query string with no equal sign", () => {
64+
expect(parseQueryString("name=Ben&age=&city=")).toEqual({
65+
name: "Ben",
66+
age: "",
67+
city: "",
68+
});
69+
});
70+
71+
// testing when a pair starts with equal sign (no key)
72+
test("parses query string starting with equal sign", () => {
73+
expect(parseQueryString("name=Ben&=45")).toEqual({
74+
name: "Ben",
75+
"": "45",
76+
});
77+
});
78+
79+
// testing when a pair has no equal sign (no value and no key)
80+
// the pair will be the key and the value will be an empty string
81+
test("parses query string with no equal sign", () => {
82+
expect(parseQueryString("name&age=45&city")).toEqual({
83+
name: "",
84+
age: "45",
85+
city: "",
1186
});
1287
});

Sprint-2/implement/tally.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1-
function tally() {}
2-
1+
function tally(arr) {
2+
if (!Array.isArray(arr)) {
3+
throw new Error("invalid input");
4+
}
5+
let result = {};
6+
for (let i = 0; i <= arr.length - 1; i++) {
7+
let item = arr[i];
8+
result[item] = (result[item] || 0) + 1;
9+
}
10+
return result;
11+
}
312
module.exports = tally;

Sprint-2/implement/tally.test.js

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,63 @@ const tally = require("./tally.js");
2323
// Given an empty array
2424
// When passed to tally
2525
// Then it should return an empty object
26-
test.todo("tally on an empty array returns an empty object");
26+
test("tally on an empty array returns an empty object", () => {
27+
expect(tally([])).toEqual({});
28+
});
2729

2830
// Given an array with duplicate items
2931
// When passed to tally
3032
// Then it should return counts for each unique item
33+
test("tally on an empty array returns an empty object", () => {
34+
expect(tally([])).toEqual({});
35+
});
36+
37+
// Given an array with duplicate items
38+
// When passed to tally
39+
// Then it should return counts for each unique item
40+
test("tally on an array with duplicates returns correct counts for each unique item", () => {
41+
expect(
42+
tally([
43+
"CYF",
44+
"CYF",
45+
"AWS",
46+
"Capgemini",
47+
"Deloitte",
48+
"Google",
49+
"Slack",
50+
"Capgemini",
51+
])
52+
).toEqual({ CYF: 2, AWS: 1, Capgemini: 2, Deloitte: 1, Google: 1, Slack: 1 });
53+
});
3154

3255
// Given an invalid input like a string
3356
// When passed to tally
3457
// Then it should throw an error
58+
test("given invalid input throws an error", () => {
59+
expect(() => tally("invalid")).toThrow("invalid input");
60+
});
61+
62+
// Given an invalid input like a number
63+
test("given invalid input throws an error", () => {
64+
expect(() => tally("invalid")).toThrow("invalid input");
65+
});
66+
67+
// Given an invalid input like a number
68+
test("given invalid input throws an error", () => {
69+
expect(() => tally(123)).toThrow("invalid input");
70+
});
71+
72+
// Given an invalid input like an object
73+
test("given invalid input throws an error", () => {
74+
expect(() => tally({})).toThrow("invalid input");
75+
});
76+
77+
// Given an invalid input like null
78+
test("given invalid input throws an error", () => {
79+
expect(() => tally(null)).toThrow("invalid input");
80+
});
81+
82+
// Given an invalid input like undefined
83+
test("given invalid input throws an error", () => {
84+
expect(() => tally(undefined)).toThrow("invalid input");
85+
});

Sprint-2/interpret/invert.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,32 @@
88

99
function invert(obj) {
1010
const invertedObj = {};
11-
11+
if (typeof obj !== "object" || obj === null || Array.isArray(obj))
12+
return invertedObj;
1213
for (const [key, value] of Object.entries(obj)) {
13-
invertedObj.key = value;
14+
invertedObj[value] = key;
1415
}
1516

1617
return invertedObj;
1718
}
1819

1920
// a) What is the current return value when invert is called with { a : 1 }
21+
// {key: 1}
2022

2123
// b) What is the current return value when invert is called with { a: 1, b: 2 }
24+
// {key: 2}
2225

2326
// c) What is the target return value when invert is called with {a : 1, b: 2}
27+
// {"1": "a", "2": "b"}
2428

2529
// c) What does Object.entries return? Why is it needed in this program?
30+
// it returns an array of the pairs properties [key, value] of the object.
31+
// it is needed in this program to iterate over the key value pairs of the object to swap them in new object.
2632

2733
// d) Explain why the current return value is different from the target output
34+
// because first it doesn't swap.
35+
// second, we're using the dot notation to assign the value where we should user the brackets notation as the key is variable and not a string literal.
2836

2937
// e) Fix the implementation of invert (and write tests to prove it's fixed!)
38+
39+
module.exports = invert;

Sprint-2/interpret/invert.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
const invert = require("./invert.js");
2+
// writing some tests.
3+
// Given an simple ordinary object.
4+
test("invert on a simple object returns the correct inverted object", () => {
5+
expect(invert({ a: 1 })).toEqual({ 1: "a" });
6+
});
7+
// Given an object with multiple key value pairs.
8+
test("invert on an object with multiple key value pairs returns the correct inverted object", () => {
9+
expect(invert({ a: 1, b: 2 })).toEqual({ 1: "a", 2: "b" });
10+
});
11+
// Given an object with duplicate values.
12+
test("invert on an object with duplicate values returns the correct inverted object", () => {
13+
expect(invert({ a: 1, b: 1 })).toEqual({ 1: "a", 1: "b" });
14+
});
15+
// Given an empty object.
16+
test("invert on an empty object returns an empty object", () => {
17+
expect(invert({})).toEqual({});
18+
});
19+
// Given an invalid input like a string.
20+
test("invert on an invalid input like a string returns an empty object", () => {
21+
expect(invert("invalid")).toEqual({});
22+
});
23+
24+
// Given an invalid input like a number.
25+
test("invert on an invalid input like a number returns an empty object", () => {
26+
expect(invert(123)).toEqual({});
27+
});
28+
// Given an invalid input like an array.
29+
test("invert on an invalid input like an array returns an empty object", () => {
30+
expect(invert([1, 2, 3])).toEqual({});
31+
});
32+
// Given an invalid input like null or undefined.
33+
test("invert on an invalid input like null or undefined returns an empty object", () => {
34+
expect(invert(null)).toEqual({});
35+
expect(invert(undefined)).toEqual({});
36+
});

0 commit comments

Comments
 (0)