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:
- Implement
toContain: Create a function that takes the actual array and the expected element as arguments. - Return Jest Matcher Result: The function should return an object with two properties:
pass: A boolean indicating whether the assertion passed (trueif the element is found,falseotherwise).message: A string function that returns a descriptive message for failure (or success, if configured).
- 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.
- Provide Meaningful Error Messages: When the assertion fails, the
messagefunction 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, orNaN. - The expected element being
null,undefined, orNaN.
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
expectfunction. You'll likely need to useexpect.extend(). - For object comparison, simple reference equality is sufficient. Deep comparison is not required for this challenge.
Notes
- Consider how you will handle the
messagefunction to provide dynamic error messages. - Think about how to check for the presence of
NaNspecifically, asNaN === NaNisfalse. - You can create a
customMatchers.tsfile and import it into your test setup.