Skip to content

Commit 4f39624

Browse files
committed
exclude non-enumerable symbol in object matching
1 parent 728f112 commit 4f39624

File tree

3 files changed

+63
-7
lines changed

3 files changed

+63
-7
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- [**BREAKING**] Changes `testPathPattern` configuration option to `testPathPatterns`, which now takes a list of patterns instead of the regex.
3333
- [**BREAKING**] `--testPathPattern` is now `--testPathPatterns`
3434
- `[jest-reporters, jest-runner]` Unhandled errors without stack get correctly logged to console ([#14619](https://github.com/facebook/jest/pull/14619))
35+
- [**BREAKING**] exclude non-enumerable in object matching ([#14670](https://github.com/jestjs/jest/pull/14670))
3536

3637
### Performance
3738

packages/expect-utils/src/__tests__/utils.test.ts

+45
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,51 @@ describe('subsetEquality()', () => {
355355
).toBe(false);
356356
});
357357
});
358+
359+
describe('matching subsets with symbols', () => {
360+
describe('same symbol', () => {
361+
test('objects to not match with value diff', () => {
362+
const symbol = Symbol('foo');
363+
expect(subsetEquality({[symbol]: 1}, {[symbol]: 2})).toBe(false);
364+
});
365+
366+
test('objects to match with non-enumerable symbols', () => {
367+
const symbol = Symbol('foo');
368+
const foo = {};
369+
Object.defineProperty(foo, symbol, {
370+
enumerable: false,
371+
value: 1,
372+
});
373+
const bar = {};
374+
Object.defineProperty(bar, symbol, {
375+
enumerable: false,
376+
value: 2,
377+
});
378+
expect(subsetEquality(foo, bar)).toBe(true);
379+
});
380+
});
381+
382+
describe('different symbol', () => {
383+
test('objects to not match with same value', () => {
384+
expect(subsetEquality({[Symbol('foo')]: 1}, {[Symbol('foo')]: 2})).toBe(
385+
false,
386+
);
387+
});
388+
test('objects to match with non-enumerable symbols', () => {
389+
const foo = {};
390+
Object.defineProperty(foo, Symbol('foo'), {
391+
enumerable: false,
392+
value: 1,
393+
});
394+
const bar = {};
395+
Object.defineProperty(bar, Symbol('foo'), {
396+
enumerable: false,
397+
value: 2,
398+
});
399+
expect(subsetEquality(foo, bar)).toBe(true);
400+
});
401+
});
402+
});
358403
});
359404

360405
describe('iterableEquality', () => {

packages/expect-utils/src/utils.ts

+17-7
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,23 @@ const hasPropertyInObject = (object: object, key: string | symbol): boolean => {
4444
};
4545

4646
// Retrieves an object's keys for evaluation by getObjectSubset. This evaluates
47-
// the prototype chain for string keys but not for symbols. (Otherwise, it
48-
// could find values such as a Set or Map's Symbol.toStringTag, with unexpected
49-
// results.)
50-
export const getObjectKeys = (object: object): Array<string | symbol> => [
51-
...Object.keys(object),
52-
...Object.getOwnPropertySymbols(object),
53-
];
47+
// the prototype chain for string keys but not for non-enumerable symbols.
48+
// (Otherwise, it could find values such as a Set or Map's Symbol.toStringTag,
49+
// with unexpected results.)
50+
// export const getObjectKeys = (object: object): Array<string | symbol> => [
51+
// ...Object.keys(object),
52+
// ...Object.getOwnPropertySymbols(object).filter(
53+
// s => Object.getOwnPropertyDescriptor(object, s)?.enumerable,
54+
// ),
55+
// ];
56+
export const getObjectKeys = (object: object): Array<string | symbol> => {
57+
return [
58+
...Object.keys(object),
59+
...Object.getOwnPropertySymbols(object).filter(
60+
s => Object.getOwnPropertyDescriptor(object, s)?.enumerable,
61+
),
62+
];
63+
};
5464

5565
export const getPath = (
5666
object: Record<string, any>,

0 commit comments

Comments
 (0)