Hone logo
Hone
Problems

Implement a Custom toBe Matcher for Jest

Jest is a popular JavaScript testing framework that provides powerful assertion utilities. One of the most fundamental assertions is toBe, which checks for strict equality (===) between the received value and the expected value. This challenge asks you to implement your own version of the toBe matcher within Jest's custom matcher framework. This exercise will deepen your understanding of Jest's extensibility and how assertions work under the hood.

Problem Description

Your task is to create a custom Jest matcher named myToBe. This matcher should behave identically to Jest's built-in toBe matcher. It needs to compare the received value with the expected value using strict equality (===).

Key Requirements:

  • Matcher Name: The custom matcher should be named myToBe.
  • Comparison: The matcher must use the strict equality operator (===) for comparison.
  • Success Message: When the assertion passes, it should report a success message indicating that the received value matches the expected value.
  • Failure Message: When the assertion fails, it should report a clear failure message indicating that the received value does not match the expected value, and display both the received and expected values.
  • Integration: The custom matcher should be registered with Jest so it can be used in your tests like any other matcher (e.g., expect(value).myToBe(expected)).

Expected Behavior:

  • If received === expected, the assertion should pass.
  • If received !== expected, the assertion should fail with an informative message.

Edge Cases to Consider:

  • Different primitive types (numbers, strings, booleans, null, undefined, symbols, bigints).
  • Object and array comparisons (remember === checks for reference equality for non-primitives).
  • NaN comparisons (note that NaN === NaN is false, but Jest's toBe handles this correctly by returning true for expect(NaN).toBe(NaN)).

Examples

Example 1: Primitive Equality

// In your test file:
expect(5).myToBe(5);
expect("hello").myToBe("hello");
expect(true).myToBe(true);
expect(null).myToBe(null);
expect(undefined).myToBe(undefined);

Output (for passing assertions): (No output, assertions pass silently)

Explanation: All primitive values match their expected counterparts using strict equality.

Example 2: Primitive Inequality

// In your test file:
expect(5).myToBe(10);
expect("hello").myToBe("world");
expect(true).myToBe(false);

Output (for failing assertions):

    Expected: 10
        Received: 5

or

    Expected: "world"
        Received: "hello"

or

    Expected: false
        Received: true

Explanation: The received and expected primitive values are different, leading to assertion failures.

Example 3: Object/Array Reference Equality

// In your test file:
const obj = { a: 1 };
const arr = [1, 2];
expect(obj).myToBe(obj); // Passing
expect(arr).myToBe(arr); // Passing
expect({ a: 1 }).myToBe({ a: 1 }); // Failing
expect([1, 2]).myToBe([1, 2]); // Failing

Output (for failing assertions):

    Expected: { a: 1 }
        Received: { a: 1 }

or

    Expected: [ 1, 2 ]
        Received: [ 1, 2 ]

Explanation: When comparing objects or arrays, === checks if they are the exact same instance in memory. Creating new objects/arrays, even with identical content, results in different references, hence the failures.

Example 4: NaN Handling

// In your test file:
expect(NaN).myToBe(NaN);

Output (for passing assertion): (No output, assertion passes silently)

Explanation: Jest's toBe matcher has a special case for NaN where NaN is considered equal to NaN. Your myToBe should replicate this behavior.

Constraints

  • The solution must be implemented in TypeScript.
  • You should not use any third-party libraries other than Jest itself.
  • The custom matcher must be registered globally or per-test-suite as per Jest's custom matcher documentation.

Notes

  • Refer to the Jest documentation on Extending Jest for guidance on how to add custom matchers.
  • Pay close attention to how Jest constructs failure messages. You'll need to provide a clear and informative message for both success and failure.
  • Consider how to handle the NaN case explicitly, as NaN === NaN evaluates to false in JavaScript. You'll need a specific check for this.
  • The goal is to replicate the behavior of toBe, not necessarily its exact internal implementation details beyond the core logic and messaging.
Loading editor...
typescript