Implement arrayContaining Matcher in Jest
You're tasked with extending Jest's assertion capabilities by implementing a custom matcher called arrayContaining. This matcher is crucial for asserting that a given array contains specific elements, regardless of their order or duplicates, which is a common requirement in testing.
Problem Description
Your goal is to create a Jest custom matcher that checks if an array contains all the elements present in another array. The order of elements should not matter, and the matcher should correctly handle cases where the expected array has duplicate elements.
Key Requirements:
- Implement a Jest custom matcher named
arrayContaining. - This matcher should accept an array of expected elements as its argument.
- It should return
trueif the actual received array contains all the elements from the expected array. - The order of elements in the received array does not affect the outcome.
- The matcher should correctly account for the frequency of duplicate elements in the expected array.
Expected Behavior:
expect([1, 2, 3]).arrayContaining([2, 1])should pass.expect([1, 2, 3]).arrayContaining([1, 2, 3, 4])should fail.expect([1, 2, 2, 3]).arrayContaining([2, 1, 2])should pass.expect([1, 2, 3]).arrayContaining([1, 1])should fail.expect([]).arrayContaining([])should pass.expect([1]).arrayContaining([])should pass.expect([]).arrayContaining([1])should fail.
Edge Cases:
- Empty arrays for both received and expected.
- Expected array with duplicate elements.
- Received array with duplicate elements.
- Expected array containing elements not present in the received array.
Examples
Example 1:
Input:
expect([1, 2, 3, 4, 5]).arrayContaining([3, 1, 5])
Output:
Passes (true)
Explanation: The received array [1, 2, 3, 4, 5] contains all elements [3, 1, 5], irrespective of their order.
Example 2:
Input:
expect([1, 2, 3]).arrayContaining([1, 2, 2])
Output:
Fails (false)
Explanation: The received array [1, 2, 3] does not contain two occurrences of the number 2, which is required by the expected array.
Example 3:
Input:
expect([1, 2, 2, 3]).arrayContaining([2, 1, 2])
Output:
Passes (true)
Explanation: The received array [1, 2, 2, 3] contains one '1' and two '2's, which matches the requirements of the expected array.
Constraints
- The
arrayContainingmatcher should be implemented as a Jest custom matcher usingexpect.extend. - The input to the matcher will always be arrays.
- The elements within the arrays can be of primitive types (numbers, strings, booleans) or simple objects (which should be compared by reference for this exercise).
- Performance is not a critical concern for this specific implementation, but aim for a reasonably efficient solution.
Notes
To implement this, you'll need to understand how Jest custom matchers work. You'll likely need to iterate through the expected array and for each element, check if it exists in the received array. A good approach for handling duplicates is to use a frequency map or to "consume" elements from the received array as they are matched. Remember that Jest custom matchers should return an object with pass: boolean and message: () => string.