diff --git a/CHANGELOG.md b/CHANGELOG.md index eaa379867814..b24eddb173a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixes - `[jest-environment-jsdom, jest-environment-node]` Fix assignment of `customExportConditions` via `testEnvironmentOptions` when custom env subclass defines a default value ([#13989](https://github.com/facebook/jest/pull/13989)) +- `[jest-matcher-utils]` Fix copying value of inherited getters ([#14007](https://github.com/facebook/jest/pull/14007)) ### Chore & Maintenance diff --git a/packages/jest-matcher-utils/src/__tests__/deepCyclicCopyReplaceable.test.ts b/packages/jest-matcher-utils/src/__tests__/deepCyclicCopyReplaceable.test.ts index 6a017b694103..e63b680a8c75 100644 --- a/packages/jest-matcher-utils/src/__tests__/deepCyclicCopyReplaceable.test.ts +++ b/packages/jest-matcher-utils/src/__tests__/deepCyclicCopyReplaceable.test.ts @@ -43,7 +43,7 @@ test('convert accessor descriptor into value descriptor', () => { }); }); -test('should not skips non-enumerables', () => { +test('should not skip non-enumerables', () => { const obj = {}; Object.defineProperty(obj, 'foo', {enumerable: false, value: 'bar'}); @@ -66,6 +66,18 @@ test('copies symbols', () => { expect(deepCyclicCopyReplaceable(obj)[symbol]).toBe(42); }); +test('copies value of inherited getters', () => { + class Foo { + #foo = 42; + get foo() { + return this.#foo; + } + } + const obj = new Foo(); + + expect(deepCyclicCopyReplaceable(obj).foo).toBe(42); +}); + test('copies arrays as array objects', () => { const array = [null, 42, 'foo', 'bar', [], {}]; diff --git a/packages/jest-matcher-utils/src/deepCyclicCopyReplaceable.ts b/packages/jest-matcher-utils/src/deepCyclicCopyReplaceable.ts index 8c7c520c2168..82cc0249a22c 100644 --- a/packages/jest-matcher-utils/src/deepCyclicCopyReplaceable.ts +++ b/packages/jest-matcher-utils/src/deepCyclicCopyReplaceable.ts @@ -57,9 +57,18 @@ export default function deepCyclicCopyReplaceable( function deepCyclicCopyObject(object: T, cycles: WeakMap): T { const newObject = Object.create(Object.getPrototypeOf(object)); - const descriptors: { - [x: string]: PropertyDescriptor; - } = Object.getOwnPropertyDescriptors(object); + let descriptors: Record = {}; + let obj = object; + do { + descriptors = Object.assign( + {}, + Object.getOwnPropertyDescriptors(obj), + descriptors, + ); + } while ( + (obj = Object.getPrototypeOf(obj)) && + obj !== Object.getPrototypeOf({}) + ); cycles.set(object, newObject);