Implementing a Custom Jest Matcher: toBeUndefined
Jest provides a powerful assertion library for testing your JavaScript and TypeScript code. Sometimes, you might encounter scenarios where the built-in matchers don't perfectly fit your needs, or you want to create reusable, domain-specific assertions. This challenge focuses on understanding how Jest's custom matchers work by implementing one of its fundamental matchers: toBeUndefined.
Problem Description
Your task is to create a custom Jest matcher named toBeUndefined. This matcher should assert that a received value is undefined. This is a foundational matcher that helps ensure variables or function return values are explicitly not set, which can be crucial for managing state and preventing unexpected behavior in your applications.
Key Requirements:
- Implement the
toBeUndefinedmatcher: This matcher will be invoked when you useexpect(...).toBeUndefined(). - Handle
undefinedvalues: When the received value isundefined, the matcher should pass. - Handle non-
undefinedvalues: When the received value is anything other thanundefined, the matcher should fail with an appropriate message. - Provide clear failure messages: If the assertion fails, the message should clearly indicate that the received value was not
undefined.
Expected Behavior:
expect(undefined).toBeUndefined()should pass.expect(null).toBeUndefined()should fail.expect(0).toBeUndefined()should fail.expect("").toBeUndefined()should fail.expect({}).toBeUndefined()should fail.
Edge Cases:
- Consider how the matcher behaves with different primitive types and object types.
Examples
Example 1:
Input:
expect(undefined).toBeUndefined();
Output: (Assertion passes)
Explanation: The received value is undefined, which matches the expectation of toBeUndefined.
Example 2:
Input:
expect(null).toBeUndefined();
Output:
expect(null).toBeUndefined()
Expected: undefined
Received: null
Explanation: The received value is null, which is not undefined. The assertion fails, and the message clearly shows the expected and received values.
Example 3:
Input:
const myVariable; // This variable is implicitly undefined
expect(myVariable).toBeUndefined();
Output: (Assertion passes)
Explanation: myVariable is declared but not assigned a value, therefore its value is undefined. The custom matcher correctly identifies this.
Constraints
- The solution must be implemented in TypeScript.
- You should use Jest's custom matcher API.
- The matcher should be registered globally or within a specific test suite setup.
- The failure message should follow the common Jest convention of "Expected: X Received: Y".
Notes
To implement custom Jest matchers, you'll typically use expect.extend(). This method allows you to add new matchers to Jest's expect object. Each custom matcher is a function that receives the received value and should return an object with pass (a boolean indicating success) and message (a function that returns the error message if pass is false).
Think about how to structure your custom matcher function to correctly determine if the received value is undefined. Consider the strict equality operator (===) for accurate comparison.