jest-extended
jest-extended copied to clipboard
Feature Request: .toMatchArray()
I was looking for a shortcut to check if an Array exactly matches the contents including order (but was not necessarily strictly equal). The matcher would have test cases like this:
describe('matchArray', () => {
it('matches arrays', () => {
expect(matchArray(['a', 'b'], ['a', 'b'])).toBeTruthy();
expect(matchArray(['a', 'b', 'c'], ['a', 'b'])).toBeFalsy();
expect(matchArray(['a', 'b'], ['a', 'b', 'c'])).toBeFalsy();
expect(matchArray(['a', 'b'], ['b', 'a'])).toBeFalsy();
});
it('short-circuits via equality', () => {
const a = [NaN]; // NaN === NaN returns false
expect(matchArray(a, a)).toBeTruthy();
});
it('uses strict equality', () => {
expect(matchArray(['1'], [1])).toBeFalsy();
expect(matchArray([{}], [{}])).toBeFalsy();
const a = {};
expect(matchArray([a], [a])).toBeTruthy();
});
});
I ended up writing this myself but would be happy to contribute it if you'll accept it.
not necessarily strictly equal
But the third it
uses strict equality. Did you mean 'not necessarily deeply equal'?
By not necessarily strictly equal, I mean the two arrays, rather than their contents. I basically want to be able to check if an array holds what I expected it to hold, including order.
.toIncludeAllMembers()
does what you want, I think, except it accepts the same items in different order.
So maybe .toIncludeAllMembersInOrder()
would be a good name for this?
expect( [1, 2, 3] ).toIncludeAllMembersInOrder( [1, 2, 3] ) // => pass
expect( [3, 2, 1] ).toIncludeAllMembersInOrder( [1, 2, 3] ) // => fail
That would throw an error like "Expected list to have all of the following members in order", rather than your implementation which will throw "expect(received).toBeTruthy()", which is less clear.
.toIncludeAllMembers()
would not resolve the second item, but toIncludeAllMembersInOrder()
might.
expect([1,2,3]).toMatchArray([1,2]) // => fail
expect([1,2,3]).toIncludeAllMembers([1,2]) // => pass (should have failed!)
Should toIncludeAllMembersInOrder()
allow disjoint matching? The cases below are possibly ambiguous:
expect([1,2,3,4]).toIncludeAllMembersInOrder([1,2,3]) // pass or fail?
expect([1,2,3,4]).toIncludeAllMembersInOrder([2,3,4]) // pass or fail?
In the context of this issue, it is obvious, but from the matcher name only, it is not obvious (they do include all members and they are in order). Maybe the new matcher in #512 should be renamed to something along the lines of:
-
toIncludeExactMembers
-
toIncludeExactlyAllMembers
-
toEqualArray
Honestly, it seems like a simple .toEqual()
(mostly) works:
expect(['a', 'b']).toEqual(['a', 'b']) // => pass
expect(['a', 'b', 'c']).not.toEqual(['a', 'b']) // => pass
expect(['a', 'b']).not.toEqual(['a', 'b', 'c']) // => pass
expect(['a', 'b']).not.toEqual(['b', 'a']) // => pass
const a = [NaN]
expect(a).toEqual(a) // => pass
expect(['1']).not.toEqual([1]) // => pass
expect([{}]).not.toEqual([{}]) // => fail
const b = {}
expect([b]).toEqual([b]) // => pass
The [{}]
case differs from what OP expected (and [NaN]
differs from my expectations), but I find the differences agreeable if strict equality or object identity are not desired.
I don't have a way of telling, but I'd wager that when I opened this issue, toEqual
didn't behave the same way. Regardless, I think the example above is close enough for the use case I was looking for that it would make sense to add similar-yet-different matcher.