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
2 changes: 1 addition & 1 deletion Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ const address = {
postcode: "XYZ 123",
};

console.log(`My house number is ${address[0]}`);
console.log(`My house number is ${address.houseNumber}`);
4 changes: 2 additions & 2 deletions Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ const author = {
alive: true,
};

for (const value of author) {
console.log(value);
for (const key in author) {
console.log(author[key]);
}
2 changes: 1 addition & 1 deletion Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ const recipe = {

console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);
${recipe.ingredients}`);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The requirement is to output each ingredient on a new line.

18 changes: 17 additions & 1 deletion Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
function contains() {}
function contains(object, property) {
if (object === null || typeof object !== "object" || Array.isArray(object)) {
return false;
}

return object.hasOwnProperty(property);
}

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'
// */
51 changes: 50 additions & 1 deletion Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ 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");

// Given an object with properties
// When passed to contains with an existing property name
Expand All @@ -33,3 +32,53 @@ 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

// Given an empty object
// When passed to contains
// Then it should return false
test("returns false for an empty object", () => {
expect(contains({}, "a")).toEqual(false);
});

// Given an object with properties
// When passed to contains with an existing property name
// Then it should return true
test("returns true when the property exists", () => {
expect(contains({ a: 1, b: 2 }, "a")).toEqual(true);
expect(contains({ a: 1, b: 2 }, "b")).toEqual(true);
});

// Given an object with properties
// When passed to contains with a non-existent property name
// Then it should return false
test("returns false when the property does not exist", () => {
expect(contains({ a: 1, b: 2 }, "c")).toEqual(false);
});

// Given an object with several properties
// When checking another existing property
// Then it should return true
test("returns true for another existing property", () => {
expect(contains({ name: "Alice", age: 25 }, "age")).toEqual(true);
});

// Given an array
// When passed to contains
// Then it should return false
test("returns false when given an array", () => {
expect(contains([1, 2, 3], "0")).toEqual(false);
});

// Given a null value
// When passed to contains
// Then it should return false
test("returns false when given null", () => {
expect(contains(null, "a")).toEqual(false);
});

// Given an undefined value
// When passed to contains
// Then it should return false
test("returns false when given undefined", () => {
expect(contains(undefined, "a")).toEqual(false);
});
23 changes: 21 additions & 2 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
function parseQueryString(queryString) {
const queryParams = {};
if (queryString === "") {
return queryString;
}
if (queryString.length === 0) {
return queryParams;
}
Comment on lines +3 to 8

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the if statements seems unnecessary.

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

const keyValuePairs = queryString.split("&").filter((pair) => pair !== "");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
const indexFirstEqual = pair.indexOf("=");

let key;
let value;

if (indexFirstEqual === -1) {
key = pair;
value = "";
} else {
key = pair.slice(0, indexFirstEqual);
value = pair.slice(indexFirstEqual + 1);
}

key = decodeURIComponent(key.replace(/\+/g, " "));
value = decodeURIComponent(value.replace(/\+/g, " "));

queryParams[key] = value;
}

Expand Down
61 changes: 42 additions & 19 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,69 @@
// 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({
const input = "equation=a=b-2";
const currentOutput = parseQueryString(input);
const targetOutput = {
equation: "a=b-2",
});
};

expect(currentOutput).toStrictEqual(targetOutput);
});

test("should ignore empty key-value pairs", () => {
expect(parseQueryString("key1=value1&&key2=value2&")).toEqual({
const input = "key1=value1&&key2=value2&";
const currentOutput = parseQueryString(input);
const targetOutput = {
key1: "value1",
key2: "value2",
});
};
expect(currentOutput).toEqual(targetOutput);
});

test("should accept empty string as key or as value", () => {
expect(parseQueryString("=value")).toEqual({ "": "value" });
expect(parseQueryString("key")).toEqual({ key: "" });
expect(parseQueryString("key=")).toEqual({ key: "" });
expect(parseQueryString("=")).toEqual({ "": "" });
expect(parseQueryString("=value")).toEqual({
"": "value",
});

expect(parseQueryString("key=")).toEqual({
key: "",
});

expect(parseQueryString("=")).toEqual({
"": "",
});
});

// test("should accept empty string as key or as value", () => {
// const currentOutput = parseQueryString(input);
// }
// expect(currentOutput).toEqual(targetOutput);
// expect(parseQueryString("=value")).toEqual({ "": "value" });
// expect(parseQueryString("key")).toEqual({ key: "" });
// expect(parseQueryString("key=")).toEqual({ key: "" });
// expect(parseQueryString("=")).toEqual({ "": "" });

test("should decode percent-encoded characters", () => {
expect(parseQueryString("%24half=1%2F2")).toEqual({
$half: "1/2",
});
});

test("should replace '+' by ' '", () => {
expect(parseQueryString("full+name=John+Doe")).toEqual({
"full name": "John Doe",
});
const input = "full+name=John+Doe";
const currentOutput = parseQueryString(input);
const expectedOutput = { "full name": "John Doe" };
expect(currentOutput).toEqual(expectedOutput);
});

// 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",
});
});
// test("should store values of a key in an array when the key has 2 or more values", () => {
// const input = "key=value1&key=value2&key=value3&foo=bar";
// const currentOutput = parseQueryString(input);
// const expectedOutput = { key: ["value1", "value2", "value3"], foo: "bar" };
// expect(currentOutput).toEqual(expectedOutput);
// });
36 changes: 35 additions & 1 deletion Sprint-2/implement/tally.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,37 @@
function tally() {}
function tally(array) {
const charCount = {};
Comment on lines +1 to +2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the following function call returns the value you expect?

tally(["toString", "toString"]);

Suggestion:

  • Look up an approach to create an empty object with no inherited properties, or
  • use Object.hasOwn()


if (!Array.isArray(array)) {
throw new Error();
}

if (array.length === 0) {
return charCount;
}

for (const char of array) {
if (charCount[char]) {
charCount[char]++;
} else {
charCount[char] = 1;
}
}

return charCount;
}

module.exports = tally;

/**
* tally array
*
* In this task, you'll need to implement a function called tally
* that will take a list of items and count the frequency of each item
* in an array
*
* For example:
*
* tally(['a']), target output: { a: 1 }
* tally(['a', 'a', 'a']), target output: { a: 3 }
* tally(['a', 'a', 'b', 'c']), target output: { a : 2, b: 1, c: 1 }
*/
20 changes: 16 additions & 4 deletions Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@ 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("should return an empty oject when given an empty array", () => {
expect(tally([])).toEqual({});
});

// 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
test("should return counts for each unique item", () => {
expect(tally(["a", "b", "a", "b"])).toEqual({
a: 2,
b: 2,
});
});
// given an invalid input like a string
//when passed to tally
//then it should throw an error

test("should throw an error when passed invalid input", () => {
expect(() => tally("")).toThrow(Error);
});
18 changes: 17 additions & 1 deletion Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,36 @@ 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?
//
//[
// ["a", 1],
//["b", 2]
//]

// d) Explain why the current return value is different from the target output
//invertedObj.key = value; means "create a property named key".
//It does not mean "use the variable key as the property name."
//invertedObj[value] = key; Square brackets allow the variable's value to become the property name.

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

test("should invert an object", () => {
expect(invert({ a: 1, b: 2 })).toEqual({
1: "a",
2: "b",
});
});

test("should invert an object with one property", () => {
expect(invert({ a: 1 })).toEqual({
1: "a",
});
});

test("should return an empty object", () => {
expect(invert({})).toEqual({});
});
Loading
Loading