Hone logo
Hone
Problems

Custom Jest toContain Matcher for Arrays

Jest is a popular JavaScript testing framework that provides a rich set of built-in matchers for asserting conditions in your tests. This challenge focuses on extending Jest by creating your own custom matcher, specifically one that checks if an array contains a specific value. This is a fundamental building block for creating more complex testing utilities.

Problem Description

Your task is to implement a custom Jest matcher named toContain that can be used to assert whether an array contains a specific element. This matcher should be compatible with Jest's custom matcher API and provide clear feedback on success or failure.

Key Requirements:

  1. Implement toContain: Create a function that takes the actual array and the expected element as arguments.
  2. Return Jest Matcher Result: The function should return an object with two properties:
    • pass: A boolean indicating whether the assertion passed (true if the element is found, false otherwise).
    • message: A string function that returns a descriptive message for failure (or success, if configured).
  3. Handle Various Data Types: The matcher should correctly identify the presence of primitives (numbers, strings, booleans) and objects/arrays as elements within the target array.
  4. Provide Meaningful Error Messages: When the assertion fails, the message function should return a helpful message indicating what was expected and what was received.

Expected Behavior:

  • expect([1, 2, 3]).toContain(2) should pass.
  • expect(['a', 'b', 'c']).toContain('d') should fail.
  • expect([{ id: 1 }, { id: 2 }]).toContain({ id: 1 }) should fail (unless deep equality is considered, which is not a requirement here – simple reference equality for objects is sufficient for this challenge).
  • const obj = { id: 1 }; expect([obj]).toContain(obj) should pass.

Edge Cases to Consider:

  • Empty arrays.
  • Arrays containing null, undefined, or NaN.
  • The expected element being null, undefined, or NaN.

Examples

Example 1:

Input:
expect([1, 2, 3]).toContain(2)

Output:
(Assertion passes)

Explanation: The number `2` is present in the array `[1, 2, 3]`.

Example 2:

Input:
expect(['apple', 'banana']).toContain('cherry')

Output:
(Assertion fails)
Expected array to contain "cherry", but it did not.

Explanation: The string "cherry" is not present in the array `['apple', 'banana']`.

Example 3:

Input:
const myObject = { name: 'Test' };
expect([1, myObject, 'hello']).toContain(myObject)

Output:
(Assertion passes)

Explanation: The specific object `myObject` is present by reference in the array.

Example 4 (Edge Case):

Input:
expect([]).toContain(5)

Output:
(Assertion fails)
Expected array to contain 5, but it did not.

Explanation: The array is empty, so it cannot contain `5`.

Constraints

  • The solution should be written in TypeScript.
  • The custom matcher should integrate with Jest's expect function. You'll likely need to use expect.extend().
  • For object comparison, simple reference equality is sufficient. Deep comparison is not required for this challenge.

Notes

  • Consider how you will handle the message function to provide dynamic error messages.
  • Think about how to check for the presence of NaN specifically, as NaN === NaN is false.
  • You can create a customMatchers.ts file and import it into your test setup.
Loading editor...
typescript