Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: .toMatchArray() #231

Closed
kara-ryli opened this issue Oct 5, 2019 · 5 comments · May be fixed by #512
Closed

Feature Request: .toMatchArray() #231

kara-ryli opened this issue Oct 5, 2019 · 5 comments · May be fixed by #512

Comments

@kara-ryli
Copy link

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.

@vatosarmat
Copy link

not necessarily strictly equal

But the third it uses strict equality. Did you mean 'not necessarily deeply equal'?

@kara-ryli
Copy link
Author

kara-ryli commented Oct 16, 2019

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.

@overlookmotel
Copy link
Contributor

.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.

@beeryt
Copy link

beeryt commented Oct 26, 2022

.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.

@kara-ryli
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants