Hone logo
Hone
Problems

Custom Jest Matcher: Resolves for Promises

This challenge asks you to create a custom Jest matcher specifically designed to test asynchronous functions that return Promises. Testing Promises directly with standard Jest matchers can be cumbersome; a dedicated resolves matcher simplifies this process, making your tests more readable and maintainable. This is a common need in modern JavaScript development, especially when working with asynchronous operations like API calls or database interactions.

Problem Description

You need to implement a custom Jest matcher named resolves. This matcher will take a Promise as input and verify that it resolves with a specific value. The matcher should behave similarly to Jest's resolves matcher, but you'll be building it from scratch.

What needs to be achieved:

  • Create a Jest custom matcher named resolves.
  • The matcher should accept a Promise and a expectedValue as arguments.
  • The matcher should resolve when the Promise resolves with the expectedValue.
  • The matcher should fail when the Promise rejects or resolves with a different value.
  • The matcher should provide a clear error message when it fails, indicating the expected and actual values.

Key Requirements:

  • The matcher must be asynchronous to handle the Promise resolution.
  • The matcher must use expect(promise).resolves internally to verify the promise resolves.
  • The matcher must handle both successful resolution and rejection of the Promise.
  • The matcher should provide a descriptive failure message.

Expected Behavior:

  • If the Promise resolves with the expectedValue, the matcher should pass.
  • If the Promise rejects, the matcher should fail with a message indicating rejection.
  • If the Promise resolves with a value different from the expectedValue, the matcher should fail with a message indicating the mismatch.

Edge Cases to Consider:

  • Promises that resolve immediately.
  • Promises that reject immediately.
  • Promises that resolve after a delay.
  • Promises that never resolve (though Jest should eventually time out).
  • expectedValue being a primitive type (string, number, boolean, etc.).
  • expectedValue being an object (consider deep equality checks if needed, though for simplicity, a strict equality check is acceptable).

Examples

Example 1:

Input: promiseThatResolvesWithValue(5)
Output: resolves.with(5) passes
Explanation: The promise resolves with the value 5, which matches the expected value.

Example 2:

Input: promiseThatResolvesWithValue("hello")
Output: resolves.with("world") fails
Explanation: The promise resolves with "hello", but the expected value is "world". The matcher fails with a descriptive error message.

Example 3:

Input: promiseThatRejects()
Output: resolves.with(10) fails
Explanation: The promise rejects, so the matcher fails, indicating that the promise did not resolve.

Constraints

  • The matcher must be implemented in TypeScript.
  • The matcher should not introduce any external dependencies beyond Jest itself.
  • The matcher should be reasonably performant; avoid unnecessary computations.
  • The matcher should be compatible with Jest's standard error reporting.

Notes

  • You'll need to use Jest's expect function to create the matcher.
  • Consider using async/await to handle the asynchronous nature of Promises.
  • Think about how to provide a clear and informative error message when the matcher fails.
  • The promiseThatResolvesWithValue and promiseThatRejects functions are assumed to be defined elsewhere and return Promises as described in the examples. You don't need to implement them. They are for testing purposes.
  • Focus on the core logic of the resolves matcher. Error handling and edge case coverage are important, but prioritize a functional and understandable implementation.
Loading editor...
typescript