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

expect: Avoid incorrect difference for subset when toMatchObject fails #9005

Merged
merged 5 commits into from Oct 17, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -25,7 +25,8 @@

### Fixes

- `[expect]` Display expectedDiff more carefully in toBeCloseTo ([#8389](https://github.com/facebook/jest/pull/8389))
- `[expect]` Display `expectedDiff` more carefully in `toBeCloseTo` ([#8389](https://github.com/facebook/jest/pull/8389))
- `[expect]` Avoid incorrect difference for subset when `toMatchObject` fails ([#9005](https://github.com/facebook/jest/pull/9005))
- `[jest-core]` Don't include unref'd timers in --detectOpenHandles results ([#8941](https://github.com/facebook/jest/pull/8941))
- `[jest-diff]` Do not inverse format if line consists of one change ([#8903](https://github.com/facebook/jest/pull/8903))
- `[jest-fake-timers]` `getTimerCount` will not include cancelled immediates ([#8764](https://github.com/facebook/jest/pull/8764))
Expand Down
39 changes: 38 additions & 1 deletion packages/expect/src/__tests__/utils.test.js
Expand Up @@ -147,7 +147,7 @@ describe('hasOwnProperty', () => {
});
});

describe('getObjectSubset()', () => {
describe('getObjectSubset', () => {
[
[{a: 'b', c: 'd'}, {a: 'd'}, {a: 'b'}],
[{a: [1, 2], b: 'b'}, {a: [3, 4]}, {a: [1, 2]}],
Expand All @@ -165,6 +165,43 @@ describe('getObjectSubset()', () => {
);
});

describe('returns the object instance if the subset has no extra properties', () => {
test('Date', () => {
const object = new Date('2015-11-30');
const subset = new Date('2016-12-30');

expect(getObjectSubset(object, subset)).toBe(object);
});
});

describe('returns the subset instance if its property values are equal', () => {
test('Object', () => {
const object = {key0: 'zero', key1: 'one', key2: 'two'};
const subset = {key0: 'zero', key2: 'two'};

expect(getObjectSubset(object, subset)).toBe(subset);
});

describe('Uint8Array', () => {
const equalObject = {'0': 0, '1': 0, '2': 0};
const typedArray = new Uint8Array(3);

test('expected', () => {
const object = equalObject;
const subset = typedArray;

expect(getObjectSubset(object, subset)).toBe(subset);
});

test('received', () => {
const object = typedArray;
const subset = equalObject;

expect(getObjectSubset(object, subset)).toBe(subset);
});
});
});

describe('calculating subsets of objects with circular references', () => {
test('simple circular references', () => {
const nonCircularObj = {a: 'world', b: 'something'};
Expand Down
6 changes: 6 additions & 0 deletions packages/expect/src/utils.ts
Expand Up @@ -111,13 +111,19 @@ export const getObjectSubset = (
): any => {
if (Array.isArray(object)) {
if (Array.isArray(subset) && subset.length === object.length) {
// The map method returns correct subclass of subset.
return subset.map((sub: any, i: number) =>
getObjectSubset(object[i], sub),
);
}
} else if (object instanceof Date) {
return object;
} else if (isObject(object) && isObject(subset)) {
if (equals(object, subset, [iterableEquality, subsetEquality])) {
// Avoid unnecessary copy which might return Object instead of subclass.
return subset;
}

const trimmed: any = {};
seenReferences.set(object, trimmed);

Expand Down