From bf4d2d6013eebf0b02b9ec3cac57c3641bb02071 Mon Sep 17 00:00:00 2001 From: Peter Staples Date: Tue, 16 Aug 2022 17:41:29 +0100 Subject: [PATCH 01/13] bug-13140 Added tests for class mocks --- .../jest-mock/src/__tests__/SuperTestClass.ts | 28 +++ packages/jest-mock/src/__tests__/TestClass.ts | 3 + .../__tests__/class-mocks-dual-import.test.ts | 122 +++++++++++++ .../class-mocks-single-import.test.ts | 120 +++++++++++++ .../src/__tests__/class-mocks-types.ts | 30 ++++ .../src/__tests__/class-mocks.test.ts | 163 ++++++++++++++++++ 6 files changed, 466 insertions(+) create mode 100644 packages/jest-mock/src/__tests__/SuperTestClass.ts create mode 100644 packages/jest-mock/src/__tests__/TestClass.ts create mode 100644 packages/jest-mock/src/__tests__/class-mocks-dual-import.test.ts create mode 100644 packages/jest-mock/src/__tests__/class-mocks-single-import.test.ts create mode 100644 packages/jest-mock/src/__tests__/class-mocks-types.ts create mode 100644 packages/jest-mock/src/__tests__/class-mocks.test.ts diff --git a/packages/jest-mock/src/__tests__/SuperTestClass.ts b/packages/jest-mock/src/__tests__/SuperTestClass.ts new file mode 100644 index 000000000000..2ea722af2f3a --- /dev/null +++ b/packages/jest-mock/src/__tests__/SuperTestClass.ts @@ -0,0 +1,28 @@ +export class SuperTestClass { + static staticTestProperty = 'staticTestProperty'; + + static get staticTestAccessor(): string { + return 'staticTestAccessor'; + } + + static set staticTestAccessor(_x: string) { + return; + } + + static staticTestMethod(): string { + return 'staticTestMethod'; + } + + testProperty = 'testProperty'; + + get testAccessor(): string { + return 'testAccessor'; + } + set testAccessor(_x: string) { + return; + } + + testMethod(): string { + return 'testMethod'; + } +} diff --git a/packages/jest-mock/src/__tests__/TestClass.ts b/packages/jest-mock/src/__tests__/TestClass.ts new file mode 100644 index 000000000000..59b17d7810f6 --- /dev/null +++ b/packages/jest-mock/src/__tests__/TestClass.ts @@ -0,0 +1,3 @@ +import {SuperTestClass} from './SuperTestClass'; + +export default class TestClass extends SuperTestClass {} diff --git a/packages/jest-mock/src/__tests__/class-mocks-dual-import.test.ts b/packages/jest-mock/src/__tests__/class-mocks-dual-import.test.ts new file mode 100644 index 000000000000..f017806fce07 --- /dev/null +++ b/packages/jest-mock/src/__tests__/class-mocks-dual-import.test.ts @@ -0,0 +1,122 @@ +import {SuperTestClass} from './SuperTestClass'; +import TestClass from './TestClass'; +jest.mock('./SuperTestClass'); +jest.mock('./TestClass'); + +describe('Testing the mocking of a class hierarchy defined in multiple imports', () => { + it('can call an instance method - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(SuperTestClass.prototype, 'testMethod') + .mockImplementation(() => { + return 'mockTestMethod'; + }); + const testClassInstance = new SuperTestClass(); + expect(testClassInstance.testMethod()).toEqual('mockTestMethod'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + + mockTestMethod.mockClear(); + }); + + it('can call a superclass instance method - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(TestClass.prototype, 'testMethod') + .mockImplementation(() => { + return 'mockTestMethod'; + }); + const testClassInstance = new TestClass(); + expect(testClassInstance.testMethod()).toEqual('mockTestMethod'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + }); + + it('can read a value from an instance getter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(SuperTestClass.prototype, 'testAccessor', 'get') + .mockImplementation(() => { + return 'mockTestAccessor'; + }); + const testClassInstance = new SuperTestClass(); + expect(testClassInstance.testAccessor).toEqual('mockTestAccessor'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + + mockTestMethod.mockClear(); + }); + + it('can read a value from a superclass instance getter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(TestClass.prototype, 'testAccessor', 'get') + .mockImplementation(() => { + return 'mockTestAccessor'; + }); + const testClassInstance = new TestClass(); + expect(testClassInstance.testAccessor).toEqual('mockTestAccessor'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + }); + + it('can write a value to an instance setter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(SuperTestClass.prototype, 'testAccessor', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + const testClassInstance = new SuperTestClass(); + testClassInstance.testAccessor = ''; + expect(mockTestMethod).toHaveBeenCalledTimes(1); + + mockTestMethod.mockClear(); + }); + + it('can write a value to a superclass instance setter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(TestClass.prototype, 'testAccessor', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + const testClassInstance = new TestClass(); + testClassInstance.testAccessor = ''; + expect(mockTestMethod).toHaveBeenCalledTimes(1); + }); + + it('can read a value from a static getter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(SuperTestClass, 'staticTestAccessor', 'get') + .mockImplementation(() => { + return 'mockStaticTestAccessor'; + }); + expect(SuperTestClass.staticTestAccessor).toEqual('mockStaticTestAccessor'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + + mockTestMethod.mockClear(); + }); + + it('can read a value from a superclass static getter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(TestClass, 'staticTestAccessor', 'get') + .mockImplementation(() => { + return 'mockStaticTestAccessor'; + }); + expect(TestClass.staticTestAccessor).toEqual('mockStaticTestAccessor'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + }); + + it('can write a value to a static setter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(SuperTestClass, 'staticTestAccessor', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + SuperTestClass.staticTestAccessor = ''; + expect(mockTestMethod).toHaveBeenCalledTimes(1); + + mockTestMethod.mockClear(); + }); + + it('can write a value to a superclass static setter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(TestClass, 'staticTestAccessor', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + TestClass.staticTestAccessor = ''; + expect(mockTestMethod).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/jest-mock/src/__tests__/class-mocks-single-import.test.ts b/packages/jest-mock/src/__tests__/class-mocks-single-import.test.ts new file mode 100644 index 000000000000..b99054d8734b --- /dev/null +++ b/packages/jest-mock/src/__tests__/class-mocks-single-import.test.ts @@ -0,0 +1,120 @@ +import SuperTestClass, {TestClass} from './class-mocks-types'; +jest.mock('./class-mocks-types'); + +describe('Testing the mocking of a class hierarchy defined in a single import', () => { + it('can call an instance method - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(SuperTestClass.prototype, 'testMethod') + .mockImplementation(() => { + return 'mockTestMethod'; + }); + const testClassInstance = new SuperTestClass(); + expect(testClassInstance.testMethod()).toEqual('mockTestMethod'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + + mockTestMethod.mockClear(); + }); + + it('can call a superclass instance method - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(TestClass.prototype, 'testMethod') + .mockImplementation(() => { + return 'mockTestMethod'; + }); + const testClassInstance = new TestClass(); + expect(testClassInstance.testMethod()).toEqual('mockTestMethod'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + }); + + it('can read a value from an instance getter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(SuperTestClass.prototype, 'testAccessor', 'get') + .mockImplementation(() => { + return 'mockTestAccessor'; + }); + const testClassInstance = new SuperTestClass(); + expect(testClassInstance.testAccessor).toEqual('mockTestAccessor'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + + mockTestMethod.mockClear(); + }); + + it('can read a value from a superclass instance getter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(TestClass.prototype, 'testAccessor', 'get') + .mockImplementation(() => { + return 'mockTestAccessor'; + }); + const testClassInstance = new TestClass(); + expect(testClassInstance.testAccessor).toEqual('mockTestAccessor'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + }); + + it('can write a value to an instance setter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(SuperTestClass.prototype, 'testAccessor', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + const testClassInstance = new SuperTestClass(); + testClassInstance.testAccessor = ''; + expect(mockTestMethod).toHaveBeenCalledTimes(1); + + mockTestMethod.mockClear(); + }); + + it('can write a value to a superclass instance setter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(TestClass.prototype, 'testAccessor', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + const testClassInstance = new TestClass(); + testClassInstance.testAccessor = ''; + expect(mockTestMethod).toHaveBeenCalledTimes(1); + }); + + it('can read a value from a static getter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(SuperTestClass, 'staticTestAccessor', 'get') + .mockImplementation(() => { + return 'mockStaticTestAccessor'; + }); + expect(SuperTestClass.staticTestAccessor).toEqual('mockStaticTestAccessor'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + + mockTestMethod.mockClear(); + }); + + it('can read a value from a superclass static getter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(TestClass, 'staticTestAccessor', 'get') + .mockImplementation(() => { + return 'mockStaticTestAccessor'; + }); + expect(TestClass.staticTestAccessor).toEqual('mockStaticTestAccessor'); + expect(mockTestMethod).toHaveBeenCalledTimes(1); + }); + + it('can write a value to a static setter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(SuperTestClass, 'staticTestAccessor', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + SuperTestClass.staticTestAccessor = ''; + expect(mockTestMethod).toHaveBeenCalledTimes(1); + + mockTestMethod.mockClear(); + }); + + it('can write a value to a superclass static setter - Auto-mocked class', () => { + const mockTestMethod = jest + .spyOn(TestClass, 'staticTestAccessor', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + TestClass.staticTestAccessor = ''; + expect(mockTestMethod).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/jest-mock/src/__tests__/class-mocks-types.ts b/packages/jest-mock/src/__tests__/class-mocks-types.ts new file mode 100644 index 000000000000..e39e582e9ad1 --- /dev/null +++ b/packages/jest-mock/src/__tests__/class-mocks-types.ts @@ -0,0 +1,30 @@ +export default class SuperTestClass { + static staticTestProperty = 'staticTestProperty'; + + static get staticTestAccessor(): string { + return 'staticTestAccessor'; + } + + static set staticTestAccessor(_x: string) { + return; + } + + static staticTestMethod(): string { + return 'staticTestMethod'; + } + + testProperty = 'testProperty'; + + get testAccessor(): string { + return 'testAccessor'; + } + set testAccessor(_x: string) { + return; + } + + testMethod(): string { + return 'testMethod'; + } +} + +export class TestClass extends SuperTestClass {} diff --git a/packages/jest-mock/src/__tests__/class-mocks.test.ts b/packages/jest-mock/src/__tests__/class-mocks.test.ts new file mode 100644 index 000000000000..e8ddd312aaf9 --- /dev/null +++ b/packages/jest-mock/src/__tests__/class-mocks.test.ts @@ -0,0 +1,163 @@ +describe('Testing the mocking of a class', () => { + it('can call an instance method', () => { + class TestClass { + testMethod(): string { + return 'testMethod'; + } + } + + jest.spyOn(TestClass.prototype, 'testMethod').mockImplementation(() => { + return 'mockTestMethod'; + }); + const testClassInstance = new TestClass(); + expect(testClassInstance.testMethod()).toEqual('mockTestMethod'); + }); + + it('can call a superclass instance method', () => { + class SuperTestClass { + testMethod(): string { + return 'testMethod'; + } + } + + class TestClass extends SuperTestClass {} + + jest.spyOn(TestClass.prototype, 'testMethod').mockImplementation(() => { + return 'mockTestMethod'; + }); + const testClassInstance = new TestClass(); + expect(testClassInstance.testMethod()).toEqual('mockTestMethod'); + }); + + it('can read a value from an instance getter', () => { + class TestClass { + get testMethod(): string { + return 'testMethod'; + } + } + + jest + .spyOn(TestClass.prototype, 'testMethod', 'get') + .mockImplementation(() => { + return 'mockTestMethod'; + }); + const testClassInstance = new TestClass(); + expect(testClassInstance.testMethod).toEqual('mockTestMethod'); + }); + + it('can read a value from an superclass instance getter', () => { + class SuperTestClass { + get testMethod(): string { + return 'testMethod'; + } + } + + class TestClass extends SuperTestClass {} + + jest + .spyOn(TestClass.prototype, 'testMethod', 'get') + .mockImplementation(() => { + return 'mockTestMethod'; + }); + const testClassInstance = new TestClass(); + expect(testClassInstance.testMethod).toEqual('mockTestMethod'); + }); + + it('can write a value to an instance setter', () => { + class TestClass { + set testMethod(_x: string) { + return; + } + } + + const mocktestMethod = jest + .spyOn(TestClass.prototype, 'testMethod', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + const testClassInstance = new TestClass(); + testClassInstance.testMethod = ''; + expect(mocktestMethod).toHaveBeenCalledTimes(1); + }); + + it('can write a value to a superclass instance setter', () => { + class SuperTestClass { + set testMethod(_x: string) { + return; + } + } + + class TestClass extends SuperTestClass {} + + const mocktestMethod = jest + .spyOn(TestClass.prototype, 'testMethod', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + const testClassInstance = new TestClass(); + testClassInstance.testMethod = ''; + expect(mocktestMethod).toHaveBeenCalledTimes(1); + }); + + it('can read a value from a static getter', () => { + class TestClass { + static get testMethod(): string { + return 'testMethod'; + } + } + + jest.spyOn(TestClass, 'testMethod', 'get').mockImplementation(() => { + return 'mockTestMethod'; + }); + expect(TestClass.testMethod).toEqual('mockTestMethod'); + }); + + it('can read a value from a superclass static getter', () => { + class SuperTestClass { + static get testMethod(): string { + return 'testMethod'; + } + } + + class TestClass extends SuperTestClass {} + + jest.spyOn(TestClass, 'testMethod', 'get').mockImplementation(() => { + return 'mockTestMethod'; + }); + expect(TestClass.testMethod).toEqual('mockTestMethod'); + }); + + it('can write a value to a static setter', () => { + class TestClass { + static set testMethod(_x: string) { + return; + } + } + + const mocktestMethod = jest + .spyOn(TestClass, 'testMethod', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + TestClass.testMethod = ''; + expect(mocktestMethod).toHaveBeenCalledTimes(1); + }); + + it('can write a value to a superclass static setter', () => { + class SuperTestClass { + static set testMethod(_x: string) { + return; + } + } + + class TestClass extends SuperTestClass {} + + const mocktestMethod = jest + .spyOn(TestClass, 'testMethod', 'set') + .mockImplementation((_x: string) => { + return () => {}; + }); + TestClass.testMethod = ''; + expect(mocktestMethod).toHaveBeenCalledTimes(1); + }); +}); From ee81c2598b690849d3c6f2a4c840234f54079e2d Mon Sep 17 00:00:00 2001 From: Peter Staples Date: Tue, 16 Aug 2022 18:02:57 +0100 Subject: [PATCH 02/13] bug-13140 Implemented mocking of getter/setter methods --- packages/jest-mock/src/index.ts | 246 +++++++++++++++++--------------- 1 file changed, 131 insertions(+), 115 deletions(-) diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 305699b0a50c..fb155c349451 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -506,7 +506,7 @@ export class ModuleMocker { if (!isReadonlyProp(object, prop)) { const propDesc = Object.getOwnPropertyDescriptor(object, prop); - if ((propDesc !== undefined && !propDesc.get) || object.__esModule) { + if (propDesc !== undefined || object.__esModule) { slots.add(prop); } } @@ -884,7 +884,9 @@ export class ModuleMocker { } this._getSlots(metadata.members).forEach(slot => { + let slotMock: Mock; const slotMetadata = (metadata.members && metadata.members[slot]) || {}; + if (slotMetadata.ref != null) { callbacks.push( (function (ref) { @@ -892,7 +894,24 @@ export class ModuleMocker { })(slotMetadata.ref), ); } else { - mock[slot] = this._generateMock(slotMetadata, callbacks, refs); + slotMock = this._generateMock(slotMetadata, callbacks, refs); + + //missing getter and setter refs will be resolved as their callbacks have been + //stacked before the setting of the accessor definition is stacked. + if ( + slotMetadata.members?.get?.ref !== undefined || + slotMetadata.members?.set?.ref !== undefined + ) { + callbacks.push( + (function (ref) { + return () => Object.defineProperty(mock, slot, ref); + })(slotMock), + ); + } else if (slotMetadata.members?.get || slotMetadata.members?.set) { + Object.defineProperty(mock, slot, slotMock); + } else { + mock[slot] = slotMock; + } } }); @@ -980,8 +999,23 @@ export class ModuleMocker { ) { return; } - // @ts-expect-error no index signature - const slotMetadata = this.getMetadata(component[slot], refs); + + let descriptor = Object.getOwnPropertyDescriptor(component, slot); + let proto = Object.getPrototypeOf(component); + while (!descriptor && proto !== null) { + descriptor = Object.getOwnPropertyDescriptor(proto, slot); + proto = Object.getPrototypeOf(proto); + } + + let slotMetadata: MockFunctionMetadata | null = null; + if (descriptor?.get || descriptor?.set) { + // @ts-expect-error ignore type mismatch + slotMetadata = this.getMetadata(descriptor, refs); + } else { + // @ts-expect-error no index signature + slotMetadata = this.getMetadata(component[slot], refs); + } + if (slotMetadata) { if (!members) { members = {}; @@ -1054,148 +1088,130 @@ export class ModuleMocker { methodName: M, accessType?: 'get' | 'set', ) { - if (accessType) { - return this._spyOnProperty(object, methodName, accessType); - } - - if (typeof object !== 'object' && typeof object !== 'function') { + if (!object) { throw new Error( - `Cannot spyOn on a primitive value; ${this._typeOf(object)} given`, + `spyOn could not find an object to spy upon for ${String(methodName)}`, ); } - const original = object[methodName]; - - if (!this.isMockFunction(original)) { - if (typeof original !== 'function') { - throw new Error( - `Cannot spy the ${String( - methodName, - )} property because it is not a function; ${this._typeOf( - original, - )} given instead`, - ); - } - - const isMethodOwner = Object.prototype.hasOwnProperty.call( - object, - methodName, - ); - - let descriptor = Object.getOwnPropertyDescriptor(object, methodName); - let proto = Object.getPrototypeOf(object); - - while (!descriptor && proto !== null) { - descriptor = Object.getOwnPropertyDescriptor(proto, methodName); - proto = Object.getPrototypeOf(proto); - } - - let mock: Mock; - - if (descriptor && descriptor.get) { - const originalGet = descriptor.get; - mock = this._makeComponent({type: 'function'}, () => { - descriptor!.get = originalGet; - Object.defineProperty(object, methodName, descriptor!); - }); - descriptor.get = () => mock; - Object.defineProperty(object, methodName, descriptor); - } else { - mock = this._makeComponent({type: 'function'}, () => { - if (isMethodOwner) { - object[methodName] = original; - } else { - delete object[methodName]; - } - }); - // @ts-expect-error overriding original method with a Mock - object[methodName] = mock; - } - - mock.mockImplementation(function (this: unknown) { - return original.apply(this, arguments); - }); + if (!methodName) { + throw new Error('No property name supplied'); } - return object[methodName]; - } - - private _spyOnProperty>( - obj: T, - propertyName: M, - accessType: 'get' | 'set' = 'get', - ): Mock<() => T> { - if (typeof obj !== 'object' && typeof obj !== 'function') { - throw new Error( - `Cannot spyOn on a primitive value; ${this._typeOf(obj)} given`, - ); + if (accessType && accessType != 'get' && accessType != 'set') { + throw new Error('Invalid accessType supplied'); } - if (!obj) { + if (typeof object !== 'object' && typeof object !== 'function') { throw new Error( - `spyOn could not find an object to spy upon for ${String( - propertyName, - )}`, + `Cannot spyOn on a primitive value; ${this._typeOf(object)} given`, ); } - if (!propertyName) { - throw new Error('No property name supplied'); - } - - let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName); - let proto = Object.getPrototypeOf(obj); - + let descriptor = Object.getOwnPropertyDescriptor(object, methodName); + let proto = Object.getPrototypeOf(object); while (!descriptor && proto !== null) { - descriptor = Object.getOwnPropertyDescriptor(proto, propertyName); + descriptor = Object.getOwnPropertyDescriptor(proto, methodName); proto = Object.getPrototypeOf(proto); } - if (!descriptor) { - throw new Error(`${String(propertyName)} property does not exist`); + throw new Error(`${String(methodName)} property does not exist`); } - if (!descriptor.configurable) { - throw new Error(`${String(propertyName)} is not declared configurable`); + throw new Error(`${String(methodName)} is not declared configurable`); } - if (!descriptor[accessType]) { - throw new Error( - `Property ${String( - propertyName, - )} does not have access type ${accessType}`, - ); + if (this.isMockFunction(descriptor.value)) { + return object[methodName]; + } else if (accessType == 'get' && this.isMockFunction(descriptor.get)) { + return descriptor.get; + } else if (accessType == 'set' && this.isMockFunction(descriptor.set)) { + return descriptor.set; } - const original = descriptor[accessType]; - - if (!this.isMockFunction(original)) { - if (typeof original !== 'function') { + if (accessType) { + if (typeof descriptor[accessType] !== 'function') { throw new Error( - `Cannot spy the ${String( - propertyName, - )} property because it is not a function; ${this._typeOf( - original, - )} given instead`, + `Cannot spy the ${String(accessType)} ${String( + methodName, + )} property because it is not a function; + ${this._typeOf(descriptor?.[accessType])} given instead`, ); } + } else if (typeof descriptor.value !== 'function') { + throw new Error( + `Cannot spy the ${String( + methodName, + )} property because it is not a function; ${this._typeOf( + descriptor.value, + )} given instead`, + ); + } + + let mock: Mock; + + if (accessType == 'get' && descriptor['get']) { + const originalAccessor = descriptor['get']; + mock = this._makeComponent( + { + type: 'function', + }, + () => { + descriptor![accessType] = originalAccessor; + Object.defineProperty(object, methodName, descriptor!); + }, + ); - descriptor[accessType] = this._makeComponent({type: 'function'}, () => { - // @ts-expect-error: mock is assignable - descriptor![accessType] = original; - Object.defineProperty(obj, propertyName, descriptor!); + descriptor[accessType] = mock; + mock.mockImplementation(function (this: unknown) { + return originalAccessor.apply(this, []); }); + Object.defineProperty(object, methodName, descriptor); + } else if (accessType == 'set' && descriptor['set']) { + const originalAccessor = descriptor['set']; + mock = this._makeComponent( + { + type: 'function', + }, + () => { + descriptor![accessType] = originalAccessor; + Object.defineProperty(object, methodName, descriptor!); + }, + ); - (descriptor[accessType] as Mock<() => T>).mockImplementation(function ( - this: unknown, - ) { - // @ts-expect-error - wrong context - return original.apply(this, arguments); + descriptor[accessType] = mock; + mock.mockImplementation(function (this: unknown) { + return originalAccessor.apply(this, arguments[0]); + }); + Object.defineProperty(object, methodName, descriptor); + } else { + const isMethodOwner = Object.prototype.hasOwnProperty.call( + object, + methodName, + ); + const original = descriptor; + + mock = this._makeComponent( + { + type: 'function', + }, + () => { + if (isMethodOwner) { + object[methodName] = original.value; + } else { + delete object[methodName]; + } + }, + ); + + // @ts-expect-error overriding original method with a Mock + object[methodName] = mock; + mock.mockImplementation(function (this: unknown) { + return original.value.apply(this, arguments); }); } - Object.defineProperty(obj, propertyName, descriptor); - return descriptor[accessType] as Mock<() => T>; + return mock; } clearAllMocks(): void { From 52bfb65de3db540062d49dd8eb09cdc4ed7e1bb1 Mon Sep 17 00:00:00 2001 From: Peter Staples Date: Wed, 17 Aug 2022 17:26:05 +0100 Subject: [PATCH 03/13] bug-13140 Made existing tests pass --- jest.config.mjs | 3 ++ .../src/__tests__/class-mocks.test.ts | 4 ++ .../jest-mock/src/__tests__/index.test.ts | 7 ++- packages/jest-mock/src/index.ts | 54 ++++++++++++++++--- 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/jest.config.mjs b/jest.config.mjs index 192ccd07dcfa..5459b96db2b2 100644 --- a/jest.config.mjs +++ b/jest.config.mjs @@ -58,6 +58,9 @@ export default { '/packages/jest-haste-map/src/__tests__/haste_impl.js', '/packages/jest-haste-map/src/__tests__/dependencyExtractor.js', '/packages/jest-haste-map/src/__tests__/test_dotfiles_root/', + '/packages/jest-mock/src/__tests__/class-mocks-types.ts', + '/packages/jest-mock/src/__tests__/TestClass.ts', + '/packages/jest-mock/src/__tests__/SuperTestClass.ts', '/packages/jest-repl/src/__tests__/test_root', '/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/', '/packages/jest-runtime/src/__tests__/defaultResolver.js', diff --git a/packages/jest-mock/src/__tests__/class-mocks.test.ts b/packages/jest-mock/src/__tests__/class-mocks.test.ts index e8ddd312aaf9..874e2940ec7a 100644 --- a/packages/jest-mock/src/__tests__/class-mocks.test.ts +++ b/packages/jest-mock/src/__tests__/class-mocks.test.ts @@ -65,6 +65,7 @@ describe('Testing the mocking of a class', () => { it('can write a value to an instance setter', () => { class TestClass { + // eslint-disable-next-line accessor-pairs set testMethod(_x: string) { return; } @@ -82,6 +83,7 @@ describe('Testing the mocking of a class', () => { it('can write a value to a superclass instance setter', () => { class SuperTestClass { + // eslint-disable-next-line accessor-pairs set testMethod(_x: string) { return; } @@ -129,6 +131,7 @@ describe('Testing the mocking of a class', () => { it('can write a value to a static setter', () => { class TestClass { + // eslint-disable-next-line accessor-pairs static set testMethod(_x: string) { return; } @@ -145,6 +148,7 @@ describe('Testing the mocking of a class', () => { it('can write a value to a superclass static setter', () => { class SuperTestClass { + // eslint-disable-next-line accessor-pairs static set testMethod(_x: string) { return; } diff --git a/packages/jest-mock/src/__tests__/index.test.ts b/packages/jest-mock/src/__tests__/index.test.ts index 6b9f716d7ef0..595e0a1a5ca3 100644 --- a/packages/jest-mock/src/__tests__/index.test.ts +++ b/packages/jest-mock/src/__tests__/index.test.ts @@ -192,6 +192,11 @@ describe('moduleMocker', () => { expect(mock.nonEnumGetter).toBeUndefined(); }); + //This test was never valid. ModuleMocker mocked the read value of the getter + //i.e. the returned class on an ES module getter. + //So this test only verified that SOMETHING (10) was assigned to the enumGetter property. + //Exclusion case has been added to the ModuleMocker to ensure that ES modules + //are still mocked, whilst accessor properties are too. it('mocks getters of ES modules', () => { const foo = Object.defineProperties( {}, @@ -1263,7 +1268,7 @@ describe('moduleMocker', () => { }, }; - const spy = moduleMocker.spyOn(obj, 'method'); + const spy = moduleMocker.spyOn(obj, 'method', 'get'); const thisArg = {this: true}; const firstArg = {first: true}; diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index fb155c349451..8ef19a51af0f 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -506,7 +506,26 @@ export class ModuleMocker { if (!isReadonlyProp(object, prop)) { const propDesc = Object.getOwnPropertyDescriptor(object, prop); - if (propDesc !== undefined || object.__esModule) { + //In test packages/jest-runtime/src/__tests__/runtime_require_mock.test.js -> it('multiple node core modules returns correct module') + //when the component.name == 'propertyIsEnumerable' (object.name at start of _getSlots()) + //when retrieving metadata, the match for object !== ObjectProto fails. + //This causes an error where an ancestor prototype getter method, + //and introduction of mocking getters, results in a getter object + //being assigned to the prototype property __proto__, + //which then breaks when later building the mock. Ignore getters for __proto__. + //Please note that the metadata structure for the objects in this test seems heavily polluted + //with unnecessary objects, as if the exclusion conditions for object types in _getSlots() + //is failing in multiple cases. + + //it seems the OR condition "object.__esModule" was added to allow + //getters returning imported class definitions to be included whilst + //other accessor properties with getters were ignored. + //Can the "object.__esModule" condition now be removed? + if ( + (propDesc !== undefined && + !(propDesc.get && prop == '__proto__')) || + object.__esModule + ) { slots.add(prop); } } @@ -896,7 +915,10 @@ export class ModuleMocker { } else { slotMock = this._generateMock(slotMetadata, callbacks, refs); - //missing getter and setter refs will be resolved as their callbacks have been + //For superclass accessor properties the subclass metadata contains the definitions + //for the getter and setter methods, and the superclass refs to them. + //The mock implementations are not available until the callbacks have been executed. + //Missing getter and setter refs will be resolved as their callbacks have been //stacked before the setting of the accessor definition is stacked. if ( slotMetadata.members?.get?.ref !== undefined || @@ -907,7 +929,16 @@ export class ModuleMocker { return () => Object.defineProperty(mock, slot, ref); })(slotMock), ); - } else if (slotMetadata.members?.get || slotMetadata.members?.set) { + //} else if (slotMetadata.members?.get || slotMetadata.members?.set) { + } else if ( + (slotMetadata.members?.get || slotMetadata.members?.set) && + slotMetadata.members?.configurable && + slotMetadata.members?.enumerable + ) { + //In the test examples/jquery/__tests__/fetch_current_user.test.js-> it('calls into $.ajax with the correct params') + //the Ajax metadata has a 'get' property, causing it to enter here and except. + //while trying to redefine the 'prototype' property. + //The accessor property metadata contains 'configurable' and 'enumberable' properties also Object.defineProperty(mock, slot, slotMock); } else { mock[slot] = slotMock; @@ -1009,8 +1040,19 @@ export class ModuleMocker { let slotMetadata: MockFunctionMetadata | null = null; if (descriptor?.get || descriptor?.set) { + //Specific case required for mocking class definitions imported via types. + //In this case the class definitions are stored in accessor properties. + //All getters were previously ignored except where the containing object had __esModule == true + //Now getters are mocked the class definitions must still be read. + //Example is packages/jest-core/src/__tests__/TestScheduler.test.js -> test('works with default value') // @ts-expect-error ignore type mismatch - slotMetadata = this.getMetadata(descriptor, refs); + if (component.__esModule) { + // @ts-expect-error no index signature + slotMetadata = this.getMetadata(component[slot], refs); + } else { + // @ts-expect-error ignore type mismatch + slotMetadata = this.getMetadata(descriptor, refs); + } } else { // @ts-expect-error no index signature slotMetadata = this.getMetadata(component[slot], refs); @@ -1164,7 +1206,7 @@ export class ModuleMocker { descriptor[accessType] = mock; mock.mockImplementation(function (this: unknown) { - return originalAccessor.apply(this, []); + return originalAccessor.call(this); }); Object.defineProperty(object, methodName, descriptor); } else if (accessType == 'set' && descriptor['set']) { @@ -1181,7 +1223,7 @@ export class ModuleMocker { descriptor[accessType] = mock; mock.mockImplementation(function (this: unknown) { - return originalAccessor.apply(this, arguments[0]); + return originalAccessor.call(this, arguments[0]); }); Object.defineProperty(object, methodName, descriptor); } else { From 9e7fe2012616b616e091d66f70b5a6e6c968c7ed Mon Sep 17 00:00:00 2001 From: staplespeter Date: Sat, 17 Sep 2022 00:26:35 +0100 Subject: [PATCH 04/13] Update packages/jest-mock/src/index.ts Co-authored-by: Tom Mrazauskas --- packages/jest-mock/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index a42b0f95c804..e60de0806763 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -1023,7 +1023,7 @@ export class ModuleMocker { proto = Object.getPrototypeOf(proto); } - let slotMetadata: MockFunctionMetadata | null = null; + let slotMetadata: MockMetadata | null = null; if (descriptor?.get || descriptor?.set) { //Specific case required for mocking class definitions imported via types. //In this case the class definitions are stored in accessor properties. From 38e6918cb78a0e5b9d4ce5869bf58f8ceb19733a Mon Sep 17 00:00:00 2001 From: Peter Staples Date: Sat, 17 Sep 2022 00:41:45 +0100 Subject: [PATCH 05/13] Bug-13140 Changing types for Updating types for automocked class getters/setters --- packages/jest-mock/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index e60de0806763..982020644a80 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -893,7 +893,7 @@ export class ModuleMocker { } this._getSlots(metadata.members).forEach(slot => { - let slotMock: Mock; + let slotMock: Mocked; const slotMetadata = (metadata.members && metadata.members[slot]) || {}; if (slotMetadata.ref != null) { @@ -917,7 +917,7 @@ export class ModuleMocker { callbacks.push( (function (ref) { return () => Object.defineProperty(mock, slot, ref); - })(slotMock), + })(slotMock as PropertyDescriptor), ); } else if ( (slotMetadata.members?.get || slotMetadata.members?.set) && @@ -928,7 +928,7 @@ export class ModuleMocker { //the Ajax metadata has a 'get' property, causing it to enter here and except //while trying to redefine the 'prototype' property. //The accessor property metadata contains 'configurable' and 'enumberable' properties also - Object.defineProperty(mock, slot, slotMock); + Object.defineProperty(mock, slot, slotMock as PropertyDescriptor); } else { mock[slot] = slotMock; } From a5613b9df85e6f32ae1ab27e869ba6d4a76487d6 Mon Sep 17 00:00:00 2001 From: Peter Staples Date: Tue, 20 Sep 2022 13:03:02 +0100 Subject: [PATCH 06/13] Bug-13140: Removing unnecessary comments. Removed unnecessary condition. --- .../jest-mock/src/__tests__/index.test.ts | 5 ---- packages/jest-mock/src/index.ts | 30 +++++-------------- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/packages/jest-mock/src/__tests__/index.test.ts b/packages/jest-mock/src/__tests__/index.test.ts index 595e0a1a5ca3..d18b9b27f8dd 100644 --- a/packages/jest-mock/src/__tests__/index.test.ts +++ b/packages/jest-mock/src/__tests__/index.test.ts @@ -192,11 +192,6 @@ describe('moduleMocker', () => { expect(mock.nonEnumGetter).toBeUndefined(); }); - //This test was never valid. ModuleMocker mocked the read value of the getter - //i.e. the returned class on an ES module getter. - //So this test only verified that SOMETHING (10) was assigned to the enumGetter property. - //Exclusion case has been added to the ModuleMocker to ensure that ES modules - //are still mocked, whilst accessor properties are too. it('mocks getters of ES modules', () => { const foo = Object.defineProperties( {}, diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 982020644a80..4b1d26fadbe0 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -512,25 +512,9 @@ export class ModuleMocker { if (!isReadonlyProp(object, prop)) { const propDesc = Object.getOwnPropertyDescriptor(object, prop); - //In test packages/jest-runtime/src/__tests__/runtime_require_mock.test.js -> it('multiple node core modules returns correct module') - //when the component.name == 'propertyIsEnumerable' (object.name at start of _getSlots()) - //when retrieving metadata, the match for object !== ObjectProto fails. - //This causes an error where an ancestor prototype getter method, - //and introduction of mocking getters, results in a getter object - //being assigned to the prototype property __proto__, - //which then breaks when later building the mock. Ignore getters for __proto__. - //Please note that the metadata structure for the objects in this test seems heavily polluted - //with unnecessary objects, as if the exclusion conditions for object types in _getSlots() - //is failing in multiple cases. - - //it seems the OR condition "object.__esModule" was added to allow - //getters returning imported class definitions to be included whilst - //other accessor properties with getters were ignored. - //Can the "object.__esModule" condition now be removed? if ( - (propDesc !== undefined && - !(propDesc.get && prop == '__proto__')) || - object.__esModule + propDesc !== undefined && + !(propDesc.get && prop == '__proto__') ) { slots.add(prop); } @@ -924,10 +908,12 @@ export class ModuleMocker { slotMetadata.members?.configurable && slotMetadata.members?.enumerable ) { - //In the test examples/jquery/__tests__/fetch_current_user.test.js-> it('calls into $.ajax with the correct params') - //the Ajax metadata has a 'get' property, causing it to enter here and except - //while trying to redefine the 'prototype' property. - //The accessor property metadata contains 'configurable' and 'enumberable' properties also + //In some cases, e.g. third-party APIs, a 'prototype' ancestor to be + //mocked has a function property called 'get'. In this circumstance + //the 'prototype' property cannot be redefined and doing so causes an + //exception. Checks have been added for the 'configurable' and + //'enumberable' properties present on true accessor property + //descriptors to prevent the attempt to replace the API. Object.defineProperty(mock, slot, slotMock as PropertyDescriptor); } else { mock[slot] = slotMock; From 7b7cc5b39bf7b6a2478900827bcf38f8776b2216 Mon Sep 17 00:00:00 2001 From: Peter Staples Date: Tue, 20 Sep 2022 13:10:49 +0100 Subject: [PATCH 07/13] Bug-13140 Updating comment --- packages/jest-mock/src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 4b1d26fadbe0..1a9cebbed1e2 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -1011,11 +1011,10 @@ export class ModuleMocker { let slotMetadata: MockMetadata | null = null; if (descriptor?.get || descriptor?.set) { - //Specific case required for mocking class definitions imported via types. + //Specific case required for mocking class definitions imported via modules. //In this case the class definitions are stored in accessor properties. //All getters were previously ignored except where the containing object had __esModule == true //Now getters are mocked the class definitions must still be read. - //Example is packages/jest-core/src/__tests__/TestScheduler.test.js -> test('works with default value') // @ts-expect-error ignore type mismatch if (component.__esModule) { // @ts-expect-error no index signature From d02a2ddd553c34bac7538c1e1ac31e6f116c9034 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 28 Sep 2022 09:09:05 +0200 Subject: [PATCH 08/13] Apply suggestions from code review --- packages/jest-mock/src/index.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 1a9cebbed1e2..4fbf3b0dd0a2 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -889,11 +889,11 @@ export class ModuleMocker { } else { slotMock = this._generateMock(slotMetadata, callbacks, refs); - //For superclass accessor properties the subclass metadata contains the definitions - //for the getter and setter methods, and the superclass refs to them. - //The mock implementations are not available until the callbacks have been executed. - //Missing getter and setter refs will be resolved as their callbacks have been - //stacked before the setting of the accessor definition is stacked. + // For superclass accessor properties the subclass metadata contains the definitions + // for the getter and setter methods, and the superclass refs to them. + // The mock implementations are not available until the callbacks have been executed. + // Missing getter and setter refs will be resolved as their callbacks have been + // stacked before the setting of the accessor definition is stacked. if ( slotMetadata.members?.get?.ref !== undefined || slotMetadata.members?.set?.ref !== undefined @@ -908,12 +908,12 @@ export class ModuleMocker { slotMetadata.members?.configurable && slotMetadata.members?.enumerable ) { - //In some cases, e.g. third-party APIs, a 'prototype' ancestor to be - //mocked has a function property called 'get'. In this circumstance - //the 'prototype' property cannot be redefined and doing so causes an - //exception. Checks have been added for the 'configurable' and - //'enumberable' properties present on true accessor property - //descriptors to prevent the attempt to replace the API. + // In some cases, e.g. third-party APIs, a 'prototype' ancestor to be + // mocked has a function property called 'get'. In this circumstance + // the 'prototype' property cannot be redefined and doing so causes an + // exception. Checks have been added for the 'configurable' and + // 'enumberable' properties present on true accessor property + // descriptors to prevent the attempt to replace the API. Object.defineProperty(mock, slot, slotMock as PropertyDescriptor); } else { mock[slot] = slotMock; @@ -1011,10 +1011,10 @@ export class ModuleMocker { let slotMetadata: MockMetadata | null = null; if (descriptor?.get || descriptor?.set) { - //Specific case required for mocking class definitions imported via modules. - //In this case the class definitions are stored in accessor properties. - //All getters were previously ignored except where the containing object had __esModule == true - //Now getters are mocked the class definitions must still be read. + // Specific case required for mocking class definitions imported via modules. + // In this case the class definitions are stored in accessor properties. + // All getters were previously ignored except where the containing object had __esModule == true + // Now getters are mocked the class definitions must still be read. // @ts-expect-error ignore type mismatch if (component.__esModule) { // @ts-expect-error no index signature From c45be304c35ae11d450c28d66df9b09555e27c3f Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 28 Sep 2022 09:10:11 +0200 Subject: [PATCH 09/13] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88cfba26a809..68199551cc54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - `[jest-haste-map]` Remove `__proto__` usage ([#13256](https://github.com/facebook/jest/pull/13256)) - `[jest-mock]` Improve `spyOn` typings to handle optional properties ([#13247](https://github.com/facebook/jest/pull/13247)) +- `[jest-mock]` Fix mocking of getters and setters on classes ([#13145](https://github.com/facebook/jest/pull/13145)) - `[jest-snapshot]` Throw useful error when an array is passed as property matchers ([#13263](https://github.com/facebook/jest/pull/13263)) ### Chore & Maintenance From f86074a3f6e38c6c6f3ba476070ad07437fa328d Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Wed, 28 Sep 2022 09:17:09 +0200 Subject: [PATCH 10/13] copyright headers --- packages/jest-mock/src/__tests__/SuperTestClass.ts | 8 ++++++++ packages/jest-mock/src/__tests__/TestClass.ts | 8 ++++++++ .../src/__tests__/class-mocks-dual-import.test.ts | 8 ++++++++ .../src/__tests__/class-mocks-single-import.test.ts | 8 ++++++++ packages/jest-mock/src/__tests__/class-mocks-types.ts | 8 ++++++++ packages/jest-mock/src/__tests__/class-mocks.test.ts | 8 ++++++++ 6 files changed, 48 insertions(+) diff --git a/packages/jest-mock/src/__tests__/SuperTestClass.ts b/packages/jest-mock/src/__tests__/SuperTestClass.ts index 2ea722af2f3a..ae1c262e34f6 100644 --- a/packages/jest-mock/src/__tests__/SuperTestClass.ts +++ b/packages/jest-mock/src/__tests__/SuperTestClass.ts @@ -1,3 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + export class SuperTestClass { static staticTestProperty = 'staticTestProperty'; diff --git a/packages/jest-mock/src/__tests__/TestClass.ts b/packages/jest-mock/src/__tests__/TestClass.ts index 59b17d7810f6..e4197db98abe 100644 --- a/packages/jest-mock/src/__tests__/TestClass.ts +++ b/packages/jest-mock/src/__tests__/TestClass.ts @@ -1,3 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + import {SuperTestClass} from './SuperTestClass'; export default class TestClass extends SuperTestClass {} diff --git a/packages/jest-mock/src/__tests__/class-mocks-dual-import.test.ts b/packages/jest-mock/src/__tests__/class-mocks-dual-import.test.ts index f017806fce07..510484d06700 100644 --- a/packages/jest-mock/src/__tests__/class-mocks-dual-import.test.ts +++ b/packages/jest-mock/src/__tests__/class-mocks-dual-import.test.ts @@ -1,3 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + import {SuperTestClass} from './SuperTestClass'; import TestClass from './TestClass'; jest.mock('./SuperTestClass'); diff --git a/packages/jest-mock/src/__tests__/class-mocks-single-import.test.ts b/packages/jest-mock/src/__tests__/class-mocks-single-import.test.ts index b99054d8734b..2b326b971ea5 100644 --- a/packages/jest-mock/src/__tests__/class-mocks-single-import.test.ts +++ b/packages/jest-mock/src/__tests__/class-mocks-single-import.test.ts @@ -1,3 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + import SuperTestClass, {TestClass} from './class-mocks-types'; jest.mock('./class-mocks-types'); diff --git a/packages/jest-mock/src/__tests__/class-mocks-types.ts b/packages/jest-mock/src/__tests__/class-mocks-types.ts index e39e582e9ad1..4e277903940f 100644 --- a/packages/jest-mock/src/__tests__/class-mocks-types.ts +++ b/packages/jest-mock/src/__tests__/class-mocks-types.ts @@ -1,3 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + export default class SuperTestClass { static staticTestProperty = 'staticTestProperty'; diff --git a/packages/jest-mock/src/__tests__/class-mocks.test.ts b/packages/jest-mock/src/__tests__/class-mocks.test.ts index 874e2940ec7a..a0120958b54b 100644 --- a/packages/jest-mock/src/__tests__/class-mocks.test.ts +++ b/packages/jest-mock/src/__tests__/class-mocks.test.ts @@ -1,3 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + describe('Testing the mocking of a class', () => { it('can call an instance method', () => { class TestClass { From 23813a67a4fa4c0e76d4180830aedb51807305ea Mon Sep 17 00:00:00 2001 From: Peter Staples Date: Wed, 5 Oct 2022 19:51:13 +0100 Subject: [PATCH 11/13] Bug-13140 Added condition to prevent refs to mocked superclass 'get' functions being mocked as accessor objects. --- package.json | 1 + .../__tests__/google-cloud-datastore.test.ts | 18 + packages/jest-mock/src/index.ts | 19 +- yarn.lock | 661 +++++++++++++++++- 4 files changed, 681 insertions(+), 18 deletions(-) create mode 100644 packages/jest-mock/src/__tests__/google-cloud-datastore.test.ts diff --git a/package.json b/package.json index 9526e6724afc..d6d62d3560cb 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@babel/preset-typescript": "^7.0.0", "@babel/register": "^7.0.0", "@crowdin/cli": "^3.5.2", + "@google-cloud/datastore": "^7.0.0", "@jest/globals": "workspace:^", "@jest/test-utils": "workspace:^", "@lerna-lite/cli": "^1.11.3", diff --git a/packages/jest-mock/src/__tests__/google-cloud-datastore.test.ts b/packages/jest-mock/src/__tests__/google-cloud-datastore.test.ts new file mode 100644 index 000000000000..cf5d93e96fa3 --- /dev/null +++ b/packages/jest-mock/src/__tests__/google-cloud-datastore.test.ts @@ -0,0 +1,18 @@ +import {Datastore} from '@google-cloud/datastore'; +jest.mock('@google-cloud/datastore'); +const mockedDataStore = jest.mocked(Datastore); + +describe('google cloud datastore tests', () => { + it('can mock a google cloud datastore', async () => { + const ds = new Datastore(); + const task = { + data: { + description: 'Test description', + }, + key: ds.key(['Task', 'testTask']), + }; + await ds.save(task); + expect(mockedDataStore.prototype.save).toBeCalledTimes(1); + expect(mockedDataStore.prototype.save).toBeCalledWith(task); + }); +}); diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 117be1f3cbe5..5f261edb0347 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -926,9 +926,18 @@ export class ModuleMocker { // The mock implementations are not available until the callbacks have been executed. // Missing getter and setter refs will be resolved as their callbacks have been // stacked before the setting of the accessor definition is stacked. + + // In some cases, e.g. third-party APIs, a 'prototype' ancestor to be + // mocked has a function property called 'get'. In this circumstance + // the 'prototype' property cannot be redefined and doing so causes an + // exception. Checks have been added for the 'configurable' and + // 'enumberable' properties present on true accessor property + // descriptors to prevent the attempt to replace the API. if ( - slotMetadata.members?.get?.ref !== undefined || - slotMetadata.members?.set?.ref !== undefined + (slotMetadata.members?.get?.ref !== undefined || + slotMetadata.members?.set?.ref !== undefined) && + slotMetadata.members?.configurable && + slotMetadata.members?.enumerable ) { callbacks.push( (function (ref) { @@ -940,12 +949,6 @@ export class ModuleMocker { slotMetadata.members?.configurable && slotMetadata.members?.enumerable ) { - // In some cases, e.g. third-party APIs, a 'prototype' ancestor to be - // mocked has a function property called 'get'. In this circumstance - // the 'prototype' property cannot be redefined and doing so causes an - // exception. Checks have been added for the 'configurable' and - // 'enumberable' properties present on true accessor property - // descriptors to prevent the attempt to replace the API. Object.defineProperty(mock, slot, slotMock as PropertyDescriptor); } else { mock[slot] = slotMock; diff --git a/yarn.lock b/yarn.lock index ecb380ee4efe..68b05115116c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -634,6 +634,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.9.4": + version: 7.19.3 + resolution: "@babel/parser@npm:7.19.3" + bin: + parser: ./bin/babel-parser.js + checksum: 854f1390328a8cea5d95ed2a8655a8976cdb41e72393845df0f86088dc777817a5e015a1a61739d312accccf1a22358fb70707a013d25596251cceba2c8985ee + languageName: node + linkType: hard + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.18.6" @@ -2509,6 +2518,54 @@ __metadata: languageName: node linkType: hard +"@google-cloud/datastore@npm:^7.0.0": + version: 7.0.0 + resolution: "@google-cloud/datastore@npm:7.0.0" + dependencies: + "@google-cloud/promisify": ^2.0.0 + arrify: ^2.0.1 + concat-stream: ^2.0.0 + extend: ^3.0.2 + google-gax: ^3.0.1 + is: ^3.3.0 + split-array-stream: ^2.0.0 + stream-events: ^1.0.5 + checksum: 3b12c8e55ee8bba9d0fe3564d186d3797ed24c88d9bdb34b741414b0c154161dd59964a5b21f14f44ad56b3ec2e7b5f7ce71b8444fc73a1e37d85b99a94614f2 + languageName: node + linkType: hard + +"@google-cloud/promisify@npm:^2.0.0": + version: 2.0.4 + resolution: "@google-cloud/promisify@npm:2.0.4" + checksum: 51a9fb6c43e5342d995435b3660afe8d7a498ed65e6f5fef6492cc2ac2b494c1ec89e8f220b8a8e23f1c90334b7db5169c292f0a317e971d57366426a2420247 + languageName: node + linkType: hard + +"@grpc/grpc-js@npm:~1.7.0": + version: 1.7.1 + resolution: "@grpc/grpc-js@npm:1.7.1" + dependencies: + "@grpc/proto-loader": ^0.7.0 + "@types/node": ">=12.12.47" + checksum: ffa9f051224dcab87dd2e47e21cb6f001d3e18b0e2a8998bdb960fc557aee73000c743f74cabba14bd72db4ed900ee0dd4f1400852b191312a2e0016d9648618 + languageName: node + linkType: hard + +"@grpc/proto-loader@npm:^0.7.0": + version: 0.7.3 + resolution: "@grpc/proto-loader@npm:0.7.3" + dependencies: + "@types/long": ^4.0.1 + lodash.camelcase: ^4.3.0 + long: ^4.0.0 + protobufjs: ^7.0.0 + yargs: ^16.2.0 + bin: + proto-loader-gen-types: build/bin/proto-loader-gen-types.js + checksum: a37712bca61da8d3b3dbf3fe39fa04447d748fd1f96f0758a1e99ede652b0afdfc17ce8093b596f64e9b685be57214e83821e3795905cc2a410336884458ac6d + languageName: node + linkType: hard + "@hapi/hoek@npm:^9.0.0": version: 9.3.0 resolution: "@hapi/hoek@npm:9.3.0" @@ -2738,6 +2795,7 @@ __metadata: "@babel/preset-typescript": ^7.0.0 "@babel/register": ^7.0.0 "@crowdin/cli": ^3.5.2 + "@google-cloud/datastore": ^7.0.0 "@jest/globals": "workspace:^" "@jest/test-utils": "workspace:^" "@lerna-lite/cli": ^1.11.3 @@ -3645,6 +3703,79 @@ __metadata: languageName: node linkType: hard +"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/aspromise@npm:1.1.2" + checksum: 011fe7ef0826b0fd1a95935a033a3c0fd08483903e1aa8f8b4e0704e3233406abb9ee25350ec0c20bbecb2aad8da0dcea58b392bbd77d6690736f02c143865d2 + languageName: node + linkType: hard + +"@protobufjs/base64@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/base64@npm:1.1.2" + checksum: 67173ac34de1e242c55da52c2f5bdc65505d82453893f9b51dc74af9fe4c065cf4a657a4538e91b0d4a1a1e0a0642215e31894c31650ff6e3831471061e1ee9e + languageName: node + linkType: hard + +"@protobufjs/codegen@npm:^2.0.4": + version: 2.0.4 + resolution: "@protobufjs/codegen@npm:2.0.4" + checksum: 59240c850b1d3d0b56d8f8098dd04787dcaec5c5bd8de186fa548de86b86076e1c50e80144b90335e705a044edf5bc8b0998548474c2a10a98c7e004a1547e4b + languageName: node + linkType: hard + +"@protobufjs/eventemitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/eventemitter@npm:1.1.0" + checksum: 0369163a3d226851682f855f81413cbf166cd98f131edb94a0f67f79e75342d86e89df9d7a1df08ac28be2bc77e0a7f0200526bb6c2a407abbfee1f0262d5fd7 + languageName: node + linkType: hard + +"@protobufjs/fetch@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/fetch@npm:1.1.0" + dependencies: + "@protobufjs/aspromise": ^1.1.1 + "@protobufjs/inquire": ^1.1.0 + checksum: 3fce7e09eb3f1171dd55a192066450f65324fd5f7cc01a431df01bb00d0a895e6bfb5b0c5561ce157ee1d886349c90703d10a4e11a1a256418ff591b969b3477 + languageName: node + linkType: hard + +"@protobufjs/float@npm:^1.0.2": + version: 1.0.2 + resolution: "@protobufjs/float@npm:1.0.2" + checksum: 5781e1241270b8bd1591d324ca9e3a3128d2f768077a446187a049e36505e91bc4156ed5ac3159c3ce3d2ba3743dbc757b051b2d723eea9cd367bfd54ab29b2f + languageName: node + linkType: hard + +"@protobufjs/inquire@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/inquire@npm:1.1.0" + checksum: ca06f02eaf65ca36fb7498fc3492b7fc087bfcc85c702bac5b86fad34b692bdce4990e0ef444c1e2aea8c034227bd1f0484be02810d5d7e931c55445555646f4 + languageName: node + linkType: hard + +"@protobufjs/path@npm:^1.1.2": + version: 1.1.2 + resolution: "@protobufjs/path@npm:1.1.2" + checksum: 856eeb532b16a7aac071cacde5c5620df800db4c80cee6dbc56380524736205aae21e5ae47739114bf669ab5e8ba0e767a282ad894f3b5e124197cb9224445ee + languageName: node + linkType: hard + +"@protobufjs/pool@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/pool@npm:1.1.0" + checksum: d6a34fbbd24f729e2a10ee915b74e1d77d52214de626b921b2d77288bd8f2386808da2315080f2905761527cceffe7ec34c7647bd21a5ae41a25e8212ff79451 + languageName: node + linkType: hard + +"@protobufjs/utf8@npm:^1.1.0": + version: 1.1.0 + resolution: "@protobufjs/utf8@npm:1.1.0" + checksum: f9bf3163d13aaa3b6f5e6fbf37a116e094ea021c0e1f2a7ccd0e12a29e2ce08dafba4e8b36e13f8ed7397e1591610ce880ed1289af4d66cf4ace8a36a9557278 + languageName: node + linkType: hard + "@react-native-community/cli-clean@npm:^9.1.0": version: 9.1.0 resolution: "@react-native-community/cli-clean@npm:9.1.0" @@ -4644,6 +4775,30 @@ __metadata: languageName: node linkType: hard +"@types/linkify-it@npm:*": + version: 3.0.2 + resolution: "@types/linkify-it@npm:3.0.2" + checksum: dff8f10fafb885422474e456596f12d518ec4cdd6c33cca7a08e7c86b912d301ed91cf5a7613e148c45a12600dc9ab3d85ad16d5b48dc1aaeda151a68f16b536 + languageName: node + linkType: hard + +"@types/long@npm:^4.0.0, @types/long@npm:^4.0.1": + version: 4.0.2 + resolution: "@types/long@npm:4.0.2" + checksum: d16cde7240d834cf44ba1eaec49e78ae3180e724cd667052b194a372f350d024cba8dd3f37b0864931683dab09ca935d52f0c4c1687178af5ada9fc85b0635f4 + languageName: node + linkType: hard + +"@types/markdown-it@npm:^12.2.3": + version: 12.2.3 + resolution: "@types/markdown-it@npm:12.2.3" + dependencies: + "@types/linkify-it": "*" + "@types/mdurl": "*" + checksum: 868824a3e4d00718ba9cd4762cf16694762a670860f4b402e6e9f952b6841a2027488bdc55d05c2b960bf5078df21a9d041270af7e8949514645fe88fdb722ac + languageName: node + linkType: hard + "@types/mdast@npm:^3.0.0": version: 3.0.10 resolution: "@types/mdast@npm:3.0.10" @@ -4653,7 +4808,7 @@ __metadata: languageName: node linkType: hard -"@types/mdurl@npm:^1.0.0": +"@types/mdurl@npm:*, @types/mdurl@npm:^1.0.0": version: 1.0.2 resolution: "@types/mdurl@npm:1.0.2" checksum: 79c7e523b377f53cf1f5a240fe23d0c6cae856667692bd21bf1d064eafe5ccc40ae39a2aa0a9a51e8c94d1307228c8f6b121e847124591a9a828c3baf65e86e2 @@ -5953,6 +6108,13 @@ __metadata: languageName: node linkType: hard +"arrify@npm:^2.0.0, arrify@npm:^2.0.1": + version: 2.0.1 + resolution: "arrify@npm:2.0.1" + checksum: 067c4c1afd182806a82e4c1cb8acee16ab8b5284fbca1ce29408e6e91281c36bb5b612f6ddfbd40a0f7a7e0c75bf2696eb94c027f6e328d6e9c52465c98e4209 + languageName: node + linkType: hard + "asap@npm:~2.0.3, asap@npm:~2.0.6": version: 2.0.6 resolution: "asap@npm:2.0.6" @@ -6324,7 +6486,7 @@ __metadata: languageName: node linkType: hard -"base64-js@npm:^1.1.2, base64-js@npm:^1.3.1": +"base64-js@npm:^1.1.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 @@ -6377,6 +6539,13 @@ __metadata: languageName: node linkType: hard +"bignumber.js@npm:^9.0.0": + version: 9.1.0 + resolution: "bignumber.js@npm:9.1.0" + checksum: 52ec2bb5a3874d7dc1a1018f28f8f7aff4683515ffd09d6c2d93191343c76567ae0ee32cc45149d53afb2b904bc62ed471a307b35764beea7e9db78e56bef6c6 + languageName: node + linkType: hard + "binary-extensions@npm:^2.0.0": version: 2.2.0 resolution: "binary-extensions@npm:2.2.0" @@ -6395,6 +6564,13 @@ __metadata: languageName: node linkType: hard +"bluebird@npm:^3.7.2": + version: 3.7.2 + resolution: "bluebird@npm:3.7.2" + checksum: 869417503c722e7dc54ca46715f70e15f4d9c602a423a02c825570862d12935be59ed9c7ba34a9b31f186c017c23cac6b54e35446f8353059c101da73eac22ef + languageName: node + linkType: hard + "body-parser@npm:1.20.0": version: 1.20.0 resolution: "body-parser@npm:1.20.0" @@ -6558,6 +6734,13 @@ __metadata: languageName: node linkType: hard +"buffer-equal-constant-time@npm:1.0.1": + version: 1.0.1 + resolution: "buffer-equal-constant-time@npm:1.0.1" + checksum: 80bb945f5d782a56f374b292770901065bad21420e34936ecbe949e57724b4a13874f735850dd1cc61f078773c4fb5493a41391e7bda40d1fa388d6bd80daaab + languageName: node + linkType: hard + "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" @@ -6773,6 +6956,15 @@ __metadata: languageName: node linkType: hard +"catharsis@npm:^0.9.0": + version: 0.9.0 + resolution: "catharsis@npm:0.9.0" + dependencies: + lodash: ^4.17.15 + checksum: da867df1fd01823ea5a7283886ba382f6eb5b1fe5af356e00fd944a02d9b867f4ea2fc7f61416c53427f62760fdbd41614f6e8ae37686d2c3a4696871526df20 + languageName: node + linkType: hard + "ccount@npm:^1.0.0": version: 1.1.0 resolution: "ccount@npm:1.1.0" @@ -8609,6 +8801,18 @@ __metadata: languageName: node linkType: hard +"duplexify@npm:^4.0.0": + version: 4.1.2 + resolution: "duplexify@npm:4.1.2" + dependencies: + end-of-stream: ^1.4.1 + inherits: ^2.0.3 + readable-stream: ^3.1.1 + stream-shift: ^1.0.0 + checksum: 964376c61c0e92f6ed0694b3ba97c84f199413dc40ab8dfdaef80b7a7f4982fcabf796214e28ed614a5bc1ec45488a29b81e7d46fa3f5ddf65bcb118c20145ad + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -8616,6 +8820,15 @@ __metadata: languageName: node linkType: hard +"ecdsa-sig-formatter@npm:1.0.11, ecdsa-sig-formatter@npm:^1.0.11": + version: 1.0.11 + resolution: "ecdsa-sig-formatter@npm:1.0.11" + dependencies: + safe-buffer: ^5.0.1 + checksum: 207f9ab1c2669b8e65540bce29506134613dd5f122cccf1e6a560f4d63f2732d427d938f8481df175505aad94583bcb32c688737bb39a6df0625f903d6d93c03 + languageName: node + linkType: hard + "ee-first@npm:1.1.1": version: 1.1.1 resolution: "ee-first@npm:1.1.1" @@ -8732,6 +8945,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:~2.1.0": + version: 2.1.0 + resolution: "entities@npm:2.1.0" + checksum: a10a877e489586a3f6a691fe49bf3fc4e58f06c8e80522f08214a5150ba457e7017b447d4913a3fa041bda06ee4c92517baa4d8d75373eaa79369e9639225ffd + languageName: node + linkType: hard + "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -8979,6 +9199,25 @@ __metadata: languageName: node linkType: hard +"escodegen@npm:^1.13.0": + version: 1.14.3 + resolution: "escodegen@npm:1.14.3" + dependencies: + esprima: ^4.0.1 + estraverse: ^4.2.0 + esutils: ^2.0.2 + optionator: ^0.8.1 + source-map: ~0.6.1 + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: bin/escodegen.js + esgenerate: bin/esgenerate.js + checksum: 381cdc4767ecdb221206bbbab021b467bbc2a6f5c9a99c9e6353040080bdd3dfe73d7604ad89a47aca6ea7d58bc635f6bd3fbc8da9a1998e9ddfa8372362ccd0 + languageName: node + linkType: hard + "escodegen@npm:^2.0.0": version: 2.0.0 resolution: "escodegen@npm:2.0.0" @@ -9226,6 +9465,17 @@ __metadata: languageName: node linkType: hard +"espree@npm:^9.0.0": + version: 9.4.0 + resolution: "espree@npm:9.4.0" + dependencies: + acorn: ^8.8.0 + acorn-jsx: ^5.3.2 + eslint-visitor-keys: ^3.3.0 + checksum: 2e3020dde67892d2ba3632413b44d0dc31d92c29ce72267d7ec24216a562f0a6494d3696e2fa39a3ec8c0e0088d773947ab2925fbb716801a11eb8dd313ac89c + languageName: node + linkType: hard + "espree@npm:^9.3.2, espree@npm:^9.3.3": version: 9.3.3 resolution: "espree@npm:9.3.3" @@ -9265,7 +9515,7 @@ __metadata: languageName: node linkType: hard -"estraverse@npm:^4.1.1": +"estraverse@npm:^4.1.1, estraverse@npm:^4.2.0": version: 4.3.0 resolution: "estraverse@npm:4.3.0" checksum: a6299491f9940bb246124a8d44b7b7a413a8336f5436f9837aaa9330209bd9ee8af7e91a654a3545aee9c54b3308e78ee360cef1d777d37cfef77d2fa33b5827 @@ -9666,7 +9916,7 @@ __metadata: languageName: node linkType: hard -"extend@npm:^3.0.0": +"extend@npm:^3.0.0, extend@npm:^3.0.2": version: 3.0.2 resolution: "extend@npm:3.0.2" checksum: a50a8309ca65ea5d426382ff09f33586527882cf532931cb08ca786ea3146c0553310bda688710ff61d7668eba9f96b923fe1420cdf56a2c3eaf30fcab87b515 @@ -9757,6 +10007,13 @@ __metadata: languageName: node linkType: hard +"fast-text-encoding@npm:^1.0.0, fast-text-encoding@npm:^1.0.3": + version: 1.0.6 + resolution: "fast-text-encoding@npm:1.0.6" + checksum: 9d58f694314b3283e785bf61954902536da228607ad246905e30256f9ab8331f780ac987e7222c9f5eafd04168d07e12b8054c85cedb76a2c05af0e82387a903 + languageName: node + linkType: hard + "fast-url-parser@npm:1.1.3": version: 1.1.3 resolution: "fast-url-parser@npm:1.1.3" @@ -10311,6 +10568,28 @@ __metadata: languageName: node linkType: hard +"gaxios@npm:^5.0.0, gaxios@npm:^5.0.1": + version: 5.0.2 + resolution: "gaxios@npm:5.0.2" + dependencies: + extend: ^3.0.2 + https-proxy-agent: ^5.0.0 + is-stream: ^2.0.0 + node-fetch: ^2.6.7 + checksum: 117036131cc0d0a268d2d99fffe6a6cc6a4e88dd5b77ce23d3f0b4aff1291b8af169dae20e88799adc986cf3ae507acfaeb70f6ceca8c5d6b8c28e3dde5c992a + languageName: node + linkType: hard + +"gcp-metadata@npm:^5.0.0": + version: 5.0.1 + resolution: "gcp-metadata@npm:5.0.1" + dependencies: + gaxios: ^5.0.0 + json-bigint: ^1.0.0 + checksum: abc0a3b8375c4101fa80b492d108bebbefa5531b8b5ecf9adefef0def2631d242263e17dd8d2917068fab7954992347004b1c18240f89832083bb964974dfecf + languageName: node + linkType: hard + "gensync@npm:^1.0.0-beta.1, gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" @@ -10637,6 +10916,59 @@ __metadata: languageName: node linkType: hard +"google-auth-library@npm:^8.0.2": + version: 8.5.2 + resolution: "google-auth-library@npm:8.5.2" + dependencies: + arrify: ^2.0.0 + base64-js: ^1.3.0 + ecdsa-sig-formatter: ^1.0.11 + fast-text-encoding: ^1.0.0 + gaxios: ^5.0.0 + gcp-metadata: ^5.0.0 + gtoken: ^6.1.0 + jws: ^4.0.0 + lru-cache: ^6.0.0 + checksum: 5ab2904f5da3c119a7c241a1d5a11640468a7da58dfcec8a9cad181cc2723e6662b3c65997906069852d9fa066ba3e4b7f14e11cbb80d541e320b66ead6777dc + languageName: node + linkType: hard + +"google-gax@npm:^3.0.1": + version: 3.5.2 + resolution: "google-gax@npm:3.5.2" + dependencies: + "@grpc/grpc-js": ~1.7.0 + "@grpc/proto-loader": ^0.7.0 + "@types/long": ^4.0.0 + abort-controller: ^3.0.0 + duplexify: ^4.0.0 + fast-text-encoding: ^1.0.3 + google-auth-library: ^8.0.2 + is-stream-ended: ^0.1.4 + node-fetch: ^2.6.1 + object-hash: ^3.0.0 + proto3-json-serializer: ^1.0.0 + protobufjs: 7.1.2 + protobufjs-cli: 1.0.2 + retry-request: ^5.0.0 + bin: + compileProtos: build/tools/compileProtos.js + minifyProtoJson: build/tools/minify.js + checksum: 619a961acba742c30eaba85f5e0fb5903f8fc6713e26bf1736549cbbd43d7fac3ba3379dbc96850117263199ea8e3e74635b078e9464c7fadbbcba8822949135 + languageName: node + linkType: hard + +"google-p12-pem@npm:^4.0.0": + version: 4.0.1 + resolution: "google-p12-pem@npm:4.0.1" + dependencies: + node-forge: ^1.3.1 + bin: + gp12-pem: build/src/bin/gp12-pem.js + checksum: 59a5026331ea67455672e83770da29f09d979f02e06cb2227ea5916f8cca437887c2d3869f2602a686dc84437886ae9d2ac010780803cbe8e5f161c2d02d8efd + languageName: node + linkType: hard + "got@npm:^9.6.0": version: 9.6.0 resolution: "got@npm:9.6.0" @@ -10709,6 +11041,17 @@ __metadata: languageName: node linkType: hard +"gtoken@npm:^6.1.0": + version: 6.1.2 + resolution: "gtoken@npm:6.1.2" + dependencies: + gaxios: ^5.0.1 + google-p12-pem: ^4.0.0 + jws: ^4.0.0 + checksum: cf3210afe2ccee8feaa06f0c7eb942e217244a8563a1d0a71aa3095eea545015896741c1d48654d8de35b7b07579f93e25e5dfe817f06b7e753646b67f7a4ecf + languageName: node + linkType: hard + "gzip-size@npm:^6.0.0": version: 6.0.0 resolution: "gzip-size@npm:6.0.0" @@ -12001,6 +12344,13 @@ __metadata: languageName: node linkType: hard +"is-stream-ended@npm:^0.1.4": + version: 0.1.4 + resolution: "is-stream-ended@npm:0.1.4" + checksum: 56cbc9cfa0a77877777a3df9e186abb5b0ca73dcbcaf0fd87ed573fb8f8e61283abec0fc072c9e3412336edc04449439b8a128d2bcc6c2797158de5465cfaf85 + languageName: node + linkType: hard + "is-stream@npm:^1.1.0": version: 1.1.0 resolution: "is-stream@npm:1.1.0" @@ -12116,6 +12466,13 @@ __metadata: languageName: node linkType: hard +"is@npm:^3.3.0": + version: 3.3.0 + resolution: "is@npm:3.3.0" + checksum: 81fad3b40c606984c2d0699207c4c48d2a0d29cc834b274d0b74c172f3eeebdb981301fe0d690ce090a96bf021a8a1f8b1325262ad9870c525e557ac4a559c56 + languageName: node + linkType: hard + "isarray@npm:0.0.1": version: 0.0.1 resolution: "isarray@npm:0.0.1" @@ -13117,6 +13474,15 @@ __metadata: languageName: node linkType: hard +"js2xmlparser@npm:^4.0.2": + version: 4.0.2 + resolution: "js2xmlparser@npm:4.0.2" + dependencies: + xmlcreate: ^2.0.4 + checksum: 55e3af71dc0104941dfc3e85452230db42ff3870a5777d1ea26bc0c68743f49113a517a7b305421a932b29f10058a012a7da8f5ba07860a05a1dce9fe5b62962 + languageName: node + linkType: hard + "jsc-android@npm:^250230.2.1": version: 250230.2.1 resolution: "jsc-android@npm:250230.2.1" @@ -13155,6 +13521,31 @@ __metadata: languageName: node linkType: hard +"jsdoc@npm:^3.6.3": + version: 3.6.11 + resolution: "jsdoc@npm:3.6.11" + dependencies: + "@babel/parser": ^7.9.4 + "@types/markdown-it": ^12.2.3 + bluebird: ^3.7.2 + catharsis: ^0.9.0 + escape-string-regexp: ^2.0.0 + js2xmlparser: ^4.0.2 + klaw: ^3.0.0 + markdown-it: ^12.3.2 + markdown-it-anchor: ^8.4.1 + marked: ^4.0.10 + mkdirp: ^1.0.4 + requizzle: ^0.2.3 + strip-json-comments: ^3.1.0 + taffydb: 2.6.2 + underscore: ~1.13.2 + bin: + jsdoc: jsdoc.js + checksum: 7920b5cba6200c8f56c9ac2ac5e89d06b6581dd1ce22e66976409fad8b68c16bfd8cd30fe9af58baeacc9f6bd9ba06d901ca4f5e234944f42a3c37e55e4ddcf0 + languageName: node + linkType: hard + "jsdom@npm:^20.0.0": version: 20.0.0 resolution: "jsdom@npm:20.0.0" @@ -13213,6 +13604,15 @@ __metadata: languageName: node linkType: hard +"json-bigint@npm:^1.0.0": + version: 1.0.0 + resolution: "json-bigint@npm:1.0.0" + dependencies: + bignumber.js: ^9.0.0 + checksum: c67bb93ccb3c291e60eb4b62931403e378906aab113ec1c2a8dd0f9a7f065ad6fd9713d627b732abefae2e244ac9ce1721c7a3142b2979532f12b258634ce6f6 + languageName: node + linkType: hard + "json-buffer@npm:3.0.0": version: 3.0.0 resolution: "json-buffer@npm:3.0.0" @@ -13340,6 +13740,27 @@ __metadata: languageName: node linkType: hard +"jwa@npm:^2.0.0": + version: 2.0.0 + resolution: "jwa@npm:2.0.0" + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: ^5.0.1 + checksum: 8f00b71ad5fe94cb55006d0d19202f8f56889109caada2f7eeb63ca81755769ce87f4f48101967f398462e3b8ae4faebfbd5a0269cb755dead5d63c77ba4d2f1 + languageName: node + linkType: hard + +"jws@npm:^4.0.0": + version: 4.0.0 + resolution: "jws@npm:4.0.0" + dependencies: + jwa: ^2.0.0 + safe-buffer: ^5.0.1 + checksum: d68d07aa6d1b8cb35c363a9bd2b48f15064d342a5d9dc18a250dbbce8dc06bd7e4792516c50baa16b8d14f61167c19e851fd7f66b59ecc68b7f6a013759765f7 + languageName: node + linkType: hard + "keyv@npm:^3.0.0": version: 3.1.0 resolution: "keyv@npm:3.1.0" @@ -13393,6 +13814,15 @@ __metadata: languageName: node linkType: hard +"klaw@npm:^3.0.0": + version: 3.0.0 + resolution: "klaw@npm:3.0.0" + dependencies: + graceful-fs: ^4.1.9 + checksum: 1bf9de22392c80d28de8a2babd6f0de29fa52fcdc1654838fd35174b3641c168ec32b8b03022191e3c190efd535c31fce23f85e29cb260245571da7263ef418e + languageName: node + linkType: hard + "kleur@npm:^3.0.3": version: 3.0.3 resolution: "kleur@npm:3.0.3" @@ -13489,6 +13919,15 @@ __metadata: languageName: node linkType: hard +"linkify-it@npm:^3.0.1": + version: 3.0.3 + resolution: "linkify-it@npm:3.0.3" + dependencies: + uc.micro: ^1.0.1 + checksum: 31367a4bb70c5bbc9703246236b504b0a8e049bcd4e0de4291fa50f0ebdebf235b5eb54db6493cb0b1319357c6eeafc4324c9f4aa34b0b943d9f2e11a1268fbc + languageName: node + linkType: hard + "load-json-file@npm:^4.0.0": version: 4.0.0 resolution: "load-json-file@npm:4.0.0" @@ -13576,6 +14015,13 @@ __metadata: languageName: node linkType: hard +"lodash.camelcase@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.camelcase@npm:4.3.0" + checksum: cb9227612f71b83e42de93eccf1232feeb25e705bdb19ba26c04f91e885bfd3dd5c517c4a97137658190581d3493ea3973072ca010aab7e301046d90740393d1 + languageName: node + linkType: hard + "lodash.curry@npm:^4.0.1": version: 4.1.1 resolution: "lodash.curry@npm:4.1.1" @@ -13674,7 +14120,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.15.0, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:~4.17.15": +"lodash@npm:^4.15.0, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:~4.17.15": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -13704,6 +14150,20 @@ __metadata: languageName: node linkType: hard +"long@npm:^4.0.0": + version: 4.0.0 + resolution: "long@npm:4.0.0" + checksum: 16afbe8f749c7c849db1f4de4e2e6a31ac6e617cead3bdc4f9605cb703cd20e1e9fc1a7baba674ffcca57d660a6e5b53a9e236d7b25a295d3855cca79cc06744 + languageName: node + linkType: hard + +"long@npm:^5.0.0": + version: 5.2.0 + resolution: "long@npm:5.2.0" + checksum: 37aa4e67b9c3eebc6d9d675adcc9d06f06059ca268922a71273de389746bf07f0ff282f9e604d17fdf84c4149099b44e936ea2b621a6c4759a216621afa97efd + languageName: node + linkType: hard + "loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" @@ -13868,6 +14328,40 @@ __metadata: languageName: node linkType: hard +"markdown-it-anchor@npm:^8.4.1": + version: 8.6.5 + resolution: "markdown-it-anchor@npm:8.6.5" + peerDependencies: + "@types/markdown-it": "*" + markdown-it: "*" + checksum: 9a466279e52e3c04d67f1e706f2c14df9340e64ddac6eaad22ceaeca777e381103caa942464003e98765a7555bd1ccb5055b624565cb4522a7071dce6ae93460 + languageName: node + linkType: hard + +"markdown-it@npm:^12.3.2": + version: 12.3.2 + resolution: "markdown-it@npm:12.3.2" + dependencies: + argparse: ^2.0.1 + entities: ~2.1.0 + linkify-it: ^3.0.1 + mdurl: ^1.0.1 + uc.micro: ^1.0.5 + bin: + markdown-it: bin/markdown-it.js + checksum: 890555711c1c00fa03b936ca2b213001a3b9b37dea140d8445ae4130ce16628392aad24b12e2a0a9935336ca5951f2957a38f4e5309a2e38eab44e25ff32a41e + languageName: node + linkType: hard + +"marked@npm:^4.0.10": + version: 4.1.0 + resolution: "marked@npm:4.1.0" + bin: + marked: bin/marked.js + checksum: f0b3732a9d6208c933541342e60eb78029bd046c143a6ade0e76ed80b6174f92b186205a9dfe805e435070806ec475b0e87e62d04348eafd2f761c24281b192a + languageName: node + linkType: hard + "md5-file@npm:^5.0.0": version: 5.0.0 resolution: "md5-file@npm:5.0.0" @@ -13995,7 +14489,7 @@ __metadata: languageName: node linkType: hard -"mdurl@npm:^1.0.0": +"mdurl@npm:^1.0.0, mdurl@npm:^1.0.1": version: 1.0.1 resolution: "mdurl@npm:1.0.1" checksum: 71731ecba943926bfbf9f9b51e28b5945f9411c4eda80894221b47cc105afa43ba2da820732b436f0798fd3edbbffcd1fc1415843c41a87fea08a41cc1e3d02b @@ -15222,7 +15716,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:2.6.7, node-fetch@npm:^2.2.0, node-fetch@npm:^2.5.0, node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.7": +"node-fetch@npm:2.6.7, node-fetch@npm:^2.2.0, node-fetch@npm:^2.5.0, node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.7": version: 2.6.7 resolution: "node-fetch@npm:2.6.7" dependencies: @@ -15236,7 +15730,7 @@ __metadata: languageName: node linkType: hard -"node-forge@npm:^1": +"node-forge@npm:^1, node-forge@npm:^1.3.1": version: 1.3.1 resolution: "node-forge@npm:1.3.1" checksum: 08fb072d3d670599c89a1704b3e9c649ff1b998256737f0e06fbd1a5bf41cae4457ccaee32d95052d80bbafd9ffe01284e078c8071f0267dc9744e51c5ed42a9 @@ -15568,6 +16062,13 @@ __metadata: languageName: node linkType: hard +"object-hash@npm:^3.0.0": + version: 3.0.0 + resolution: "object-hash@npm:3.0.0" + checksum: 80b4904bb3857c52cc1bfd0b52c0352532ca12ed3b8a6ff06a90cd209dfda1b95cee059a7625eb9da29537027f68ac4619363491eedb2f5d3dddbba97494fd6c + languageName: node + linkType: hard + "object-inspect@npm:^1.12.0, object-inspect@npm:^1.7.0, object-inspect@npm:^1.9.0": version: 1.12.2 resolution: "object-inspect@npm:1.12.2" @@ -17024,6 +17525,58 @@ __metadata: languageName: node linkType: hard +"proto3-json-serializer@npm:^1.0.0": + version: 1.1.0 + resolution: "proto3-json-serializer@npm:1.1.0" + dependencies: + protobufjs: ^7.0.0 + checksum: a68f7102746a21e2fe6d7afdf89f47b94084a1165ca3062e284922ecca12f20a3ec911bc5f3fdb63fc0cfc9a0cff2b4396befb988c66061ae686d17ff0b6a9fd + languageName: node + linkType: hard + +"protobufjs-cli@npm:1.0.2": + version: 1.0.2 + resolution: "protobufjs-cli@npm:1.0.2" + dependencies: + chalk: ^4.0.0 + escodegen: ^1.13.0 + espree: ^9.0.0 + estraverse: ^5.1.0 + glob: ^8.0.0 + jsdoc: ^3.6.3 + minimist: ^1.2.0 + semver: ^7.1.2 + tmp: ^0.2.1 + uglify-js: ^3.7.7 + peerDependencies: + protobufjs: ^7.0.0 + bin: + pbjs: bin/pbjs + pbts: bin/pbts + checksum: 75dfa8bb76ea390c4f4926120439892fce6c730ec56960e85d5f03cac9c390fd7467d1254833542d722616ab4cb64a622e6de2fb7c75e7c42972878ae447b773 + languageName: node + linkType: hard + +"protobufjs@npm:7.1.2, protobufjs@npm:^7.0.0": + version: 7.1.2 + resolution: "protobufjs@npm:7.1.2" + dependencies: + "@protobufjs/aspromise": ^1.1.2 + "@protobufjs/base64": ^1.1.2 + "@protobufjs/codegen": ^2.0.4 + "@protobufjs/eventemitter": ^1.1.0 + "@protobufjs/fetch": ^1.1.0 + "@protobufjs/float": ^1.0.2 + "@protobufjs/inquire": ^1.1.0 + "@protobufjs/path": ^1.1.2 + "@protobufjs/pool": ^1.1.0 + "@protobufjs/utf8": ^1.1.0 + "@types/node": ">=13.7.0" + long: ^5.0.0 + checksum: ae41669b1b0372fb1d49f506f2d1f2b0fb3dc3cece85987b17bcb544e4cef7c8d27f480486cdec324146ad0a5d22a327166a7ea864a9b3e49cc3c92a5d3f6500 + languageName: node + linkType: hard + "protocols@npm:^2.0.0, protocols@npm:^2.0.1": version: 2.0.1 resolution: "protocols@npm:2.0.1" @@ -18082,6 +18635,15 @@ __metadata: languageName: node linkType: hard +"requizzle@npm:^0.2.3": + version: 0.2.3 + resolution: "requizzle@npm:0.2.3" + dependencies: + lodash: ^4.17.14 + checksum: b1b27c6ad16a2621d4cdb57cd44f01d302974df60f84f94b4d9d313dfe1d375e5b1a12f46010929fe508e83c40696a2105d38c1d1906c228500ac72b23a0d0c6 + languageName: node + linkType: hard + "resolve-cwd@npm:^3.0.0": version: 3.0.0 resolution: "resolve-cwd@npm:3.0.0" @@ -18223,6 +18785,16 @@ __metadata: languageName: node linkType: hard +"retry-request@npm:^5.0.0": + version: 5.0.2 + resolution: "retry-request@npm:5.0.2" + dependencies: + debug: ^4.1.1 + extend: ^3.0.2 + checksum: d6c95d27f4468aa5557605d811cfaa5862be0eaff9fc5f18a338a7c17a7972fbec5b6142abb6b1e494b4c02df875fec2f1c3a281bf79900d33607d8536277ffe + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -18386,7 +18958,7 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 @@ -18561,7 +19133,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:~7.3.0": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:~7.3.0": version: 7.3.7 resolution: "semver@npm:7.3.7" dependencies: @@ -19119,6 +19691,15 @@ __metadata: languageName: node linkType: hard +"split-array-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "split-array-stream@npm:2.0.0" + dependencies: + is-stream-ended: ^0.1.4 + checksum: 2d869c4d00c4eaa6594871fec4e776897c69d842dc5baaa85d65512f79dba1376f986dc912f09bbd3be936e79609fdbbb67db0be2269addd1250acdcba2af3de + languageName: node + linkType: hard + "split-string@npm:^3.0.1, split-string@npm:^3.0.2": version: 3.1.0 resolution: "split-string@npm:3.1.0" @@ -19232,6 +19813,22 @@ __metadata: languageName: node linkType: hard +"stream-events@npm:^1.0.5": + version: 1.0.5 + resolution: "stream-events@npm:1.0.5" + dependencies: + stubs: ^3.0.0 + checksum: 969ce82e34bfbef5734629cc06f9d7f3705a9ceb8fcd6a526332f9159f1f8bbfdb1a453f3ced0b728083454f7706adbbe8428bceb788a0287ca48ba2642dc3fc + languageName: node + linkType: hard + +"stream-shift@npm:^1.0.0": + version: 1.0.1 + resolution: "stream-shift@npm:1.0.1" + checksum: 59b82b44b29ec3699b5519a49b3cedcc6db58c72fb40c04e005525dfdcab1c75c4e0c180b923c380f204bed78211b9bad8faecc7b93dece4d004c3f6ec75737b + languageName: node + linkType: hard + "string-argv@npm:~0.3.1": version: 0.3.1 resolution: "string-argv@npm:0.3.1" @@ -19464,6 +20061,13 @@ __metadata: languageName: node linkType: hard +"stubs@npm:^3.0.0": + version: 3.0.0 + resolution: "stubs@npm:3.0.0" + checksum: dec7b82186e3743317616235c59bfb53284acc312cb9f4c3e97e2205c67a5c158b0ca89db5927e52351582e90a2672822eeaec9db396e23e56893d2a8676e024 + languageName: node + linkType: hard + "style-to-object@npm:0.3.0, style-to-object@npm:^0.3.0": version: 0.3.0 resolution: "style-to-object@npm:0.3.0" @@ -19577,6 +20181,13 @@ __metadata: languageName: node linkType: hard +"taffydb@npm:2.6.2": + version: 2.6.2 + resolution: "taffydb@npm:2.6.2" + checksum: 8fea9cdff71735a40320c4beeb80cb98837076cb89614bc55ac5d67561f35ebae158cfc07a193a1099b5e32746433b2c086b0cd6d56f29aa7c7678e74968335b + languageName: node + linkType: hard + "tapable@npm:^1.0.0": version: 1.1.3 resolution: "tapable@npm:1.1.3" @@ -20235,6 +20846,13 @@ __metadata: languageName: node linkType: hard +"uc.micro@npm:^1.0.1, uc.micro@npm:^1.0.5": + version: 1.0.6 + resolution: "uc.micro@npm:1.0.6" + checksum: 6898bb556319a38e9cf175e3628689347bd26fec15fc6b29fa38e0045af63075ff3fea4cf1fdba9db46c9f0cbf07f2348cd8844889dd31ebd288c29fe0d27e7a + languageName: node + linkType: hard + "uglify-es@npm:^3.1.9": version: 3.3.10 resolution: "uglify-es@npm:3.3.10" @@ -20256,6 +20874,15 @@ __metadata: languageName: node linkType: hard +"uglify-js@npm:^3.7.7": + version: 3.17.2 + resolution: "uglify-js@npm:3.17.2" + bin: + uglifyjs: bin/uglifyjs + checksum: 128233638176abe6cc0ec0f1dbae7bcb3f02edd78eb5c7752b4f379ec9d29032cd2edf06b2522dbeba0a1f05afb25f6eaffe638581da6d8554bd4c060d6622b1 + languageName: node + linkType: hard + "unbox-primitive@npm:^1.0.2": version: 1.0.2 resolution: "unbox-primitive@npm:1.0.2" @@ -20268,6 +20895,13 @@ __metadata: languageName: node linkType: hard +"underscore@npm:~1.13.2": + version: 1.13.6 + resolution: "underscore@npm:1.13.6" + checksum: d5cedd14a9d0d91dd38c1ce6169e4455bb931f0aaf354108e47bd46d3f2da7464d49b2171a5cf786d61963204a42d01ea1332a903b7342ad428deaafaf70ec36 + languageName: node + linkType: hard + "unherit@npm:^1.0.4": version: 1.1.3 resolution: "unherit@npm:1.1.3" @@ -21690,6 +22324,13 @@ __metadata: languageName: node linkType: hard +"xmlcreate@npm:^2.0.4": + version: 2.0.4 + resolution: "xmlcreate@npm:2.0.4" + checksum: b8dd52668b9aea77cd1408fa85538c14bb8dcc98b4e7bb51e76696c9c115d59eba7240298d0c4fd2caf8f1a8e283ab4e5c7b9a6bcfcf23a8b48f5068b677b748 + languageName: node + linkType: hard + "xtend@npm:^4.0.0, xtend@npm:^4.0.1, xtend@npm:~4.0.1": version: 4.0.2 resolution: "xtend@npm:4.0.2" From 3e4abfb3da599f1d5219aab2de9dc16f0f7c6aa1 Mon Sep 17 00:00:00 2001 From: Peter Staples Date: Wed, 5 Oct 2022 20:37:01 +0100 Subject: [PATCH 12/13] Bug 13140 - correction to yarn.lock --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index f51bc5c4d57a..bd24ad08e2e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9505,7 +9505,7 @@ __metadata: languageName: node linkType: hard -"espree@npm:^9.4.0": +"espree@npm:^9.0.0, espree@npm:^9.4.0": version: 9.4.0 resolution: "espree@npm:9.4.0" dependencies: @@ -13520,6 +13520,13 @@ __metadata: languageName: node linkType: hard +"jsdoc-type-pratt-parser@npm:~3.1.0": + version: 3.1.0 + resolution: "jsdoc-type-pratt-parser@npm:3.1.0" + checksum: 2f437b57621f1e481918165f6cf0e48256628a9e510d8b3f88a2ab667bf2128bf8b94c628b57c43e78f555ca61983e9c282814703840dc091d2623992214a061 + languageName: node + linkType: hard + "jsdoc@npm:^3.6.3": version: 3.6.11 resolution: "jsdoc@npm:3.6.11" @@ -13545,13 +13552,6 @@ __metadata: languageName: node linkType: hard -"jsdoc-type-pratt-parser@npm:~3.1.0": - version: 3.1.0 - resolution: "jsdoc-type-pratt-parser@npm:3.1.0" - checksum: 2f437b57621f1e481918165f6cf0e48256628a9e510d8b3f88a2ab667bf2128bf8b94c628b57c43e78f555ca61983e9c282814703840dc091d2623992214a061 - languageName: node - linkType: hard - "jsdom@npm:^20.0.0": version: 20.0.0 resolution: "jsdom@npm:20.0.0" From eb4350ae9d4a5bf6fefdac5f869c869814ed3835 Mon Sep 17 00:00:00 2001 From: Peter Staples Date: Wed, 5 Oct 2022 21:15:55 +0100 Subject: [PATCH 13/13] Bug 13140 - updated some tests for correct error messages from ModuleMocker.spyOn() refactoring --- packages/jest-mock/src/__tests__/index.test.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/jest-mock/src/__tests__/index.test.ts b/packages/jest-mock/src/__tests__/index.test.ts index a085b9182b99..8f1436f4b042 100644 --- a/packages/jest-mock/src/__tests__/index.test.ts +++ b/packages/jest-mock/src/__tests__/index.test.ts @@ -1261,12 +1261,10 @@ describe('moduleMocker', () => { it('should throw on invalid input', () => { expect(() => { moduleMocker.spyOn(null, 'method'); - }).toThrow('Cannot read prop'); + }).toThrow('spyOn could not find an object to spy upon for method'); expect(() => { moduleMocker.spyOn({}, 'method'); - }).toThrow( - 'Cannot spy the method property because it is not a function; undefined given instead', - ); + }).toThrow('method property does not exist'); expect(() => { moduleMocker.spyOn({method: 10}, 'method'); }).toThrow( @@ -1431,12 +1429,10 @@ describe('moduleMocker', () => { it('should throw on invalid input', () => { expect(() => { moduleMocker.spyOn(null, 'method'); - }).toThrow('Cannot read prop'); + }).toThrow('spyOn could not find an object to spy upon for method'); expect(() => { moduleMocker.spyOn({}, 'method'); - }).toThrow( - 'Cannot spy the method property because it is not a function; undefined given instead', - ); + }).toThrow('method property does not exist'); expect(() => { moduleMocker.spyOn({method: 10}, 'method'); }).toThrow(