Skip to content
Closed
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: 2 additions & 0 deletions Sprint-2/debug/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ const address = {
};

console.log(`My house number is ${address[0]}`);
//My houseNumber will be undefined
console.log(`My house number is ${address["houseNumber"]}`);
4 changes: 4 additions & 0 deletions Sprint-2/debug/author.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ const author = {
for (const value of author) {
console.log(value);
}
// TypeError, for is not iterable object, it used for arrays.
for (const value of Object.values(author)) {
console.log(value);
}
5 changes: 5 additions & 0 deletions Sprint-2/debug/recipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ const recipe = {
console.log(`${recipe.title} serves ${recipe.serves}
ingredients:
${recipe}`);

// The code will not log the ingredients, only the object.
for (const ingredient of recipe.ingredients) {
console.log(ingredient);
}
15 changes: 13 additions & 2 deletions Sprint-2/implement/contains.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
function contains() {}

module.exports = contains;
function contains(object, property) {
if (
object === null ||
typeof object !== "object" ||
Array.isArray(object)
) {

return false;
}

return Object.hasOwn(object, property);
}
module.exports = contains;
24 changes: 18 additions & 6 deletions Sprint-2/implement/contains.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const contains = require("./contains.js");

/*
/*
Implement a function called contains that checks an object contains a
particular property

Expand All @@ -10,7 +10,7 @@ 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'
*/

const object = { a: 1, b: 2 };
// Acceptance criteria:

// Given a contains function
Expand All @@ -20,16 +20,28 @@ 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({}, "any")).toBe(false);
});
// Given an object with properties
// When passed to contains with an existing property name
// Then it should return true

test("contains returns true for existing property", () => {
expect(contains(object, "a")).toBe(true);
expect(contains(object, "b")).toBe(true);
});
// Given an object with properties
// When passed to contains with a non-existent property name
// Then it should return false

test("contains returns false for non-existent property", () => {
expect(contains(object, "c")).toBe(false);
});
// Given invalid parameters like an array
// When passed to contains
// Then it should return false or throw an error
test("contains returns false for invalid input like arrays", () => {
expect(contains([1, 2, 3], "1")).toBe(false);
expect(contains(null, "anything")).toBe(false);
expect(contains(42, "toString")).toBe(false);
expect(contains("string", "length")).toBe(false);
});
8 changes: 6 additions & 2 deletions Sprint-2/implement/lookup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
function createLookup() {
// implementation here
function createLookup(currencyPairs){
const lookup = {};
for (const [countryCode, currencyCode] of currencyPairs) {
lookup[countryCode] = currencyCode;
}
return lookup;
}

module.exports = createLookup;
28 changes: 27 additions & 1 deletion Sprint-2/implement/lookup.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
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", () => {
const countryCurrencyPairs = [
['US', 'USD'],
['CA', 'CAD'],
['GB', 'GBP'],
['NG', 'NGN']
];

const expectedLookup = {
'US': 'USD',
'CA': 'CAD',
'GB': 'GBP',
'NG': 'NGN',
};
expect(createLookup(countryCurrencyPairs)).toEqual(expectedLookup);
});
/*

Create a lookup object of key value pairs from an array of code pairs
Expand Down Expand Up @@ -33,3 +48,14 @@ It should return:
'CA': 'CAD'
}
*/
test('handles mixed data correctly', () => {
const input = [['NG', 'NGN'], ['FR', 'EUR'], ['GB', 'GBP']];
const expected = { NG: 'NGN', FR: 'EUR', GB: 'GBP' };
expect(createLookup(input)).toEqual(expected);
});

test('returns empty object for empty input', () => {
const input = [];
const expected = {};
expect(createLookup(input)).toEqual(expected);
});
11 changes: 6 additions & 5 deletions Sprint-2/implement/querystring.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
function parseQueryString(queryString) {
const queryParams = {};
if (queryString.length === 0) {
if (!queryString) {
return queryParams;
}
const keyValuePairs = queryString.split("&");

for (const pair of keyValuePairs) {
const [key, value] = pair.split("=");
queryParams[key] = value;
const [key, ...rest] = pair.split("=");
const value = rest.join("="); // Join the rest in case the value contains '='
queryParams[decodeURIComponent(key)] = decodeURIComponent(value);

}

return queryParams;
return queryParams;
}

module.exports = parseQueryString;
20 changes: 20 additions & 0 deletions Sprint-2/implement/querystring.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,23 @@ test("parses querystring values containing =", () => {
"equation": "x=y+1",
});
});
test("parses querystring with multiple values", () => {
expect(parseQueryString("humanleg=2&spider=6&dog=4")).toEqual({
"humanleg": "2",
"spider": "6",
"dog": "4",
});
});
test("parses querystring with empty values", () => {
expect(parseQueryString("a=&b=2&c=")).toEqual({
"a": "",
"b": "2",
"c": "",
});
});
test("parses querystring with special characters", () => {
expect(parseQueryString("name=Mayowa%20Fadare&age=25")).toEqual({
"name": "Mayowa Fadare",
"age": "25",
});
});
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(items) {
if (!Array.isArray(items)) {
throw new Error("Input must be an array");
}
const counts = Object.create(null);
for (const item of items) {
if (typeof item !== "string" && typeof item !== "number") {
throw new Error("Items must be strings or numbers");
}
counts[item] = (counts[item] || 0) + 1;
}
return counts;
}

module.exports = tally;
19 changes: 15 additions & 4 deletions Sprint-2/implement/tally.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const tally = require("./tally.js");
const tally = require("./tally.js")


/**
* tally array
Expand All @@ -19,16 +20,26 @@ 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("tally on an array with multiple items returns correct counts", () => {
expect(tally(['a', 'b', 'a', 'c', 'b', 'a'])).toEqual({
a: 3, b: 2, 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 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("tally on an array with one item returns count of 1", () => {
expect(tally(['a'])).toEqual({ a: 1 });
});

// Given an invalid input like a string
// When passed to tally
// Then it should throw an error
test("tally throws error for non-array input", () => {
expect(() => tally("not an array")).toThrow("Input must be an array");
});
43 changes: 43 additions & 0 deletions Sprint-2/interpret/invent.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const invert = require("./invert.js");


// a) What is the current return value when invert is called with { a : 1 }
test("invert returns correct inverted object", () => {
const input = { a: 1, b: 2 };
const expectedOutput = { '1': 'a', '2': 'b' };
expect(invert(input)).toEqual(expectedOutput);
});

// b) What is the current return value when invert is called with { a: 1, b: 2 }
test("invert with numeric values returns string keys", () => {
const input = { a: 1, b: 2 };
const expectedOutput = { '1': 'a', '2': 'b' };
expect(invert(input)).toEqual(expectedOutput);
});

// c) What is the target return value when invert is called with {a : 1, b: 2}
test("invert with string values returns correct inverted object", () => {
const input = { a: '1', b: '2' };
const expectedOutput = { '1': 'a', '2': 'b' };
expect(invert(input)).toEqual(expectedOutput);
});

// c) What does Object.entries return? Why is it needed in this program?
test("Object.entries returns key-value pairs", () => {
const obj = { a: '1', b: '2' };
const entries = Object.entries(obj);
expect(entries).toEqual([['a', '1'], ['b', '2']]);
});
// d) Explain why the current return value is different from the target output
test("invert handles numeric values as strings", () => {
const input = { a: 1, b: 2 };
const expectedOutput = { '1': 'a', '2': 'b' };
expect(invert(input)).toEqual(expectedOutput);
});

// e) Fix the implementation of invert (and write tests to prove it's fixed!)
test("invert handles empty object", () => {
const input = {};
const expectedOutput = {};
expect(invert(input)).toEqual(expectedOutput);
});
25 changes: 18 additions & 7 deletions Sprint-2/interpret/invert.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,35 @@

// E.g. invert({x : 10, y : 20}), target output: {"10": "x", "20": "y"}

function invert(obj) {
function invert(obj) {
const invertedObj = {};

for (const [key, value] of Object.entries(obj)) {
invertedObj.key = value;
const stringValue = String(value); // Ensure value is a string
if (invertedObj.hasOwnProperty(value)) {
throw new Error(`Duplicate value found: ${value} for keys ${invertedObj[value]} and ${key}`);
}
invertedObj[stringValue] = key;
}

return invertedObj;
}

// a) What is the current return value when invert is called with { a : 1 }
module.exports = invert;

// a) What is the current return value when invert is called with { a : 1 }
//{key : 1} because invertedObj.key means object "invertedObj" has a key property with the exact name "key" and we need to add a key that its name is the value of key property.

// b) What is the current return value when invert is called with { a: 1, b: 2 }
//{key : 1, key : 2} because invertedObj.key means object "invertedObj" has a key property with the exact name "key" and we need to add a key that its name is the value of key property.

// c) What is the target return value when invert is called with {a : 1, b: 2}
//{1 : a ,2 : b} because invertedObj.key means object "invertedObj" has a key property with the exact name "key" and we need to add a key that its name is the value of key property.

// c) What does Object.entries return? Why is it needed in this program?
// d) What does Object.entries return? Why is it needed in this program?
//Object.entries returns an array of key-value pairs from the object.

// d) Explain why the current return value is different from the target output
// e) Explain why the current return value is different from the target output
//The current return value is different because the keys in the inverted object are being set to the string representation of the original values, while the target output expects the keys to be the original values themselves.

// e) Fix the implementation of invert (and write tests to prove it's fixed!)
// f) Fix the implementation of invert (and write tests to prove it's fixed!)
//The implementation has been fixed to ensure that the values are converted to strings before being used as keys in the inverted object. Additionally, it checks for duplicate values to prevent overwriting keys in the inverted object.
Loading