Socket
Socket
Sign inDemoInstall

jest-mock

Package Overview
Dependencies
Maintainers
6
Versions
238
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jest-mock - npm Package Compare versions

Comparing version 29.0.3 to 29.1.0

115

build/index.d.ts

@@ -12,3 +12,3 @@ /**

export declare type ConstructorLikeKeys<T> = keyof {
[K in keyof T as T[K] extends ClassLike ? K : never]: T[K];
[K in keyof T as Required<T>[K] extends ClassLike ? K : never]: T[K];
};

@@ -23,3 +23,3 @@

export declare type MethodLikeKeys<T> = keyof {
[K in keyof T as T[K] extends FunctionLike ? K : never]: T[K];
[K in keyof T as Required<T>[K] extends FunctionLike ? K : never]: T[K];
};

@@ -184,2 +184,4 @@

mockImplementationOnce(fn: T): this;
withImplementation(fn: T, callback: () => Promise<unknown>): Promise<void>;
withImplementation(fn: T, callback: () => void): void;
mockName(name: string): this;

@@ -258,25 +260,32 @@ mockReturnThis(): this;

fn<T extends FunctionLike = UnknownFunction>(implementation?: T): Mock<T>;
spyOn<T extends object, M extends PropertyLikeKeys<T>>(
spyOn<
T extends object,
K extends PropertyLikeKeys<T>,
V extends Required<T>[K],
>(object: T, methodKey: K, accessType: 'get'): SpyInstance<() => V>;
spyOn<
T extends object,
K extends PropertyLikeKeys<T>,
V extends Required<T>[K],
>(object: T, methodKey: K, accessType: 'set'): SpyInstance<(arg: V) => void>;
spyOn<
T extends object,
K extends ConstructorLikeKeys<T>,
V extends Required<T>[K],
>(
object: T,
methodName: M,
accessType: 'get',
): SpyInstance<() => T[M]>;
spyOn<T extends object, M extends PropertyLikeKeys<T>>(
object: T,
methodName: M,
accessType: 'set',
): SpyInstance<(arg: T[M]) => void>;
spyOn<T extends object, M extends ConstructorLikeKeys<T>>(
object: T,
methodName: M,
): T[M] extends ClassLike
? SpyInstance<(...args: ConstructorParameters<T[M]>) => InstanceType<T[M]>>
methodKey: K,
): V extends ClassLike
? SpyInstance<(...args: ConstructorParameters<V>) => InstanceType<V>>
: never;
spyOn<T extends object, M extends MethodLikeKeys<T>>(
spyOn<
T extends object,
K extends MethodLikeKeys<T>,
V extends Required<T>[K],
>(
object: T,
methodName: M,
): T[M] extends FunctionLike
? SpyInstance<(...args: Parameters<T[M]>) => ReturnType<T[M]>>
methodKey: K,
): V extends FunctionLike
? SpyInstance<(...args: Parameters<V>) => ReturnType<V>>
: never;
private _spyOnProperty;
clearAllMocks(): void;

@@ -317,59 +326,67 @@ resetAllMocks(): void;

T extends object,
M extends Exclude<
K_2 extends Exclude<
keyof T,
| keyof {[K in keyof T as T[K] extends ClassLike ? K : never]: T[K]}
| keyof {
[K_1 in keyof T as T[K_1] extends FunctionLike ? K_1 : never]: T[K_1];
[K in keyof T as Required<T>[K] extends ClassLike ? K : never]: T[K];
}
| keyof {
[K_1 in keyof T as Required<T>[K_1] extends FunctionLike
? K_1
: never]: T[K_1];
}
>,
V extends Required<T>[K_2],
>(
object: T,
methodName: M,
methodKey: K_2,
accessType: 'get',
): SpyInstance<() => T[M]>;
): SpyInstance<() => V>;
<
T_1 extends object,
M_1 extends Exclude<
K_5 extends Exclude<
keyof T_1,
| keyof {
[K_2 in keyof T_1 as T_1[K_2] extends ClassLike
? K_2
: never]: T_1[K_2];
}
| keyof {
[K_3 in keyof T_1 as T_1[K_3] extends FunctionLike
[K_3 in keyof T_1 as Required<T_1>[K_3] extends ClassLike
? K_3
: never]: T_1[K_3];
}
| keyof {
[K_4 in keyof T_1 as Required<T_1>[K_4] extends FunctionLike
? K_4
: never]: T_1[K_4];
}
>,
V_1 extends Required<T_1>[K_5],
>(
object: T_1,
methodName: M_1,
methodKey: K_5,
accessType: 'set',
): SpyInstance<(arg: T_1[M_1]) => void>;
): SpyInstance<(arg: V_1) => void>;
<
T_2 extends object,
M_2 extends keyof {
[K_4 in keyof T_2 as T_2[K_4] extends ClassLike ? K_4 : never]: T_2[K_4];
K_7 extends keyof {
[K_6 in keyof T_2 as Required<T_2>[K_6] extends ClassLike
? K_6
: never]: T_2[K_6];
},
V_2 extends Required<T_2>[K_7],
>(
object: T_2,
methodName: M_2,
): T_2[M_2] extends ClassLike
? SpyInstance<
(...args: ConstructorParameters<T_2[M_2]>) => InstanceType<T_2[M_2]>
>
methodKey: K_7,
): V_2 extends ClassLike
? SpyInstance<(...args: ConstructorParameters<V_2>) => InstanceType<V_2>>
: never;
<
T_3 extends object,
M_3 extends keyof {
[K_5 in keyof T_3 as T_3[K_5] extends FunctionLike
? K_5
: never]: T_3[K_5];
K_9 extends keyof {
[K_8 in keyof T_3 as Required<T_3>[K_8] extends FunctionLike
? K_8
: never]: T_3[K_8];
},
V_3 extends Required<T_3>[K_9],
>(
object: T_3,
methodName: M_3,
): T_3[M_3] extends FunctionLike
? SpyInstance<(...args: Parameters<T_3[M_3]>) => ReturnType<T_3[M_3]>>
methodKey: K_9,
): V_3 extends FunctionLike
? SpyInstance<(...args: Parameters<V_3>) => ReturnType<V_3>>
: never;

@@ -376,0 +393,0 @@ };

@@ -8,2 +8,12 @@ 'use strict';

function _jestUtil() {
const data = require('jest-util');
_jestUtil = function () {
return data;
};
return data;
}
/**

@@ -17,14 +27,2 @@ * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.

/* eslint-disable local/ban-types-eventually, local/prefer-rest-params-eventually */
// TODO remove re-export in Jest 30
// TODO remove re-export in Jest 30
/**
* All what the internal typings need is to be sure that we have any-function.
* `FunctionLike` type ensures that and helps to constrain the type as well.
* The default of `UnknownFunction` makes sure that `any`s do not leak to the
* user side. For instance, calling `fn()` without implementation will return
* a mock of `(...args: Array<unknown>) => unknown` type. If implementation
* is provided, its typings are inferred correctly.
*/
// eslint-disable-next-line @typescript-eslint/no-empty-interface
const MOCK_CONSTRUCTOR_NAME = 'mockConstructor';

@@ -289,3 +287,6 @@ const FUNCTION_NAME_RESERVED_PATTERN = /[\s!-/:-@[-`{-~]/;

if ((propDesc !== undefined && !propDesc.get) || object.__esModule) {
if (
propDesc !== undefined &&
!(propDesc.get && prop == '__proto__')
) {
slots.add(prop);

@@ -532,2 +533,21 @@ }

f.withImplementation = withImplementation.bind(this);
function withImplementation(fn, callback) {
// Remember previous mock implementation, then set new one
const mockConfig = this._ensureMockConfig(f);
const previousImplementation = mockConfig.mockImpl;
mockConfig.mockImpl = fn;
const returnedValue = callback();
if ((0, _jestUtil().isPromise)(returnedValue)) {
return returnedValue.then(() => {
mockConfig.mockImpl = previousImplementation;
});
} else {
mockConfig.mockImpl = previousImplementation;
}
}
f.mockImplementation = fn => {

@@ -630,2 +650,3 @@ // next function call will use mock implementation return value

this._getSlots(metadata.members).forEach(slot => {
let slotMock;
const slotMetadata = (metadata.members && metadata.members[slot]) || {};

@@ -640,3 +661,32 @@

} else {
mock[slot] = this._generateMock(slotMetadata, callbacks, refs);
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.
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) &&
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);
} else {
mock[slot] = slotMock;
}
}

@@ -731,6 +781,32 @@ });

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 = 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.
// @ts-expect-error ignore type mismatch
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);
}
if (slotMetadata) {

@@ -773,102 +849,28 @@ if (!members) {

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
spyOn(object, methodName, accessType) {
if (accessType) {
return this._spyOnProperty(object, methodName, accessType);
}
if (typeof object !== 'object' && typeof object !== 'function') {
spyOn(object, methodKey, accessType) {
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(methodKey)}`
);
}
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;
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 () {
return original.apply(this, arguments);
});
if (!methodKey) {
throw new Error('No property name supplied');
}
return object[methodName];
}
_spyOnProperty(obj, propertyName, accessType = 'get') {
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(object, methodKey);
let proto = Object.getPrototypeOf(object);
let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
let proto = Object.getPrototypeOf(obj);
while (!descriptor && proto !== null) {
descriptor = Object.getOwnPropertyDescriptor(proto, propertyName);
descriptor = Object.getOwnPropertyDescriptor(proto, methodKey);
proto = Object.getPrototypeOf(proto);

@@ -878,31 +880,39 @@ }

if (!descriptor) {
throw new Error(`${String(propertyName)} property does not exist`);
throw new Error(`${String(methodKey)} property does not exist`);
}
if (!descriptor.configurable) {
throw new Error(`${String(propertyName)} is not declared configurable`);
throw new Error(`${String(methodKey)} is not declared configurable`);
}
if (!descriptor[accessType]) {
if (this.isMockFunction(descriptor.value)) {
return object[methodKey];
} else if (accessType == 'get' && this.isMockFunction(descriptor.get)) {
return descriptor.get;
} else if (accessType == 'set' && this.isMockFunction(descriptor.set)) {
return descriptor.set;
}
if (accessType) {
if (typeof descriptor[accessType] !== 'function') {
throw new Error(`Cannot spy the ${String(accessType)} ${String(
methodKey
)} property because it is not a function;
${this._typeOf(descriptor?.[accessType])} given instead`);
}
} else if (typeof descriptor.value !== 'function') {
throw new Error(
`Property ${String(
propertyName
)} does not have access type ${accessType}`
`Cannot spy the ${String(
methodKey
)} property because it is not a function; ${this._typeOf(
descriptor.value
)} given instead`
);
}
const original = descriptor[accessType];
let mock;
if (!this.isMockFunction(original)) {
if (typeof original !== 'function') {
throw new Error(
`Cannot spy the ${String(
propertyName
)} property because it is not a function; ${this._typeOf(
original
)} given instead`
);
}
descriptor[accessType] = this._makeComponent(
if (accessType == 'get' && descriptor['get']) {
const originalAccessor = descriptor['get'];
mock = this._makeComponent(
{

@@ -912,15 +922,53 @@ type: 'function'

() => {
// @ts-expect-error: mock is assignable
descriptor[accessType] = original;
Object.defineProperty(obj, propertyName, descriptor);
descriptor[accessType] = originalAccessor;
Object.defineProperty(object, methodKey, descriptor);
}
);
descriptor[accessType].mockImplementation(function () {
// @ts-expect-error - wrong context
return original.apply(this, arguments);
descriptor[accessType] = mock;
mock.mockImplementation(function () {
return originalAccessor.call(this);
});
Object.defineProperty(object, methodKey, descriptor);
} else if (accessType == 'set' && descriptor['set']) {
const originalAccessor = descriptor['set'];
mock = this._makeComponent(
{
type: 'function'
},
() => {
descriptor[accessType] = originalAccessor;
Object.defineProperty(object, methodKey, descriptor);
}
);
descriptor[accessType] = mock;
mock.mockImplementation(function () {
return originalAccessor.call(this, arguments[0]);
});
Object.defineProperty(object, methodKey, descriptor);
} else {
const isMethodOwner = Object.prototype.hasOwnProperty.call(
object,
methodKey
);
const original = descriptor;
mock = this._makeComponent(
{
type: 'function'
},
() => {
if (isMethodOwner) {
object[methodKey] = original.value;
} else {
delete object[methodKey];
}
}
); // @ts-expect-error overriding original method with a Mock
object[methodKey] = mock;
mock.mockImplementation(function () {
return original.value.apply(this, arguments);
});
}
Object.defineProperty(obj, propertyName, descriptor);
return descriptor[accessType];
return mock;
}

@@ -927,0 +975,0 @@

{
"name": "jest-mock",
"version": "29.0.3",
"version": "29.1.0",
"repository": {

@@ -20,4 +20,5 @@ "type": "git",

"dependencies": {
"@jest/types": "^29.0.3",
"@types/node": "*"
"@jest/types": "^29.1.0",
"@types/node": "*",
"jest-util": "^29.1.0"
},

@@ -34,3 +35,3 @@ "devDependencies": {

},
"gitHead": "77f865da39af5b3e1c114dc347e49257eb3dcfd1"
"gitHead": "51f10300daf90db003a1749ceaed1084c4f74811"
}

@@ -101,1 +101,7 @@ # jest-mock

- if the last call is `.mockImplementationOnce()` or `.mockImplementation()`, run the specific implementation and return the result or run default implementation and return the result.
##### `.withImplementation(function, callback)`
Temporarily overrides the default mock implementation within the callback, then restores it's previous implementation.
If the callback is async or returns a `thenable`, `withImplementation` will return a promise. Awaiting the promise will await the callback and reset the implementation.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc