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
9 changes: 4 additions & 5 deletions Sprint-3/1-implement-and-rewrite-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ to choose test values that thoroughly test a function.

## 1 Implement solutions

In the `implement` directory you've got a number of functions you'll need to implement.
For each function, you also have a number of different cases you'll need to check for your function.
Here is a recommended order:

Write your assertions and build up your program case by case. Don't rush to a solution. The point of these assignments is to learn how to write assertions and build up a program step by step.
1. `1-get-angle-type.js`In the `implement` directory you've got a number of functions you'll need to implement.
For each function, you also have a number of different cases you'll need to check for your function.

Here is a recommended order:
Write your assertions and build up your program case by case. Don't rush to a solution. The point of these assignments is to learn how to write assertions and build up a program step by step.

1. `1-get-angle-type.js`
2. `2-is-proper-fraction.js`
3. `3-get-card-value.js`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,19 @@
// execute the code to ensure all tests pass.

function getAngleType(angle) {
// TODO: Implement this function
if (angle > 0 && angle < 90) {
return "Acute angle";
} else if (angle === 90) {
return "Right angle";
} else if (angle > 90 && angle < 180) {
return "Obtuse angle";
} else if (angle === 180) {
return "Straight angle";
} else if (angle > 180 && angle < 360) {
return "Reflex angle";
} else {
return "Invalid angle";
}
}

// The line below allows us to load the getAngleType function into tests in other files.
Expand All @@ -27,11 +39,29 @@ module.exports = getAngleType;
function assertEquals(actualOutput, targetOutput) {
console.assert(
actualOutput === targetOutput,
`Expected ${actualOutput} to equal ${targetOutput}`
`Expected ${actualOutput} to equal ${targetOutput}`,
);
}

// TODO: Write tests to cover all cases, including boundary and invalid cases.
// Example: Identify Right Angles
const right = getAngleType(90);
let invalid = getAngleType(0);
assertEquals(invalid, "Invalid angle");
let acute = getAngleType(1);
assertEquals(acute, "Acute angle");
acute = getAngleType(89);
assertEquals(acute, "Acute angle");
let right = getAngleType(90);
assertEquals(right, "Right angle");
let obtuse = getAngleType(91);
assertEquals(obtuse, "Obtuse angle");
obtuse = getAngleType(179);
assertEquals(obtuse, "Obtuse angle");
const straight = getAngleType(180);
assertEquals(straight, "Straight angle");
let reflex = getAngleType(181);
assertEquals(reflex, "Reflex angle");
reflex = getAngleType(359);
assertEquals(reflex, "Reflex angle");
invalid = getAngleType(400);
assertEquals(invalid, "Invalid angle");
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
// execute the code to ensure all tests pass.

function isProperFraction(numerator, denominator) {
// TODO: Implement this function
if (denominator === 0) {
return false;
}
return Math.abs(numerator) < Math.abs(denominator);
Copy link
Contributor

Choose a reason for hiding this comment

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

The indentation is off. Looks like you may not have successfully assigned "prettier" as your default JS formatter.


}

// The line below allows us to load the isProperFraction function into tests in other files.
Expand All @@ -22,7 +26,7 @@ module.exports = isProperFraction;
function assertEquals(actualOutput, targetOutput) {
console.assert(
actualOutput === targetOutput,
`Expected ${actualOutput} to equal ${targetOutput}`
`Expected ${actualOutput} to equal ${targetOutput}`,
);
}

Expand All @@ -31,3 +35,10 @@ function assertEquals(actualOutput, targetOutput) {

// Example: 1/2 is a proper fraction
assertEquals(isProperFraction(1, 2), true);
assertEquals(isProperFraction(5, 4), false);
assertEquals(isProperFraction(3, 3), false);
assertEquals(isProperFraction(0, 5), true);
assertEquals(isProperFraction(1, 0), false);
assertEquals(isProperFraction(-1, 2), true);
assertEquals(isProperFraction(1, -2), true);
assertEquals(isProperFraction(-1, -2), true);
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,86 @@
// execute the code to ensure all tests pass.

function getCardValue(card) {
// TODO: Implement this function
if (typeof card !== "string" || card.length < 2) {
throw new Error("Invalid card");
}
const suit = card.slice(-1);
const rank = card.slice(0, -1);

const validSuits = ["♠", "♥", "♦", "♣"];
const validRanks = [
"A",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"J",
"Q",
"K",
];

if (!validSuits.includes(suit) || !validRanks.includes(rank)) {
throw new Error("Invalid card");
} else if (rank == "A") {
return 11;
} else if (["J", "Q", "K"].includes(rank)) {
return 10;
} else {
return Number(rank);
}
}

// The line below allows us to load the getCardValue function into tests in other files.
// This will be useful in the "rewrite tests with jest" step.
//module.exports = getCardValue;
module.exports = getCardValue;

// Helper functions to make our assertions easier to read.
function assertEquals(actualOutput, targetOutput) {
console.assert(
actualOutput === targetOutput,
`Expected ${actualOutput} to equal ${targetOutput}`
`Expected ${actualOutput} to equal ${targetOutput}`,
);
}

// TODO: Write tests to cover all outcomes, including throwing errors for invalid cards.
// Examples:
assertEquals(getCardValue("9♠"), 9);
assertEquals(getCardValue("A♠"), 11);
assertEquals(getCardValue("K♦"), 10);
assertEquals(getCardValue("10♥"), 10);

// Handling invalid cards
try {
getCardValue("invalid");
getCardValue("11♠");
console.error("Error was not thrown for invalid card");
} catch (e) {}
try {
getCardValue("A?");
console.error("Error was not thrown for invalid card");
} catch (e) {}
try {
getCardValue("A");

console.error("Error was not thrown for invalid card");
} catch (e) {}
try {
getCardValue(10);

// This line will not be reached if an error is thrown as expected
console.error("Error was not thrown for invalid card");
} catch (e) {}

// What other invalid card cases can you think of?
//try {
//getCardValue("AA");
//console.error("Error was not thrown for invalid card");
//} catch (e) {}
//try {
//getCardValue("1♠");

//console.error("Error was not thrown for invalid card");
//} catch (e) {}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,27 @@ const getAngleType = require("../implement/1-get-angle-type");
test(`should return "Acute angle" when (0 < angle < 90)`, () => {
// Test various acute angles, including boundary cases
expect(getAngleType(1)).toEqual("Acute angle");
expect(getAngleType(45)).toEqual("Acute angle");
expect(getAngleType(89)).toEqual("Acute angle");
});
test(`should return "Right angle" when (angle = 90)`, () => {
expect(getAngleType(90)).toEqual("Right angle");
});
test(`should return"Obtuse angle" when (90 < angle< 180)`, () => {
expect(getAngleType(91)).toEqual("Obtuse angle");
expect(getAngleType(179)).toEqual("Obtuse angle");
});
test(`should return "Straight angle" when ( angle = 180)`, () => {
expect(getAngleType(180)).toEqual("Straight angle");
});
test(`should return "Reflex angle" when (180 < angle <360)`, () => {
expect(getAngleType(181)).toEqual("Reflex angle");
expect(getAngleType(359)).toEqual("Reflex angle");
});
test(`should return "invalid angle when angles outside the valid range`, () => {
expect(getAngleType(0)).toEqual("Invalid angle");
expect(getAngleType(360)).toEqual("Invalid angle");
expect(getAngleType(-10)).toEqual("Invalid angle");
});

// Case 2: Right angle
// Case 3: Obtuse angles
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,24 @@ const isProperFraction = require("../implement/2-is-proper-fraction");

// TODO: Write tests in Jest syntax to cover all combinations of positives, negatives, zeros, and other categories.

// Special case: numerator is zero

test(`should return false when denominator is zero`, () => {
expect(isProperFraction(1, 0)).toEqual(false);
});
test(`Should return true when numerator is zero`, () => {
expect(isProperFraction(0, 5)).toEqual(true);
});
test(`should return true when denominator is greater than numerator`, () => {
expect(isProperFraction(1, 2)).toEqual(true);
});
test(`should return false when numerator is greater than denominator`, () => {
expect(isProperFraction(5, 4)).toEqual(false);
});
test(`should return false when numerator is equals to denominator`, () => {
expect(isProperFraction(3, 3)).toEqual(false);
});
test("should return true when abs(numerator) < abs(denominator)", () => {
expect(isProperFraction(-1, 2)).toEqual(true);
expect(isProperFraction(1, -2)).toEqual(true);
expect(isProperFraction(-1, -2)).toEqual(true);
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,37 @@ const getCardValue = require("../implement/3-get-card-value");
test(`Should return 11 when given an ace card`, () => {
expect(getCardValue("A♠")).toEqual(11);
});

// Suggestion: Group the remaining test data into these categories:
// Number Cards (2-10)
test("should return the value of number cards (2–10)", () => {
expect(getCardValue("2♣")).toEqual(2);
expect(getCardValue("5♦")).toEqual(5);
expect(getCardValue("9♥")).toEqual(9);
expect(getCardValue("10♠")).toEqual(10);
});
// Face Cards (J, Q, K)
test("should return 10 for face cards", () => {
expect(getCardValue("J♣")).toEqual(10);
expect(getCardValue("Q♦")).toEqual(10);
expect(getCardValue("K♥")).toEqual(10);
});
// Invalid Cards
test("should throw error for invalid ranks", () => {
expect(() => getCardValue("11♠")).toThrow();
});

test("should throw error for invalid suits", () => {
expect(() => getCardValue("A?")).toThrow();
});

test("should throw error for missing suits", () => {
expect(() => getCardValue("A")).toThrow();
});

test("should throw error for non-string input", () => {
expect(() => getCardValue(10)).toThrow();
});

// To learn how to test whether a function throws an error as expected in Jest,
// please refer to the Jest documentation:
// https://jestjs.io/docs/expect#tothrowerror

24 changes: 13 additions & 11 deletions Sprint-3/1-implement-and-rewrite-tests/testing-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ Input ──▶ Function ──▶ Output
```

A function

- Takes **input** (via **arguments**)
- Does some work
- Produces **one output** (via a **return value**)

Example:

```
Expand All @@ -19,17 +20,18 @@ sum(2, 3) → 5

Important idea: the same input should produce the same output.


## 2. Testing Means Predicting

Testing means:
> If I give this input, what output should I get?
Testing means:

> If I give this input, what output should I get?

## 3. Choosing Good Test Values

### Step 1: Determining the space of possible inputs

Ask:

- What type of value is expected?
- What values make sense?
- If they are numbers:
Expand All @@ -39,7 +41,7 @@ Ask:
- What are their length and patterns?
- What values would not make sense?

### Step 2: Choosing Good Test Values
### Step 2: Choosing Good Test Values

#### Normal Cases

Expand All @@ -48,10 +50,9 @@ These confirm that the function works in normal use.
- What does a typical, ordinary input look like?
- Are there multiple ordinary groups of inputs? e.g. for an age checking function, maybe there are "adults" and "children" as expected ordinary groups of inputs.


#### Boundary Cases

Test values exactly at, just inside, and just outside defined ranges.
Test values exactly at, just inside, and just outside defined ranges.
These values are where logic breaks most often.

#### Consider All Outcomes
Expand All @@ -64,6 +65,7 @@ Every outcome must be reached by at least one test.
#### Crossing the Edges and Invalid Values

This tests how the function behaves when assumptions are violated.

- What happens when input is outside of the expected range?
- What happens when input is not of the expected type?
- What happens when input is not in the expected format?
Expand All @@ -73,18 +75,18 @@ This tests how the function behaves when assumptions are violated.
### 1. Using `console.assert()`

```javascript
// Report a failure only when the first argument is false
console.assert( sum(4, 6) === 10, "Expected 4 + 6 to equal 10" );
// Report a failure only when the first argument is false
console.assert(sum(4, 6) === 10, "Expected 4 + 6 to equal 10");
```

It is simpler than using `if-else` and requires no setup.

### 2. Jest Testing Framework

```javascript
test("Should correctly return the sum of two positive numbers", () => {
expect( sum(4, 6) ).toEqual(10);
... // Can test multiple samples
... // Can test multiple samples
});

```
Expand Down
Loading