Skip to content

Commit 5ee78d2

Browse files
sprint3 complete
1 parent 6dbd3b5 commit 5ee78d2

8 files changed

Lines changed: 578 additions & 0 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Implement solutions and rewrite tests with Jest
2+
3+
Before writing any code, please read the [Testing Function Guide](testing-guide.md) to learn how
4+
to choose test values that thoroughly test a function.
5+
6+
## 1 Implement solutions
7+
8+
In the `implement` directory you've got a number of functions you'll need to implement.
9+
For each function, you also have a number of different cases you'll need to check for your function.
10+
11+
Write your implementation and your tests to cover the cases the function should fulfil.
12+
13+
Here is a recommended order:
14+
15+
1. `1-get-angle-type.js`
16+
2. `2-is-proper-fraction.js`
17+
3. `3-get-card-value.js`
18+
19+
## 2 Rewrite tests with Jest
20+
21+
`console.log` is most often used as a debugging tool. We use to inspect the state of our program during runtime.
22+
23+
We can use `console.assert` to write assertions: however, it is not very easy to use when writing large test suites. In the first section, Implement, we used a custom "helper function" to make our assertions more readable.
24+
25+
Jest is a whole library of helper functions we can use to make our assertions more readable and easier to write.
26+
27+
Your new task is to write the same tests as you wrote in the `implement` directory, but using Jest instead of `console.assert`.
28+
29+
You shouldn't have to change the contents of `implement` to write these tests.
30+
31+
There are files for your Jest tests in the `rewrite-tests-with-jest` directory. They will automatically use the functions you already implemented.
32+
33+
You can run all the tests in this repo by running `npm test` in your terminal. However, VSCode has a built-in test runner that you can use to run the tests, and this should make it much easier to focus on building up your test cases one at a time.
34+
35+
https://code.visualstudio.com/docs/editor/testing
36+
37+
1. Go to rewrite-tests-with-jest/1-get-angle-type.test.js
38+
2. Click the green play button to run the test. It's on the left of the test function in the gutter.
39+
3. Read the output in the TEST_RESULTS tab at the bottom of the screen.
40+
4. Explore all the tests in this repo by opening the TEST EXPLORER tab. The logo is a beaker.
41+
42+
![VSCode Test Runner](../../run-this-test.png)
43+
44+
![Test Results](../../test-results-output.png)
45+
46+
> [!TIP]
47+
> You can always run a single test file by running `npm test path/to/test-file.test.js`.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Implement a function getAngleType
2+
//
3+
// When given an angle in degrees, it should return a string indicating the type of angle:
4+
// - "Acute angle" for angles greater than 0° and less than 90°
5+
// - "Right angle" for exactly 90°
6+
// - "Obtuse angle" for angles greater than 90° and less than 180°
7+
// - "Straight angle" for exactly 180°
8+
// - "Reflex angle" for angles greater than 180° and less than 360°
9+
// - "Invalid angle" for angles outside the valid range.
10+
11+
// Assumption: The parameter is a valid number. (You do not need to handle non-numeric inputs.)
12+
13+
// Acceptance criteria:
14+
// After you have implemented the function, write tests to cover all the cases, and
15+
// execute the code to ensure all tests pass.
16+
17+
function getAngleType(angle) {
18+
// TODO: Implement this function
19+
}
20+
21+
// The line below allows us to load the getAngleType function into tests in other files.
22+
// This will be useful in the "rewrite tests with jest" step.
23+
module.exports = getAngleType;
24+
25+
// This helper function is written to make our assertions easier to read.
26+
// If the actual output matches the target output, the test will pass
27+
function assertEquals(actualOutput, targetOutput) {
28+
console.assert(
29+
actualOutput === targetOutput,
30+
`Expected ${actualOutput} to equal ${targetOutput}`
31+
);
32+
}
33+
34+
// TODO: Write tests to cover all cases, including boundary and invalid cases.
35+
// Example: Identify Right Angles
36+
const right = getAngleType(90);
37+
assertEquals(right, "Right angle");
38+
39+
//
40+
41+
function getAngleType(angle) {
42+
if (angle > 0 && angle < 90) {
43+
return "Acute angle";
44+
} else if (angle === 90) {
45+
return "Right angle";
46+
} else if (angle > 90 && angle < 180) {
47+
return "Obtuse angle";
48+
} else if (angle === 180) {
49+
return "Straight angle";
50+
} else if (angle > 180 && angle < 360) {
51+
return "Reflex angle";
52+
} else {
53+
return "Invalid angle";
54+
}
55+
}
56+
57+
module.exports = getAngleType;
58+
59+
function assertEquals(actualOutput, targetOutput) {
60+
console.assert(
61+
actualOutput === targetOutput,
62+
`Expected ${actualOutput} to equal ${targetOutput}`
63+
);
64+
}
65+
66+
// Tests
67+
assertEquals(getAngleType(45), "Acute angle");
68+
assertEquals(getAngleType(90), "Right angle");
69+
assertEquals(getAngleType(120), "Obtuse angle");
70+
assertEquals(getAngleType(180), "Straight angle");
71+
assertEquals(getAngleType(270), "Reflex angle");
72+
73+
assertEquals(getAngleType(0), "Invalid angle");
74+
assertEquals(getAngleType(-10), "Invalid angle");
75+
assertEquals(getAngleType(360), "Invalid angle");
76+
assertEquals(getAngleType(500), "Invalid angle");
77+
78+
console.log("All tests passed!");
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Implement a function isProperFraction,
2+
// when given two numbers, a numerator and a denominator, it should return true if
3+
// the given numbers form a proper fraction, and false otherwise.
4+
5+
// Assumption: The parameters are valid numbers (not NaN or Infinity).
6+
7+
// Note: If you are unfamiliar with proper fractions, please look up its mathematical definition.
8+
9+
// Acceptance criteria:
10+
// After you have implemented the function, write tests to cover all the cases, and
11+
// execute the code to ensure all tests pass.
12+
13+
function isProperFraction(numerator, denominator) {
14+
// TODO: Implement this function
15+
}
16+
17+
// The line below allows us to load the isProperFraction function into tests in other files.
18+
// This will be useful in the "rewrite tests with jest" step.
19+
module.exports = isProperFraction;
20+
21+
// Here's our helper again
22+
function assertEquals(actualOutput, targetOutput) {
23+
console.assert(
24+
actualOutput === targetOutput,
25+
`Expected ${actualOutput} to equal ${targetOutput}`
26+
);
27+
}
28+
29+
// TODO: Write tests to cover all cases.
30+
// What combinations of numerators and denominators should you test?
31+
32+
// Example: 1/2 is a proper fraction
33+
assertEquals(isProperFraction(1, 2), true);
34+
35+
//
36+
37+
function isProperFraction(numerator, denominator) {
38+
if (denominator === 0) {
39+
return false;
40+
}
41+
42+
return Math.abs(numerator) < Math.abs(denominator);
43+
}
44+
45+
// Export for later testing
46+
module.exports = isProperFraction;
47+
48+
// Helper function
49+
function assertEquals(actualOutput, targetOutput) {
50+
console.assert(
51+
actualOutput === targetOutput,
52+
`Expected ${actualOutput} to equal ${targetOutput}`
53+
);
54+
}
55+
56+
// TESTS
57+
58+
// Proper fractions
59+
assertEquals(isProperFraction(1, 2), true);
60+
assertEquals(isProperFraction(3, 4), true);
61+
62+
// Not proper (equal)
63+
assertEquals(isProperFraction(5, 5), false);
64+
65+
// Not proper (numerator bigger)
66+
assertEquals(isProperFraction(7, 4), false);
67+
68+
// Zero numerator
69+
assertEquals(isProperFraction(0, 5), true);
70+
71+
// Invalid denominator
72+
assertEquals(isProperFraction(1, 0), false);
73+
74+
// Negative values
75+
assertEquals(isProperFraction(-1, 3), true);
76+
assertEquals(isProperFraction(-5, 2), false);
77+
78+
console.log("✅ All tests passed");
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// This problem involves playing cards: https://en.wikipedia.org/wiki/Standard_52-card_deck
2+
3+
// Implement a function getCardValue, when given a string representing a playing card,
4+
// should return the numerical value of the card.
5+
6+
// A valid card string will contain a rank followed by the suit.
7+
// The rank can be one of the following strings:
8+
// "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"
9+
// The suit can be one of the following emojis:
10+
// "♠", "♥", "♦", "♣"
11+
// For example: "A♠", "2♥", "10♥", "J♣", "Q♦", "K♦".
12+
13+
// When the card is an ace ("A"), the function should return 11.
14+
// When the card is a face card ("J", "Q", "K"), the function should return 10.
15+
// When the card is a number card ("2" to "10"), the function should return its numeric value.
16+
17+
// When the card string is invalid (not following the above format), the function should
18+
// throw an error.
19+
20+
// Acceptance criteria:
21+
// After you have implemented the function, write tests to cover all the cases, and
22+
// execute the code to ensure all tests pass.
23+
24+
function getCardValue(card) {
25+
// TODO: Implement this function
26+
}
27+
28+
// The line below allows us to load the getCardValue function into tests in other files.
29+
// This will be useful in the "rewrite tests with jest" step.
30+
module.exports = getCardValue;
31+
32+
// Helper functions to make our assertions easier to read.
33+
function assertEquals(actualOutput, targetOutput) {
34+
console.assert(
35+
actualOutput === targetOutput,
36+
`Expected ${actualOutput} to equal ${targetOutput}`
37+
);
38+
}
39+
40+
// TODO: Write tests to cover all outcomes, including throwing errors for invalid cards.
41+
// Examples:
42+
assertEquals(getCardValue("9♠"), 9);
43+
44+
// Handling invalid cards
45+
try {
46+
getCardValue("invalid");
47+
48+
// This line will not be reached if an error is thrown as expected
49+
console.error("Error was not thrown for invalid card 😢");
50+
} catch (e) {
51+
console.log("Error thrown for invalid card 🎉");
52+
}
53+
54+
// What other invalid card cases can you think of?
55+
56+
function getCardValue(card) {
57+
const cardPattern = /^(A|[2-9]|10|J|Q|K)[]$/;
58+
59+
if (!cardPattern.test(card)) {
60+
throw new Error("Invalid card");
61+
}
62+
63+
const rank = card.slice(0, -1);
64+
65+
if (rank === "A") {
66+
return 11;
67+
}
68+
69+
if (["J", "Q", "K"].includes(rank)) {
70+
return 10;
71+
}
72+
73+
return Number(rank);
74+
}
75+
76+
module.exports = getCardValue;
77+
78+
// Helper
79+
function assertEquals(actualOutput, targetOutput) {
80+
console.assert(
81+
actualOutput === targetOutput,
82+
`Expected ${actualOutput} to equal ${targetOutput}`
83+
);
84+
}
85+
86+
// Tests
87+
assertEquals(getCardValue("2♥"), 2);
88+
assertEquals(getCardValue("9♠"), 9);
89+
assertEquals(getCardValue("10♦"), 10);
90+
91+
assertEquals(getCardValue("A♣"), 11);
92+
93+
assertEquals(getCardValue("J♣"), 10);
94+
assertEquals(getCardValue("Q♦"), 10);
95+
assertEquals(getCardValue("K♥"), 10);
96+
97+
// Invalid tests
98+
try {
99+
getCardValue("invalid");
100+
console.error("❌ Failed");
101+
} catch {
102+
console.log("✅ Invalid text");
103+
}
104+
105+
try {
106+
getCardValue("1♠");
107+
console.error("❌ Failed");
108+
} catch {
109+
console.log("✅ Invalid rank");
110+
}
111+
112+
try {
113+
getCardValue("AX");
114+
console.error("❌ Failed");
115+
} catch {
116+
console.log("✅ Invalid suit");
117+
}
118+
119+
console.log("🎉 Tests completed");
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// This statement loads the getAngleType function you wrote in the implement directory.
2+
// We will use the same function, but write tests for it using Jest in this file.
3+
const getAngleType = require("../implement/1-get-angle-type");
4+
5+
// TODO: Write tests in Jest syntax to cover all cases/outcomes,
6+
// including boundary and invalid cases.
7+
8+
// Case 1: Acute angles
9+
test(`should return "Acute angle" when (0 < angle < 90)`, () => {
10+
// Test various acute angles, including boundary cases
11+
expect(getAngleType(1)).toEqual("Acute angle");
12+
expect(getAngleType(45)).toEqual("Acute angle");
13+
expect(getAngleType(89)).toEqual("Acute angle");
14+
});
15+
16+
// Case 2: Right angle
17+
// Case 3: Obtuse angles
18+
// Case 4: Straight angle
19+
// Case 5: Reflex angles
20+
// Case 6: Invalid angles
21+
22+
// This statement loads the getAngleType function you wrote in the implement directory.
23+
const getAngleType = require("../implement/1-get-angle-type");
24+
25+
// Case 1: Acute angles
26+
test(`should return "Acute angle" when (0 < angle < 90)`, () => {
27+
expect(getAngleType(1)).toEqual("Acute angle");
28+
expect(getAngleType(45)).toEqual("Acute angle");
29+
expect(getAngleType(89)).toEqual("Acute angle");
30+
});
31+
32+
// Case 2: Right angle
33+
test(`should return "Right angle" when angle is 90`, () => {
34+
expect(getAngleType(90)).toEqual("Right angle");
35+
});
36+
37+
// Case 3: Obtuse angles
38+
test(`should return "Obtuse angle" when (90 < angle < 180)`, () => {
39+
expect(getAngleType(91)).toEqual("Obtuse angle");
40+
expect(getAngleType(120)).toEqual("Obtuse angle");
41+
expect(getAngleType(179)).toEqual("Obtuse angle");
42+
});
43+
44+
// Case 4: Straight angle
45+
test(`should return "Straight angle" when angle is 180`, () => {
46+
expect(getAngleType(180)).toEqual("Straight angle");
47+
});
48+
49+
// Case 5: Reflex angles
50+
test(`should return "Reflex angle" when (180 < angle < 360)`, () => {
51+
expect(getAngleType(181)).toEqual("Reflex angle");
52+
expect(getAngleType(270)).toEqual("Reflex angle");
53+
expect(getAngleType(359)).toEqual("Reflex angle");
54+
});
55+
56+
// Case 6: Invalid angles
57+
test(`should return "Invalid angle" for invalid values`, () => {
58+
expect(getAngleType(0)).toEqual("Invalid angle");
59+
expect(getAngleType(-1)).toEqual("Invalid angle");
60+
expect(getAngleType(360)).toEqual("Invalid angle");
61+
expect(getAngleType(500)).toEqual("Invalid angle");
62+
});

0 commit comments

Comments
 (0)