Hone logo
Hone
Problems

Custom toContain Matcher for Jest

Jest's built-in matchers are powerful, but sometimes you need a custom matcher to handle specific scenarios. This challenge asks you to create a custom Jest matcher called toContain that extends Jest's expect to verify if an array or string contains a specific value. This is useful for more readable and maintainable tests when checking for the presence of elements within collections.

Problem Description

You need to implement a custom Jest matcher named toContain. This matcher should work similarly to Jest's built-in toContain but be more flexible and potentially handle different data types gracefully. The matcher should accept a value to search for within the item being tested (which is assumed to be an array or a string).

What needs to be achieved:

  • Create a Jest custom matcher named toContain.
  • The matcher should accept a single argument: the value to search for.
  • The matcher should return true if the value is found within the item being tested (array or string).
  • The matcher should return false if the value is not found.
  • Provide a descriptive failure message when the value is not found.

Key Requirements:

  • The matcher must be compatible with Jest's assertion style.
  • The matcher should handle both arrays and strings as the item being tested.
  • The matcher should perform a strict equality check (===) for comparison.
  • The matcher should provide a clear and informative failure message.

Expected Behavior:

When used in a Jest test, the toContain matcher should behave as follows:

  • expect([1, 2, 3]).toContain(2) should pass.
  • expect([1, 2, 3]).toContain(4) should fail with a message indicating that 4 was not found in the array.
  • expect("hello").toContain("ell") should pass.
  • expect("hello").toContain("world") should fail with a message indicating that "world" was not found in the string.
  • expect([1, "2", 3]).toContain(2) should fail (strict equality).

Edge Cases to Consider:

  • The item being tested is not an array or a string. While not strictly required, handling this gracefully (e.g., throwing an error or returning false) would be good practice.
  • The value being searched for is null or undefined.
  • Empty arrays or strings.

Examples

Example 1:

Input: expect([1, 2, 3]).toContain(2);
Output: Pass
Explanation: The array [1, 2, 3] contains the value 2.

Example 2:

Input: expect("hello").toContain("world");
Output: Fail
Explanation: The string "hello" does not contain the substring "world". The failure message should indicate this.

Example 3:

Input: expect([1, "2"]).toContain(2);
Output: Fail
Explanation: Strict equality check fails. 2 !== "2".

Constraints

  • The matcher must be implemented in TypeScript.
  • The matcher should be compatible with Jest versions 25 or higher.
  • The matcher should not introduce any external dependencies.
  • The matcher should be reasonably performant for typical use cases (e.g., arrays and strings of moderate size).

Notes

  • You'll need to create a Jest custom matcher factory function.
  • Within the matcher factory, you'll define the matcher's logic and return an object with match, inverseMatch, and optionally negateMessage methods.
  • The match method is where the core comparison logic resides.
  • Consider using template literals to create informative failure messages.
  • Think about how to handle cases where the input is not an array or string. A simple check at the beginning of the match function can prevent unexpected errors.
Loading editor...
typescript