Hone logo
Hone
Problems

Achieving 100% Statement Coverage in Jest

In software development, robust testing is crucial for ensuring code quality and reliability. Statement coverage is a fundamental metric that measures whether every executable line of code in your program has been executed by your tests. This challenge will guide you through the process of achieving 100% statement coverage for a given TypeScript function using Jest.

Problem Description

Your task is to write Jest unit tests for a provided TypeScript function such that all executable statements within that function are covered. You will need to identify all possible execution paths and craft test cases that trigger each statement. The goal is to demonstrate your understanding of how to use Jest to achieve comprehensive statement coverage.

Key Requirements:

  • Write Jest tests for the given calculateDiscount function.
  • Ensure that 100% statement coverage is achieved for the calculateDiscount function.
  • The tests should be written in TypeScript.
  • The provided calculateDiscount function should not be modified.

Expected Behavior:

Your Jest tests should successfully execute all lines of code within the calculateDiscount function, as indicated by a coverage report.

Edge Cases to Consider:

  • What happens with invalid input types?
  • What are the boundaries for discount eligibility?
  • How are zero or negative values handled?

Examples

Example 1:

Input Function:
function calculateDiscount(price: number, quantity: number): number {
  let discountPercentage = 0;
  if (quantity > 10) {
    discountPercentage = 0.1; // 10% discount for more than 10 items
  }
  if (price > 100) {
    discountPercentage = Math.max(discountPercentage, 0.15); // Additional 15% if price > 100
  }
  return price * (1 - discountPercentage);
}

Input Test Case:
price = 50, quantity = 5

Expected Output (from tests):
The test case should execute the `discountPercentage = 0` path and return `50`.
Explanation: Neither condition (`quantity > 10` or `price > 100`) is met, so the discount remains 0. The function returns `50 * (1 - 0) = 50`.

Example 2:

Input Function: (same as Example 1)

Input Test Case:
price = 120, quantity = 15

Expected Output (from tests):
The test case should execute both `if` blocks and return `102`.
Explanation:
1. `quantity > 10` is true, `discountPercentage` becomes 0.1.
2. `price > 100` is true, `discountPercentage` becomes `Math.max(0.1, 0.15) = 0.15`.
The function returns `120 * (1 - 0.15) = 120 * 0.85 = 102`.

Example 3: (Edge Case)

Input Function: (same as Example 1)

Input Test Case:
price = 80, quantity = 12

Expected Output (from tests):
The test case should execute the first `if` block and then the second `if` block, returning `68`.
Explanation:
1. `quantity > 10` is true, `discountPercentage` becomes 0.1.
2. `price > 100` is false, `discountPercentage` remains 0.1.
The function returns `80 * (1 - 0.1) = 80 * 0.9 = 72`.

(Self-correction during example generation): The previous explanation for Example 3 was incorrect. The correct explanation for price = 80, quantity = 12 is:

  1. quantity > 10 is true, discountPercentage becomes 0.1.
  2. price > 100 is false, discountPercentage remains 0.1. The function returns 80 * (1 - 0.1) = 72.

Constraints

  • The calculateDiscount function must be tested using Jest.
  • You must aim for 100% statement coverage.
  • Jest configuration for coverage reporting should be set up to display statement coverage.
  • Tests should be written in TypeScript.

Notes

  • To run Jest with coverage, you typically use the command npx jest --coverage.
  • Examine the output of the coverage report to identify which statements are not being executed.
  • Think about how to create test inputs that will force the execution of every line of code.
  • Consider all possible branches within the if statements, including when conditions are true and false.
  • Remember that a statement is any executable piece of code, including assignments, function calls, and conditional branches.
Loading editor...
typescript