Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
fdc0069
Implemented a function getAngleType
i786m Oct 17, 2025
6825f69
Implemented a function isProperFraction
i786m Oct 18, 2025
be5d5ca
implemented getCard Value function
i786m Oct 18, 2025
cad7330
wrote tests for get angle type function
i786m Oct 18, 2025
7cbd9b7
wrote tests for proper fraction function
i786m Oct 22, 2025
bb78124
wrote tests for get card value function
i786m Oct 22, 2025
ed33a43
updated if condition for zero numerator
i786m Oct 28, 2025
6678a10
fix typo in comparison to if function
i786m Nov 1, 2025
716a310
Add CI/CD test coverage workflow for Sprint 3
Nov 3, 2025
f6933d2
Adjust coverage thresholds to 40% with 100% function coverage
Nov 3, 2025
7dad219
Simplify coverage reporting to avoid action errors
Nov 3, 2025
ec26710
Add comprehensive test reporting to GitHub Actions summary
Nov 3, 2025
64d8f8e
Use MishaKav/jest-coverage-comment for proper coverage reporting
Nov 3, 2025
5c265f2
Deploy coverage reports to GitHub Pages for browser viewing
Nov 3, 2025
b45e475
Rollback to simplified ArtiomTr jest-coverage-report-action
Nov 3, 2025
69c7817
Fix ArtiomTr action to use proper Jest report format
Nov 3, 2025
baaf318
Add PR write permissions for automatic coverage comments
Nov 3, 2025
003b0ec
Remove PR comment permissions
Nov 3, 2025
4c72c29
Refactor: Remove SH and using NodeJS / simpler approach
Nov 20, 2025
daece44
Refactor: PR write permissions for job
Nov 20, 2025
7ffdf3b
Refactor: PR write permissions for job
Nov 20, 2025
fff9ffb
Refactor: Added readme instructions for trainees awareness
Nov 20, 2025
e988e4e
Refactor: Revert back trigger to PR
Nov 20, 2025
61e08e2
Refactor: Revert back trigger to PR
Nov 20, 2025
50fd116
Refactor: Tuning workflow
Nov 20, 2025
c15ff9e
Refactor: adjusting token
Nov 20, 2025
f07827b
Refactor: Adjusting gh actions
Nov 20, 2025
4ac1f84
Refactor: removed coverage pr comments functionality
Nov 20, 2025
af00810
Refactor: Github actions warnings for parity issues or inline tests f…
Nov 20, 2025
ba84bab
Refactor: Adjusting warning message
Nov 20, 2025
d6d1d7e
Covered sprint 3 tests supporting
Nov 27, 2025
3c050ab
Covered sprint 3 tests supporting
Nov 27, 2025
00756ef
File names convention
Nov 27, 2025
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
32 changes: 32 additions & 0 deletions .github/workflows/test-coverage-1-implement-rewrite-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Test Coverage Report - Implement and rewrite

on:
pull_request:
branches:
- main
paths:
- 'Sprint-3/1-implement-and-rewrite-tests/**'

jobs:
test-coverage:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run Inline Assertion Tests & Verify Parity
run: node scripts/run-inline-tests.js
continue-on-error: true

- name: Run Jest Tests with Coverage
run: npx jest --config=jest.config.jest-tests.js --coverage --ci

Choose a reason for hiding this comment

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

the npm test command is defined in the package.json.Is there a reason you use npx to run the same command here?

28 changes: 28 additions & 0 deletions .github/workflows/test-coverage-2-practice-tdd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Test Coverage Report - Practice TDD

on:
pull_request:
branches:
- main
paths:
- 'Sprint-3/2-practice-tdd/**'

jobs:
test-coverage:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run Jest Tests with Coverage
run: npx jest --config=jest.config.jest-tests.js --coverage --ci
28 changes: 28 additions & 0 deletions .github/workflows/test-coverage-3-stretch.yml

Choose a reason for hiding this comment

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

This file looks the same as for coverage-2. Could they be combined?

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Test Coverage Report - Stretch

on:
pull_request:
branches:
- main
paths:
- 'Sprint-3/3-stretch/**'

jobs:
test-coverage:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run Jest Tests with Coverage
run: npx jest --config=jest.config.jest-tests.js --coverage --ci
19 changes: 19 additions & 0 deletions Sprint-3/1-implement-and-rewrite-tests/README.md

Choose a reason for hiding this comment

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

Test coverage runs for task 2 and task 3 in this sprint. Either the instructions should be replicated in those readmes, or a more general set of instructions should be given in the main sprint3 readme rather than here.

Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,22 @@ https://code.visualstudio.com/docs/editor/testing

> [!TIP]
> You can always run a single test file by running `npm test path/to/test-file.test.js`.

## Automated Checks for This Exercise

For **this specific exercise only**, when you create a pull request with changes to files in `Sprint-3/1-implement-and-rewrite-tests/`, automated checks will run:

### What runs automatically:

1. **Inline Assertion Tests** - Verifies your inline assertions (from the `implement` directory) match your Jest tests
2. **Jest Test Coverage** - Runs your Jest tests from `rewrite-tests-with-jest` and reports coverage

### How to view the results on your PR:

1. Open your pull request on GitHub
2. Scroll to the bottom - look for the **Checks** section
3. Find "Test Coverage Report"
4. Click **Details** to see the full output
5. A coverage report comment will also be posted on your PR

A ✅ green checkmark means all tests passed. A ❌ red X means something failed - click Details to see what went wrong.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,20 @@ function getAngleType(angle) {
return "Right angle";
}
// Run the tests, work out what Case 2 is testing, and implement the required code here.
if (angle < 90) {
return "Acute angle";
}
// Then keep going for the other cases, one at a time.
if (angle > 90 && angle < 180) {
return "Obtuse angle";
}
if (angle === 180) {
return "Straight angle";
}
if (angle > 180 && angle < 360) {
return "Reflex angle";
}

}

// The line below allows us to load the getAngleType function into tests in other files.
Expand Down Expand Up @@ -50,14 +63,19 @@ assertEquals(acute, "Acute angle");
// When the angle is greater than 90 degrees and less than 180 degrees,
// Then the function should return "Obtuse angle"
const obtuse = getAngleType(120);
assertEquals(obtuse, "Obtuse angle");
// ====> write your test here, and then add a line to pass the test in the function above

// Case 4: Identify Straight Angles:
// When the angle is exactly 180 degrees,
// Then the function should return "Straight angle"
// ====> write your test here, and then add a line to pass the test in the function above
const straight = getAngleType(180);
assertEquals(straight, "Straight angle");

// Case 5: Identify Reflex Angles:
// When the angle is greater than 180 degrees and less than 360 degrees,
// Then the function should return "Reflex angle"
// ====> write your test here, and then add a line to pass the test in the function above
// ====> write your test here, and then add a line to pass the test in the function above
const reflex = getAngleType(270);
assertEquals(reflex, "Reflex angle");
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,18 @@
// write one test at a time, and make it pass, build your solution up methodically

function isProperFraction(numerator, denominator) {
if (numerator < denominator) {
if (Math.abs(numerator) < Math.abs(denominator)) {
return true;
}
if (numerator >= denominator) {
return false;
}
if(numerator == 0 && denominator !== 0){
return true;
}
if (denominator === 0) {
return false;
}
}

// The line below allows us to load the isProperFraction function into tests in other files.
Expand Down Expand Up @@ -47,13 +56,48 @@ assertEquals(improperFraction, false);
// Explanation: The fraction -4/7 is a proper fraction because the absolute value of the numerator (4) is less than the denominator (7). The function should return true.
const negativeFraction = isProperFraction(-4, 7);
// ====> complete with your assertion

assertEquals(negativeFraction, true);
// Equal Numerator and Denominator check:
// Input: numerator = 3, denominator = 3
// target output: false
// Explanation: The fraction 3/3 is not a proper fraction because the numerator is equal to the denominator. The function should return false.
const equalFraction = isProperFraction(3, 3);
// ====> complete with your assertion

assertEquals(equalFraction, false);
// Stretch:
// What other scenarios could you test for?
// Zero Numerator check:
// Input: numerator = 0, denominator = 5
// target output: true
// Explanation: The fraction 0/5 is a proper fraction because the numerator (0) is less than the denominator (5). The function should return true.
const zeroNumerator = isProperFraction(0, 5);
// ====> complete with your assertion
assertEquals(zeroNumerator, true);
// Zero Denominator check:
// Input: numerator = 4, denominator = 0
// target output: false
// Explanation: The fraction 4/0 is undefined because division by zero is not allowed. The function should return false.
const zeroDenominator = isProperFraction(4, 0);
// ====> complete with your assertion
assertEquals(zeroDenominator, false);
// Negative Denominator check:
// Input: numerator = 3, denominator = -5
// target output: true
// Explanation: The fraction 3/-5 is a proper fraction because the absolute value of the numerator (3) is less than the absolute value of the denominator (5). The function should return true.
const negativeDenominator = isProperFraction(3, -5);
// ====> complete with your assertion
assertEquals(negativeDenominator, true);
// Both Negative check:
// Input: numerator = -2, denominator = -6
// target output: true
// Explanation: The fraction -2/-6 is a proper fraction because the absolute value of the numerator (2) is less than the absolute value of the denominator (6). The function should return true.
const bothNegative = isProperFraction(-2, -6);
// ====> complete with your assertion
assertEquals(bothNegative, true);
// Zero Numerator and Denominator check:
// Input: numerator = 0, denominator = 0
// target output: false
// Explanation: The fraction 0/0 is undefined. The function should return false.
const zeroNumeratorDenominator = isProperFraction(0, 0);
// ====> complete with your assertion
assertEquals(zeroNumeratorDenominator, false);
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,32 @@
// write one test at a time, and make it pass, build your solution up methodically
// just make one change at a time -- don't rush -- programmers are deep and careful thinkers
function getCardValue(card) {
if (rank === "A") {
return 11;
const rank = card.slice(0,-1)
const suit = card.slice(-1)
if (!["♠","♥","♦","♣"].includes(suit)) {
return "Invalid card rank.";
}
switch(rank) {
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
return parseInt(rank);
case "10":
case "J":
case "Q":
case "K":
return 10;
case "A":
return 11;
default:
return "Invalid card rank.";
}

}

// The line below allows us to load the getCardValue function into tests in other files.
Expand Down Expand Up @@ -40,18 +63,36 @@ assertEquals(aceofSpades, 11);
// Then it should return the numeric value corresponding to the rank (e.g., "5" should return 5).
const fiveofHearts = getCardValue("5♥");
// ====> write your test here, and then add a line to pass the test in the function above

assertEquals(fiveofHearts, 5);
// Handle Face Cards (J, Q, K):
// Given a card with a rank of "10," "J," "Q," or "K",
// When the function is called with such a card,
// Then it should return the value 10, as these cards are worth 10 points each in blackjack.
const kingofDiamonds = getCardValue("K♦");
assertEquals(kingofDiamonds, 10);

const tenofClubs = getCardValue("10♣");
assertEquals(tenofClubs, 10);

// Handle Ace (A):
// Given a card with a rank of "A",
// When the function is called with an Ace,
// Then it should, by default, assume the Ace is worth 11 points, which is a common rule in blackjack.

const aceofHearts = getCardValue("A♥");
assertEquals(aceofHearts, 11);
// Handle Invalid Cards:
// Given a card with an invalid rank (neither a number nor a recognized face card),
// When the function is called with such a card,
// Then it should throw an error indicating "Invalid card rank."

const invalidCard = getCardValue("1♠");
assertEquals(invalidCard, "Invalid card rank.");

const invalidCard2 = getCardValue("B♦");
assertEquals(invalidCard2, "Invalid card rank.");

const invalidCard3 = getCardValue("11");
assertEquals(invalidCard3, "Invalid card rank.");

const invalidCard4 = getCardValue("3😄");
assertEquals(invalidCard4, "Invalid card rank.");
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,25 @@ test("should identify right angle (90°)", () => {
// Case 2: Identify Acute Angles:
// When the angle is less than 90 degrees,
// Then the function should return "Acute angle"
test("should identify acute angle (<90°)", () => {
expect(getAngleType(45)).toEqual("Acute angle");
});

// Case 3: Identify Obtuse Angles:
// When the angle is greater than 90 degrees and less than 180 degrees,
// Then the function should return "Obtuse angle"

test("should identify obtuse angle (>90° and <180°)", () => {
expect(getAngleType(120)).toEqual("Obtuse angle");
});
// Case 4: Identify Straight Angles:
// When the angle is exactly 180 degrees,
// Then the function should return "Straight angle"

test("should identify straight angle (180°)", () => {
expect(getAngleType(180)).toEqual("Straight angle");
});
// Case 5: Identify Reflex Angles:
// When the angle is greater than 180 degrees and less than 360 degrees,
// Then the function should return "Reflex angle"
test("should identify reflex angle (>180° and <360°)", () => {
expect(getAngleType(270)).toEqual("Reflex angle");
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,30 @@ test("should return true for a proper fraction", () => {
});

// Case 2: Identify Improper Fractions:
test("should return false for an improper fraction", () => {
expect(isProperFraction(5, 2)).toEqual(false);
});

// Case 3: Identify Negative Fractions:

test("should return true for a negative proper fraction", () => {
expect(isProperFraction(-4, 7)).toEqual(true);
});
// Case 4: Identify Equal Numerator and Denominator:
test("should return false when numerator equals denominator", () => {
expect(isProperFraction(3, 3)).toEqual(false);
});

// Case 5: Zero Numerator:
test("should return true for zero numerator", () => {
expect(isProperFraction(0, 5)).toEqual(true);
});

// Case 6: Zero Denominator:
test("should return false for zero denominator", () => {
expect(isProperFraction(4, 0)).toEqual(false);
});

// Case 7: Negative Denominator:
test("should return true for negative denominator", () => {
expect(isProperFraction(3, -5)).toEqual(true);
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,27 @@ test("should return 11 for Ace of Spades", () => {
});

// Case 2: Handle Number Cards (2-10):
test("should return correct value for number cards", () => {
expect(getCardValue("2♣")).toEqual(2);
expect(getCardValue("5♦")).toEqual(5);
expect(getCardValue("10♥")).toEqual(10);
})
// Case 3: Handle 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);
})
// Case 4: Handle Ace (A):
test("should return 11 for Ace cards", () => {
expect(getCardValue("A♣")).toEqual(11);
expect(getCardValue("A♦")).toEqual(11);
expect(getCardValue("A♥")).toEqual(11);
})
// Case 5: Handle Invalid Cards:
test("should return Invalid card rank for invalid cards", () => {
expect(getCardValue("1♣")).toEqual("Invalid card rank.");
expect(getCardValue("11♦")).toEqual("Invalid card rank.");
expect(getCardValue("3")).toEqual("Invalid card rank.");
expect(getCardValue("3😄")).toEqual("Invalid card rank.");
})
Loading
Loading