Skip to content

Commit

Permalink
fix: toStrictEqual considers array sparseness (resolves #7586) (#7591)
Browse files Browse the repository at this point in the history
* fix: toStrictEqual considers array sparseness (resolves #7586)

* changelog

* review feedback

* line in docs
  • Loading branch information
marcfallows authored and thymikee committed Jan 9, 2019
1 parent 59ca269 commit 055e31e
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

### Fixes

- `[expect]` `toStrictEqual` considers sparseness of arrays. ([#7591](https://github.com/facebook/jest/pull/7591))
- `[jest-cli]` Fix empty coverage data for untested files ([#7388](https://github.com/facebook/jest/pull/7388))
- `[jest-cli]` [**BREAKING**] Do not use `text-summary` coverage reporter by default if other reporters are configured ([#7058](https://github.com/facebook/jest/pull/7058))
- `[jest-mock]` [**BREAKING**] Fix bugs with mock/spy result tracking of recursive functions ([#6381](https://github.com/facebook/jest/pull/6381))
Expand Down
1 change: 1 addition & 0 deletions docs/ExpectAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,7 @@ Use `.toStrictEqual` to test that objects have the same types as well as structu
Differences from `.toEqual`:

- Keys with `undefined` properties are checked. e.g. `{a: undefined, b: 2}` does not match `{b: 2}` when using `.toStrictEqual`.
- Array sparseness is checked. e.g. `[, 1]` does not match `[undefined, 1]` when using `.toStrictEqual`.
- Object types are checked to be equal. e.g. A class instance with fields `a` and `b` will not equal a literal object with fields `a` and `b`.

```js
Expand Down
16 changes: 16 additions & 0 deletions packages/expect/src/__tests__/matchers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,22 @@ describe('.toStrictEqual()', () => {
expect(c.constructor.name).toEqual(d.constructor.name);
expect({test: c}).not.toStrictEqual({test: d});
});

/* eslint-disable no-sparse-arrays */
it('passes for matching sparse arrays', () => {
expect([, 1]).toStrictEqual([, 1]);
});

it('does not pass when sparseness of arrays do not match', () => {
expect([, 1]).not.toStrictEqual([undefined, 1]);
expect([undefined, 1]).not.toStrictEqual([, 1]);
expect([, , , 1]).not.toStrictEqual([, 1]);
});

it('does not pass when equally sparse arrays have different values', () => {
expect([, 1]).not.toStrictEqual([, 2]);
});
/* eslint-enable */
});

describe('.toEqual()', () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/expect/src/matchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
getObjectSubset,
getPath,
iterableEquality,
sparseArrayEquality,
subsetEquality,
typeEquality,
isOneline,
Expand Down Expand Up @@ -666,7 +667,7 @@ const matchers: MatchersObject = {
const pass = equals(
received,
expected,
[iterableEquality, typeEquality],
[iterableEquality, typeEquality, sparseArrayEquality],
true,
);

Expand Down
11 changes: 11 additions & 0 deletions packages/expect/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,17 @@ export const typeEquality = (a: any, b: any) => {
return false;
};

export const sparseArrayEquality = (a: any, b: any) => {
if (!Array.isArray(a) || !Array.isArray(b)) {
return undefined;
}

// A sparse array [, , 1] will have keys ["2"] whereas [undefined, undefined, 1] will have keys ["0", "1", "2"]
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
return equals(a, b) && equals(aKeys, bKeys);
};

export const partition = <T>(
items: Array<T>,
predicate: T => boolean,
Expand Down

0 comments on commit 055e31e

Please sign in to comment.