@corez/mock
Advanced tools
Comparing version 0.6.0 to 0.7.0
@@ -17,2 +17,7 @@ /** | ||
/** | ||
* Mock identification symbol | ||
*/ | ||
declare const IS_MOCKED: unique symbol; | ||
/** | ||
* Mock behavior interface | ||
@@ -194,3 +199,3 @@ */ | ||
*/ | ||
interface MockFunction<T extends Fn = Fn> extends Function { | ||
interface MockFunction<T extends Fn = Fn> { | ||
(...args: Parameters<T>): ReturnType<T>; | ||
@@ -236,17 +241,11 @@ _isMockFunction: boolean; | ||
/** | ||
* Makes all methods in T into MockFunction types | ||
* Mock class type that extends the original class type | ||
* Includes all mock-related properties and methods | ||
*/ | ||
type MockOf<T> = { | ||
[P in keyof T]: T[P] extends Fn ? MockFunction<T[P]> : T[P] extends object ? MockOf<T[P]> : T[P]; | ||
type ClsMock<T extends Constructor<any>> = T & { | ||
__is_mocked__: boolean; | ||
[IS_MOCKED]: true; | ||
new (...args: ConstructorParameters<T>): InstanceType<T>; | ||
}; | ||
/** | ||
* Represents a mocked class constructor | ||
*/ | ||
type ClsMock<T extends new (...args: any[]) => any> = { | ||
new (...args: ConstructorParameters<T>): MockOf<InstanceType<T>>; | ||
prototype: MockOf<InstanceType<T>>; | ||
} & { | ||
[K in keyof T]: T[K] extends (...args: any[]) => any ? MockFunction<T[K]> : T[K]; | ||
}; | ||
/** | ||
* Mock object interface that includes utility methods | ||
@@ -253,0 +252,0 @@ */ |
@@ -210,2 +210,3 @@ 'use strict'; | ||
// src/constants/mock-symbols.ts | ||
var IS_MOCKED = Symbol("__is_mocked__"); | ||
var MOCK_SYMBOLS = { | ||
@@ -222,3 +223,5 @@ // State tracking | ||
// Debug info | ||
DEBUG_CONTEXT: Symbol("__mock_debug_context__") | ||
DEBUG_CONTEXT: Symbol("__mock_debug_context__"), | ||
// Mock identification | ||
IS_MOCKED | ||
}; | ||
@@ -738,35 +741,4 @@ | ||
// src/utils/method-spy.ts | ||
function createMethodSpy(target, methodName, options = {}, originalMethod) { | ||
const tracker = new MethodTracker(target, options); | ||
const method = originalMethod || target[methodName]; | ||
const spy = createSpy(); | ||
if (!options.preservePrototype) { | ||
return spy; | ||
} | ||
spy.mockImplementation(function(...args) { | ||
tracker.trackMethodCall(methodName, args); | ||
try { | ||
const result = method.apply(this, args); | ||
if (result instanceof Promise) { | ||
return result.then((asyncResult) => { | ||
tracker.trackMethodReturn(methodName, asyncResult); | ||
return asyncResult; | ||
}).catch((error) => { | ||
tracker.trackError(methodName, error); | ||
throw error; | ||
}); | ||
} | ||
tracker.trackMethodReturn(methodName, result); | ||
return result; | ||
} catch (error) { | ||
tracker.trackError(methodName, error); | ||
throw error; | ||
} | ||
}); | ||
return spy; | ||
} | ||
// src/mocks/class.ts | ||
function handleStaticMethodInheritance(mockClass, originalClass, options = {}) { | ||
function handleStaticMethodInheritance(mockClass, originalClass, _options = {}) { | ||
let currentProto = Object.getPrototypeOf(originalClass); | ||
@@ -777,3 +749,3 @@ while (currentProto && currentProto !== Function.prototype) { | ||
const method = currentProto[methodName].bind(mockClass); | ||
mockClass[methodName] = createMethodSpy(mockClass, methodName, options, method); | ||
mockClass[methodName] = createSpy(method); | ||
} | ||
@@ -784,13 +756,2 @@ }); | ||
} | ||
function createPropertyDescriptor(target, name, descriptor, config) { | ||
const getterSpy = descriptor.get ? createMethodSpy(target, name, config, descriptor.get.bind(target)) : void 0; | ||
const setterSpy = descriptor.set ? createMethodSpy(target, name, config, descriptor.set.bind(target)) : void 0; | ||
return { | ||
...descriptor, | ||
get: getterSpy, | ||
set: setterSpy, | ||
configurable: true, | ||
enumerable: descriptor.enumerable | ||
}; | ||
} | ||
function initializeMockInstance(instance, config) { | ||
@@ -806,2 +767,8 @@ instance[MOCK_SYMBOLS.STATES] = /* @__PURE__ */ new Map(); | ||
function cls(target, options = {}) { | ||
if (target[IS_MOCKED]) { | ||
if (options.debug) { | ||
console.debug("Class is already mocked:", target.name); | ||
} | ||
return target; | ||
} | ||
const config = { | ||
@@ -814,78 +781,38 @@ ...DEFAULT_CLASS_OPTIONS, | ||
} | ||
const handleDescriptor = (name, descriptor, context) => { | ||
if (!descriptor) { | ||
return { | ||
configurable: true, | ||
enumerable: true, | ||
writable: true, | ||
value: void 0 | ||
}; | ||
} | ||
const { value, get, set } = descriptor; | ||
if (typeof value === "function") { | ||
const override = typeof name === "string" && config.overrides?.[name]; | ||
if (override) { | ||
return { | ||
...descriptor, | ||
value: createMethodSpy(context, name, config, override) | ||
}; | ||
} | ||
return { | ||
...descriptor, | ||
value: config.preservePrototype ? createMethodSpy(context, name, config, value) : createSpy() | ||
}; | ||
} | ||
if (get || set) { | ||
const getterOverride = typeof name === "string" && config.overrides?.[`get${name.charAt(0).toUpperCase()}${name.slice(1)}`]; | ||
const setterOverride = typeof name === "string" && config.overrides?.[`set${name.charAt(0).toUpperCase()}${name.slice(1)}`]; | ||
const getterSpy = get && (getterOverride ? createMethodSpy(context, name, config, getterOverride) : config.preservePrototype ? createMethodSpy(context, name, config, get) : createSpy()); | ||
const setterSpy = set && (setterOverride ? createMethodSpy(context, name, config, setterOverride) : config.preservePrototype ? createMethodSpy(context, name, config, set) : createSpy()); | ||
return { | ||
...descriptor, | ||
get: getterSpy, | ||
set: setterSpy | ||
}; | ||
} | ||
return descriptor; | ||
}; | ||
const processMembers = (target2, source) => { | ||
Object.getOwnPropertyNames(source).forEach((name) => { | ||
if (name === "constructor") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(source, name); | ||
if (!descriptor) return; | ||
if (descriptor.value && typeof descriptor.value === "function") { | ||
const override = config.overrides?.[name]; | ||
const method = override || descriptor.value; | ||
target2[name] = createMethodSpy(target2, name, config, method.bind(target2)); | ||
} else if (descriptor.get || descriptor.set) { | ||
Object.defineProperty(target2, name, createPropertyDescriptor(target2, name, descriptor, config)); | ||
} else { | ||
const value = source[name]; | ||
if (typeof value === "function") { | ||
target2[name] = createMethodSpy(target2, name, config, value.bind(target2)); | ||
} else { | ||
target2[name] = value; | ||
if (config.mockInPlace) { | ||
target[IS_MOCKED] = true; | ||
target.__is_mocked__ = true; | ||
Object.getOwnPropertyNames(target.prototype).forEach((prop) => { | ||
if (prop === "constructor") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target.prototype, prop); | ||
if (descriptor) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(target.prototype, prop, { | ||
...descriptor, | ||
value: createSpy(override) | ||
}); | ||
} else if (typeof descriptor.value === "function") { | ||
Object.defineProperty(target.prototype, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value) : createSpy() | ||
}); | ||
} | ||
} | ||
}); | ||
}; | ||
if (config.mockInPlace) { | ||
const proto = target.prototype; | ||
Object.getOwnPropertyNames(proto).forEach((name) => { | ||
if (name === "constructor") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(proto, name); | ||
if (typeof proto[name] === "function") { | ||
proto[name] = createMethodSpy(proto, name, config, proto[name]); | ||
} else if (descriptor) { | ||
Object.defineProperty(proto, name, createPropertyDescriptor(proto, name, descriptor, config)); | ||
} | ||
}); | ||
Object.getOwnPropertyNames(target).forEach((name) => { | ||
if (name === "length" || name === "prototype" || name === "name") return; | ||
if (typeof target[name] === "function") { | ||
target[name] = createMethodSpy(target, name, config, target[name]); | ||
} else { | ||
const descriptor = Object.getOwnPropertyDescriptor(target, name); | ||
if (descriptor) { | ||
Object.defineProperty(target, name, createPropertyDescriptor(target, name, descriptor, config)); | ||
Object.getOwnPropertyNames(target).forEach((prop) => { | ||
if (prop === "length" || prop === "prototype" || prop === "name") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target, prop); | ||
if (descriptor) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(target, prop, { | ||
...descriptor, | ||
value: createSpy(override) | ||
}); | ||
} else if (typeof descriptor.value === "function") { | ||
Object.defineProperty(target, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value) : createSpy() | ||
}); | ||
} | ||
@@ -904,9 +831,12 @@ } | ||
initializeMockInstance(instance, config); | ||
try { | ||
const temp = new target(...args); | ||
Object.getOwnPropertyNames(temp).forEach((prop) => { | ||
const descriptor = Object.getOwnPropertyDescriptor(temp, prop); | ||
if (config.preserveConstructor) { | ||
const constructedInstance = Reflect.construct(target, args); | ||
Object.getOwnPropertyNames(constructedInstance).forEach((prop) => { | ||
const descriptor = Object.getOwnPropertyDescriptor(constructedInstance, prop); | ||
if (descriptor) { | ||
if (typeof descriptor.value === "function") { | ||
instance[prop] = createMethodSpy(instance, prop, config, descriptor.value.bind(instance)); | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: createSpy(descriptor.value.bind(instance)) | ||
}); | ||
} else { | ||
@@ -917,8 +847,41 @@ Object.defineProperty(instance, prop, descriptor); | ||
}); | ||
} catch { | ||
} | ||
processMembers(instance, target.prototype); | ||
Object.getOwnPropertyNames(target.prototype).forEach((prop) => { | ||
if (prop === "constructor") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target.prototype, prop); | ||
if (descriptor) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: createSpy(override) | ||
}); | ||
} else if (typeof descriptor.value === "function") { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value.bind(instance)) : createSpy() | ||
}); | ||
} | ||
} | ||
}); | ||
let proto = Object.getPrototypeOf(target.prototype); | ||
while (proto && proto !== Object.prototype) { | ||
processMembers(instance, proto); | ||
Object.getOwnPropertyNames(proto).forEach((prop) => { | ||
if (prop === "constructor") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(proto, prop); | ||
if (descriptor && !instance.hasOwnProperty(prop)) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: createSpy(override) | ||
}); | ||
} else if (typeof descriptor.value === "function") { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value.bind(instance)) : createSpy() | ||
}); | ||
} | ||
} | ||
}); | ||
proto = Object.getPrototypeOf(proto); | ||
@@ -929,11 +892,24 @@ } | ||
MockClass.prototype = Object.create(target.prototype); | ||
MockClass.prototype.constructor = MockClass; | ||
Object.getOwnPropertyNames(target).forEach((name) => { | ||
if (name === "length" || name === "prototype" || name === "name") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target, name); | ||
Object.setPrototypeOf(MockClass, target); | ||
Object.getOwnPropertyNames(target).forEach((prop) => { | ||
if (prop === "length" || prop === "prototype" || prop === "name") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target, prop); | ||
if (descriptor) { | ||
Object.defineProperty(MockClass, name, handleDescriptor(name, descriptor, target)); | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(MockClass, prop, { | ||
...descriptor, | ||
value: createSpy(override) | ||
}); | ||
} else if (typeof descriptor.value === "function") { | ||
Object.defineProperty(MockClass, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value) : createSpy() | ||
}); | ||
} | ||
} | ||
}); | ||
handleStaticMethodInheritance(MockClass, target, { debug: config.debug }); | ||
MockClass[IS_MOCKED] = true; | ||
MockClass.__is_mocked__ = true; | ||
return MockClass; | ||
@@ -987,3 +963,3 @@ } | ||
} | ||
function createMethodSpy2(method, mockTarget, isArrowFn) { | ||
function createMethodSpy(method, mockTarget, isArrowFn) { | ||
const spy = createSpy(); | ||
@@ -1013,3 +989,3 @@ const boundMethod = function(...args) { | ||
const isArrowFn = !method.prototype; | ||
const spy = createMethodSpy2(method, mockTarget, isArrowFn); | ||
const spy = createMethodSpy(method, mockTarget, isArrowFn); | ||
Object.defineProperty(mockTarget, key, { | ||
@@ -1028,3 +1004,3 @@ ...descriptor, | ||
const isArrowFn = !method.prototype; | ||
const spy = createMethodSpy2(method, mockTarget, isArrowFn); | ||
const spy = createMethodSpy(method, mockTarget, isArrowFn); | ||
Object.defineProperty(mockTarget, key, { | ||
@@ -1031,0 +1007,0 @@ ...descriptor, |
@@ -204,2 +204,3 @@ import rfdc from 'rfdc'; | ||
// src/constants/mock-symbols.ts | ||
var IS_MOCKED = Symbol("__is_mocked__"); | ||
var MOCK_SYMBOLS = { | ||
@@ -216,3 +217,5 @@ // State tracking | ||
// Debug info | ||
DEBUG_CONTEXT: Symbol("__mock_debug_context__") | ||
DEBUG_CONTEXT: Symbol("__mock_debug_context__"), | ||
// Mock identification | ||
IS_MOCKED | ||
}; | ||
@@ -732,35 +735,4 @@ | ||
// src/utils/method-spy.ts | ||
function createMethodSpy(target, methodName, options = {}, originalMethod) { | ||
const tracker = new MethodTracker(target, options); | ||
const method = originalMethod || target[methodName]; | ||
const spy = createSpy(); | ||
if (!options.preservePrototype) { | ||
return spy; | ||
} | ||
spy.mockImplementation(function(...args) { | ||
tracker.trackMethodCall(methodName, args); | ||
try { | ||
const result = method.apply(this, args); | ||
if (result instanceof Promise) { | ||
return result.then((asyncResult) => { | ||
tracker.trackMethodReturn(methodName, asyncResult); | ||
return asyncResult; | ||
}).catch((error) => { | ||
tracker.trackError(methodName, error); | ||
throw error; | ||
}); | ||
} | ||
tracker.trackMethodReturn(methodName, result); | ||
return result; | ||
} catch (error) { | ||
tracker.trackError(methodName, error); | ||
throw error; | ||
} | ||
}); | ||
return spy; | ||
} | ||
// src/mocks/class.ts | ||
function handleStaticMethodInheritance(mockClass, originalClass, options = {}) { | ||
function handleStaticMethodInheritance(mockClass, originalClass, _options = {}) { | ||
let currentProto = Object.getPrototypeOf(originalClass); | ||
@@ -771,3 +743,3 @@ while (currentProto && currentProto !== Function.prototype) { | ||
const method = currentProto[methodName].bind(mockClass); | ||
mockClass[methodName] = createMethodSpy(mockClass, methodName, options, method); | ||
mockClass[methodName] = createSpy(method); | ||
} | ||
@@ -778,13 +750,2 @@ }); | ||
} | ||
function createPropertyDescriptor(target, name, descriptor, config) { | ||
const getterSpy = descriptor.get ? createMethodSpy(target, name, config, descriptor.get.bind(target)) : void 0; | ||
const setterSpy = descriptor.set ? createMethodSpy(target, name, config, descriptor.set.bind(target)) : void 0; | ||
return { | ||
...descriptor, | ||
get: getterSpy, | ||
set: setterSpy, | ||
configurable: true, | ||
enumerable: descriptor.enumerable | ||
}; | ||
} | ||
function initializeMockInstance(instance, config) { | ||
@@ -800,2 +761,8 @@ instance[MOCK_SYMBOLS.STATES] = /* @__PURE__ */ new Map(); | ||
function cls(target, options = {}) { | ||
if (target[IS_MOCKED]) { | ||
if (options.debug) { | ||
console.debug("Class is already mocked:", target.name); | ||
} | ||
return target; | ||
} | ||
const config = { | ||
@@ -808,78 +775,38 @@ ...DEFAULT_CLASS_OPTIONS, | ||
} | ||
const handleDescriptor = (name, descriptor, context) => { | ||
if (!descriptor) { | ||
return { | ||
configurable: true, | ||
enumerable: true, | ||
writable: true, | ||
value: void 0 | ||
}; | ||
} | ||
const { value, get, set } = descriptor; | ||
if (typeof value === "function") { | ||
const override = typeof name === "string" && config.overrides?.[name]; | ||
if (override) { | ||
return { | ||
...descriptor, | ||
value: createMethodSpy(context, name, config, override) | ||
}; | ||
} | ||
return { | ||
...descriptor, | ||
value: config.preservePrototype ? createMethodSpy(context, name, config, value) : createSpy() | ||
}; | ||
} | ||
if (get || set) { | ||
const getterOverride = typeof name === "string" && config.overrides?.[`get${name.charAt(0).toUpperCase()}${name.slice(1)}`]; | ||
const setterOverride = typeof name === "string" && config.overrides?.[`set${name.charAt(0).toUpperCase()}${name.slice(1)}`]; | ||
const getterSpy = get && (getterOverride ? createMethodSpy(context, name, config, getterOverride) : config.preservePrototype ? createMethodSpy(context, name, config, get) : createSpy()); | ||
const setterSpy = set && (setterOverride ? createMethodSpy(context, name, config, setterOverride) : config.preservePrototype ? createMethodSpy(context, name, config, set) : createSpy()); | ||
return { | ||
...descriptor, | ||
get: getterSpy, | ||
set: setterSpy | ||
}; | ||
} | ||
return descriptor; | ||
}; | ||
const processMembers = (target2, source) => { | ||
Object.getOwnPropertyNames(source).forEach((name) => { | ||
if (name === "constructor") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(source, name); | ||
if (!descriptor) return; | ||
if (descriptor.value && typeof descriptor.value === "function") { | ||
const override = config.overrides?.[name]; | ||
const method = override || descriptor.value; | ||
target2[name] = createMethodSpy(target2, name, config, method.bind(target2)); | ||
} else if (descriptor.get || descriptor.set) { | ||
Object.defineProperty(target2, name, createPropertyDescriptor(target2, name, descriptor, config)); | ||
} else { | ||
const value = source[name]; | ||
if (typeof value === "function") { | ||
target2[name] = createMethodSpy(target2, name, config, value.bind(target2)); | ||
} else { | ||
target2[name] = value; | ||
if (config.mockInPlace) { | ||
target[IS_MOCKED] = true; | ||
target.__is_mocked__ = true; | ||
Object.getOwnPropertyNames(target.prototype).forEach((prop) => { | ||
if (prop === "constructor") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target.prototype, prop); | ||
if (descriptor) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(target.prototype, prop, { | ||
...descriptor, | ||
value: createSpy(override) | ||
}); | ||
} else if (typeof descriptor.value === "function") { | ||
Object.defineProperty(target.prototype, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value) : createSpy() | ||
}); | ||
} | ||
} | ||
}); | ||
}; | ||
if (config.mockInPlace) { | ||
const proto = target.prototype; | ||
Object.getOwnPropertyNames(proto).forEach((name) => { | ||
if (name === "constructor") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(proto, name); | ||
if (typeof proto[name] === "function") { | ||
proto[name] = createMethodSpy(proto, name, config, proto[name]); | ||
} else if (descriptor) { | ||
Object.defineProperty(proto, name, createPropertyDescriptor(proto, name, descriptor, config)); | ||
} | ||
}); | ||
Object.getOwnPropertyNames(target).forEach((name) => { | ||
if (name === "length" || name === "prototype" || name === "name") return; | ||
if (typeof target[name] === "function") { | ||
target[name] = createMethodSpy(target, name, config, target[name]); | ||
} else { | ||
const descriptor = Object.getOwnPropertyDescriptor(target, name); | ||
if (descriptor) { | ||
Object.defineProperty(target, name, createPropertyDescriptor(target, name, descriptor, config)); | ||
Object.getOwnPropertyNames(target).forEach((prop) => { | ||
if (prop === "length" || prop === "prototype" || prop === "name") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target, prop); | ||
if (descriptor) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(target, prop, { | ||
...descriptor, | ||
value: createSpy(override) | ||
}); | ||
} else if (typeof descriptor.value === "function") { | ||
Object.defineProperty(target, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value) : createSpy() | ||
}); | ||
} | ||
@@ -898,9 +825,12 @@ } | ||
initializeMockInstance(instance, config); | ||
try { | ||
const temp = new target(...args); | ||
Object.getOwnPropertyNames(temp).forEach((prop) => { | ||
const descriptor = Object.getOwnPropertyDescriptor(temp, prop); | ||
if (config.preserveConstructor) { | ||
const constructedInstance = Reflect.construct(target, args); | ||
Object.getOwnPropertyNames(constructedInstance).forEach((prop) => { | ||
const descriptor = Object.getOwnPropertyDescriptor(constructedInstance, prop); | ||
if (descriptor) { | ||
if (typeof descriptor.value === "function") { | ||
instance[prop] = createMethodSpy(instance, prop, config, descriptor.value.bind(instance)); | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: createSpy(descriptor.value.bind(instance)) | ||
}); | ||
} else { | ||
@@ -911,8 +841,41 @@ Object.defineProperty(instance, prop, descriptor); | ||
}); | ||
} catch { | ||
} | ||
processMembers(instance, target.prototype); | ||
Object.getOwnPropertyNames(target.prototype).forEach((prop) => { | ||
if (prop === "constructor") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target.prototype, prop); | ||
if (descriptor) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: createSpy(override) | ||
}); | ||
} else if (typeof descriptor.value === "function") { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value.bind(instance)) : createSpy() | ||
}); | ||
} | ||
} | ||
}); | ||
let proto = Object.getPrototypeOf(target.prototype); | ||
while (proto && proto !== Object.prototype) { | ||
processMembers(instance, proto); | ||
Object.getOwnPropertyNames(proto).forEach((prop) => { | ||
if (prop === "constructor") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(proto, prop); | ||
if (descriptor && !instance.hasOwnProperty(prop)) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: createSpy(override) | ||
}); | ||
} else if (typeof descriptor.value === "function") { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value.bind(instance)) : createSpy() | ||
}); | ||
} | ||
} | ||
}); | ||
proto = Object.getPrototypeOf(proto); | ||
@@ -923,11 +886,24 @@ } | ||
MockClass.prototype = Object.create(target.prototype); | ||
MockClass.prototype.constructor = MockClass; | ||
Object.getOwnPropertyNames(target).forEach((name) => { | ||
if (name === "length" || name === "prototype" || name === "name") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target, name); | ||
Object.setPrototypeOf(MockClass, target); | ||
Object.getOwnPropertyNames(target).forEach((prop) => { | ||
if (prop === "length" || prop === "prototype" || prop === "name") return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target, prop); | ||
if (descriptor) { | ||
Object.defineProperty(MockClass, name, handleDescriptor(name, descriptor, target)); | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(MockClass, prop, { | ||
...descriptor, | ||
value: createSpy(override) | ||
}); | ||
} else if (typeof descriptor.value === "function") { | ||
Object.defineProperty(MockClass, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value) : createSpy() | ||
}); | ||
} | ||
} | ||
}); | ||
handleStaticMethodInheritance(MockClass, target, { debug: config.debug }); | ||
MockClass[IS_MOCKED] = true; | ||
MockClass.__is_mocked__ = true; | ||
return MockClass; | ||
@@ -981,3 +957,3 @@ } | ||
} | ||
function createMethodSpy2(method, mockTarget, isArrowFn) { | ||
function createMethodSpy(method, mockTarget, isArrowFn) { | ||
const spy = createSpy(); | ||
@@ -1007,3 +983,3 @@ const boundMethod = function(...args) { | ||
const isArrowFn = !method.prototype; | ||
const spy = createMethodSpy2(method, mockTarget, isArrowFn); | ||
const spy = createMethodSpy(method, mockTarget, isArrowFn); | ||
Object.defineProperty(mockTarget, key, { | ||
@@ -1022,3 +998,3 @@ ...descriptor, | ||
const isArrowFn = !method.prototype; | ||
const spy = createMethodSpy2(method, mockTarget, isArrowFn); | ||
const spy = createMethodSpy(method, mockTarget, isArrowFn); | ||
Object.defineProperty(mockTarget, key, { | ||
@@ -1025,0 +1001,0 @@ ...descriptor, |
{ | ||
"name": "@corez/mock", | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"description": "A powerful and flexible TypeScript mocking library for testing", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -171,2 +171,6 @@ # @corez/mock | ||
// Check if class is mocked | ||
console.log(MockDatabase.__is_mocked__); // true | ||
console.log(MockDatabase[IS_MOCKED]); // true | ||
const db = new MockDatabase(); | ||
@@ -194,2 +198,21 @@ // Access call information | ||
### Type Definitions | ||
The library provides comprehensive type definitions for mocked classes: | ||
```typescript | ||
// Mock class type that includes mock markers | ||
type ClsMock<T extends Constructor<any>> = T & { | ||
__is_mocked__: boolean; | ||
[IS_MOCKED]: true; | ||
new (...args: ConstructorParameters<T>): InstanceType<T>; | ||
}; | ||
// Usage with type checking | ||
const mockDb: ClsMock<typeof Database> = mock.cls(Database); | ||
if (mockDb.__is_mocked__) { | ||
console.log('Class is mocked'); | ||
} | ||
``` | ||
## API Reference | ||
@@ -253,43 +276,57 @@ | ||
#### `mock.cls<T extends Constructor<any>>(target: T, options?: ClsMockOptions<T>): ClsMock<T>` | ||
#### `mock.cls<T extends Constructor<any>>(target: T, options?: ClassMockOptions<T>): ClsMock<T>` | ||
Creates a mock class with automatic method tracking: | ||
Creates a mock class with automatic method tracking and type safety: | ||
```typescript | ||
class Database { | ||
async connect() { | ||
/* ... */ | ||
} | ||
async query(sql: string) { | ||
/* ... */ | ||
} | ||
} | ||
// Create a mock class with options | ||
const MockDatabase = mock.cls(Database, { | ||
// Modify original class instead of creating new one | ||
mockInPlace: false, | ||
// Create a new mock class | ||
const MockDatabase = mock.cls(Database, { | ||
// Preserve original method implementations | ||
preservePrototype: true, | ||
// Call original constructor | ||
preserveConstructor: true, | ||
// Override specific methods | ||
overrides: { | ||
query: async () => [{id: 1}], | ||
}, | ||
// Enable debug logging | ||
debug: false, | ||
}); | ||
const db = new MockDatabase(); | ||
// Access call information | ||
const queryMock = db.query as MockFunction; | ||
// Type checking and verification | ||
if (MockDatabase.__is_mocked__) { | ||
console.log('Class is properly mocked'); | ||
} | ||
// Access mock information | ||
const instance = new MockDatabase(); | ||
const queryMock = instance.query as MockFunction; | ||
console.log(queryMock.calls.count()); | ||
``` | ||
// Or modify the original class | ||
mock.cls(Database, { | ||
mockInPlace: true, | ||
overrides: { | ||
query: async () => [{id: 1}], | ||
}, | ||
}); | ||
The `ClassMockOptions` interface provides fine-grained control: | ||
// Store original methods for restoration | ||
const originalQuery = Database.prototype.query; | ||
const originalConnect = Database.prototype.connect; | ||
```typescript | ||
interface ClassMockOptions<T> { | ||
// Whether to modify the original class | ||
mockInPlace?: boolean; | ||
// Later, restore original methods | ||
Database.prototype.query = originalQuery; | ||
Database.prototype.connect = originalConnect; | ||
// Whether to preserve original method implementations | ||
preservePrototype?: boolean; | ||
// Whether to call original constructor | ||
preserveConstructor?: boolean; | ||
// Method overrides | ||
overrides?: Partial<T>; | ||
// Enable debug logging | ||
debug?: boolean; | ||
} | ||
``` | ||
@@ -296,0 +333,0 @@ |
/** | ||
* Mock identification symbol | ||
*/ | ||
export const IS_MOCKED = Symbol('__is_mocked__'); | ||
/** | ||
* Mock-related symbols used for internal state tracking and property access. | ||
@@ -20,2 +25,5 @@ * Using symbols ensures no naming conflicts with mocked objects. | ||
DEBUG_CONTEXT: Symbol('__mock_debug_context__'), | ||
// Mock identification | ||
IS_MOCKED: IS_MOCKED, | ||
} as const; | ||
@@ -22,0 +30,0 @@ |
@@ -1,2 +0,2 @@ | ||
import type {MockFunction} from '../../types'; | ||
import type {ClsMock, MockFunction} from '../../types'; | ||
import {cls} from '../class'; | ||
@@ -46,3 +46,3 @@ | ||
expect(typeof mockAnimal.makeSound).toBe('function'); | ||
expect(mockAnimal.makeSound.mock).toBeDefined(); | ||
expect((mockAnimal.makeSound as MockFunction<() => string>).mock).toBeDefined(); | ||
}); | ||
@@ -55,3 +55,3 @@ | ||
(mockAnimal.makeSound as MockFunction).mockImplementation(mockSound); | ||
(mockAnimal.makeSound as MockFunction<() => string>).mockImplementation(mockSound); | ||
expect(mockAnimal.makeSound()).toBe('custom sound'); | ||
@@ -371,3 +371,3 @@ expect(mockSound).toHaveBeenCalled(); | ||
(mockAnimal.makeSound as MockFunction).mockImplementation(mockSound); | ||
(mockAnimal.makeSound as MockFunction<() => string>).mockImplementation(mockSound); | ||
expect(mockAnimal.makeSound()).toBe('mocked sound'); | ||
@@ -385,3 +385,3 @@ expect(mockSound).toHaveBeenCalled(); | ||
(mockAnimal.makeSound as MockFunction).mockImplementation(mockSound); | ||
(mockAnimal.makeSound as MockFunction<() => string>).mockImplementation(mockSound); | ||
mockAnimal.makeSound(); | ||
@@ -495,2 +495,37 @@ expect(mockSound).toHaveBeenCalled(); | ||
}); | ||
describe('IS_MOCKED symbol', () => { | ||
class TestClass { | ||
value: string = 'test'; | ||
getValue(): string { | ||
return this.value; | ||
} | ||
} | ||
it('should mark mock class with IS_MOCKED symbol', () => { | ||
const MockClass = cls(TestClass); | ||
expect((MockClass as ClsMock<typeof TestClass>).__is_mocked__).toBe(true); | ||
}); | ||
it('should mark mock class with IS_MOCKED symbol when mockInPlace is true', () => { | ||
const MockClass = cls(TestClass, {mockInPlace: true}); | ||
expect((MockClass as ClsMock<typeof TestClass>).__is_mocked__).toBe(true); | ||
}); | ||
it('should not create mock if class is already mocked', () => { | ||
const FirstMock = cls(TestClass); | ||
const SecondMock = cls(FirstMock); | ||
expect(SecondMock).toBe(FirstMock); | ||
}); | ||
it('should preserve IS_MOCKED symbol after inheritance', () => { | ||
class ChildClass extends TestClass { | ||
getUpperValue(): string { | ||
return this.getValue().toUpperCase(); | ||
} | ||
} | ||
const MockChildClass = cls(ChildClass); | ||
expect((MockChildClass as ClsMock<typeof ChildClass>).__is_mocked__).toBe(true); | ||
}); | ||
}); | ||
}); |
@@ -1,2 +0,2 @@ | ||
import {MOCK_SYMBOLS} from '../constants/mock-symbols'; | ||
import {IS_MOCKED, MOCK_SYMBOLS} from '../constants/mock-symbols'; | ||
import {DEFAULT_CLASS_OPTIONS} from '../defaults'; | ||
@@ -6,3 +6,2 @@ import {createSpy} from '../spy'; | ||
import {createDebugContext} from '../utils/debug'; | ||
import {createMethodSpy} from '../utils/method-spy'; | ||
@@ -12,3 +11,3 @@ function handleStaticMethodInheritance( | ||
originalClass: any, | ||
options: Partial<ClassMockOptions> = {}, | ||
_options: Partial<ClassMockOptions> = {}, | ||
): void { | ||
@@ -23,3 +22,3 @@ let currentProto = Object.getPrototypeOf(originalClass); | ||
const method = currentProto[methodName].bind(mockClass); | ||
mockClass[methodName] = createMethodSpy(mockClass, methodName, options, method); | ||
mockClass[methodName] = createSpy(method); | ||
} | ||
@@ -31,24 +30,2 @@ }); | ||
function createPropertyDescriptor<T>( | ||
target: any, | ||
name: string | symbol, | ||
descriptor: PropertyDescriptor, | ||
config: ClassMockOptions<T>, | ||
): PropertyDescriptor { | ||
const getterSpy = descriptor.get | ||
? createMethodSpy(target, name as string, config, descriptor.get.bind(target)) | ||
: undefined; | ||
const setterSpy = descriptor.set | ||
? createMethodSpy(target, name as string, config, descriptor.set.bind(target)) | ||
: undefined; | ||
return { | ||
...descriptor, | ||
get: getterSpy as (() => any) | undefined, | ||
set: setterSpy as ((v: any) => void) | undefined, | ||
configurable: true, | ||
enumerable: descriptor.enumerable, | ||
}; | ||
} | ||
function initializeMockInstance(instance: any, config: ClassMockOptions): void { | ||
@@ -91,2 +68,10 @@ // Use symbols for all mock-related properties | ||
): ClsMock<T> { | ||
// Check if the class is already mocked | ||
if ((target as any)[IS_MOCKED]) { | ||
if (options.debug) { | ||
console.debug('Class is already mocked:', target.name); | ||
} | ||
return target as unknown as ClsMock<T>; | ||
} | ||
const config = { | ||
@@ -101,116 +86,44 @@ ...DEFAULT_CLASS_OPTIONS, | ||
// Helper to handle property descriptor | ||
const handleDescriptor = ( | ||
name: string | symbol, | ||
descriptor: PropertyDescriptor | undefined, | ||
context: any, | ||
): PropertyDescriptor => { | ||
if (!descriptor) { | ||
return { | ||
configurable: true, | ||
enumerable: true, | ||
writable: true, | ||
value: undefined, | ||
}; | ||
} | ||
if (config.mockInPlace) { | ||
// Modify the original class (when mockInPlace is true) | ||
// Mark the class as mocked | ||
(target as any)[IS_MOCKED] = true; | ||
(target as any).__is_mocked__ = true; | ||
const {value, get, set} = descriptor; | ||
if (typeof value === 'function') { | ||
// Check if there's an override implementation | ||
const override = typeof name === 'string' && config.overrides?.[name]; | ||
if (override) { | ||
return { | ||
...descriptor, | ||
value: createMethodSpy(context, name as string, config, override), | ||
}; | ||
} | ||
return { | ||
...descriptor, | ||
value: config.preservePrototype ? createMethodSpy(context, name as string, config, value) : createSpy(), | ||
}; | ||
} | ||
if (get || set) { | ||
// Check if there are getter/setter overrides | ||
const getterOverride = | ||
typeof name === 'string' && config.overrides?.[`get${name.charAt(0).toUpperCase()}${name.slice(1)}`]; | ||
const setterOverride = | ||
typeof name === 'string' && config.overrides?.[`set${name.charAt(0).toUpperCase()}${name.slice(1)}`]; | ||
const getterSpy = | ||
get && | ||
(getterOverride | ||
? createMethodSpy(context, name as string, config, getterOverride) | ||
: config.preservePrototype | ||
? createMethodSpy(context, name as string, config, get) | ||
: createSpy()); | ||
const setterSpy = | ||
set && | ||
(setterOverride | ||
? createMethodSpy(context, name as string, config, setterOverride) | ||
: config.preservePrototype | ||
? createMethodSpy(context, name as string, config, set) | ||
: createSpy()); | ||
return { | ||
...descriptor, | ||
get: getterSpy, | ||
set: setterSpy, | ||
}; | ||
} | ||
return descriptor; | ||
}; | ||
// Process instance properties and methods | ||
const processMembers = (target: any, source: any) => { | ||
Object.getOwnPropertyNames(source).forEach(name => { | ||
if (name === 'constructor') return; | ||
const descriptor = Object.getOwnPropertyDescriptor(source, name); | ||
if (!descriptor) return; | ||
if (descriptor.value && typeof descriptor.value === 'function') { | ||
const override = config.overrides?.[name]; | ||
const method = override || descriptor.value; | ||
target[name] = createMethodSpy(target, name, config, method.bind(target)); | ||
} else if (descriptor.get || descriptor.set) { | ||
Object.defineProperty(target, name, createPropertyDescriptor(target, name, descriptor, config)); | ||
} else { | ||
// Handle prototype methods defined as properties | ||
const value = source[name]; | ||
if (typeof value === 'function') { | ||
target[name] = createMethodSpy(target, name, config, value.bind(target)); | ||
} else { | ||
target[name] = value; | ||
// Mock prototype methods | ||
Object.getOwnPropertyNames(target.prototype).forEach(prop => { | ||
if (prop === 'constructor') return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target.prototype, prop); | ||
if (descriptor) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(target.prototype, prop, { | ||
...descriptor, | ||
value: createSpy(override), | ||
}); | ||
} else if (typeof descriptor.value === 'function') { | ||
Object.defineProperty(target.prototype, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value) : createSpy(), | ||
}); | ||
} | ||
} | ||
}); | ||
}; | ||
if (config.mockInPlace) { | ||
// Modify the original class (when mockInPlace is true) | ||
// First, process prototype methods | ||
const proto = target.prototype; | ||
Object.getOwnPropertyNames(proto).forEach(name => { | ||
if (name === 'constructor') return; | ||
const descriptor = Object.getOwnPropertyDescriptor(proto, name); | ||
if (typeof proto[name] === 'function') { | ||
(proto as any)[name] = createMethodSpy(proto, name, config, proto[name]); | ||
} else if (descriptor) { | ||
Object.defineProperty(proto, name, createPropertyDescriptor(proto, name, descriptor, config)); | ||
} | ||
}); | ||
// Handle static members | ||
Object.getOwnPropertyNames(target).forEach(name => { | ||
if (name === 'length' || name === 'prototype' || name === 'name') return; | ||
if (typeof (target as any)[name] === 'function') { | ||
(target as any)[name] = createMethodSpy(target, name, config, (target as any)[name]); | ||
} else { | ||
const descriptor = Object.getOwnPropertyDescriptor(target, name); | ||
if (descriptor) { | ||
Object.defineProperty(target, name, createPropertyDescriptor(target, name, descriptor, config)); | ||
// Mock static methods | ||
Object.getOwnPropertyNames(target).forEach(prop => { | ||
if (prop === 'length' || prop === 'prototype' || prop === 'name') return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target, prop); | ||
if (descriptor) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(target, prop, { | ||
...descriptor, | ||
value: createSpy(override), | ||
}); | ||
} else if (typeof descriptor.value === 'function') { | ||
Object.defineProperty(target, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value) : createSpy(), | ||
}); | ||
} | ||
@@ -240,12 +153,14 @@ } | ||
try { | ||
// Create a temporary instance to get instance properties | ||
const temp = new target(...args); | ||
// Call original constructor if preserving constructor | ||
if (config.preserveConstructor) { | ||
const constructedInstance = Reflect.construct(target, args); | ||
// Copy instance properties | ||
Object.getOwnPropertyNames(temp).forEach(prop => { | ||
const descriptor = Object.getOwnPropertyDescriptor(temp, prop); | ||
Object.getOwnPropertyNames(constructedInstance).forEach(prop => { | ||
const descriptor = Object.getOwnPropertyDescriptor(constructedInstance, prop); | ||
if (descriptor) { | ||
if (typeof descriptor.value === 'function') { | ||
// Handle arrow function class fields | ||
instance[prop] = createMethodSpy(instance, prop, config, descriptor.value.bind(instance)); | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: createSpy(descriptor.value.bind(instance)), | ||
}); | ||
} else { | ||
@@ -256,13 +171,45 @@ Object.defineProperty(instance, prop, descriptor); | ||
}); | ||
} catch { | ||
// Silently continue if constructor fails | ||
} | ||
// Process prototype methods | ||
processMembers(instance, target.prototype); | ||
// Mock prototype methods | ||
Object.getOwnPropertyNames(target.prototype).forEach(prop => { | ||
if (prop === 'constructor') return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target.prototype, prop); | ||
if (descriptor) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: createSpy(override), | ||
}); | ||
} else if (typeof descriptor.value === 'function') { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value.bind(instance)) : createSpy(), | ||
}); | ||
} | ||
} | ||
}); | ||
// Handle inherited members | ||
// Handle inherited methods | ||
let proto = Object.getPrototypeOf(target.prototype); | ||
while (proto && proto !== Object.prototype) { | ||
processMembers(instance, proto); | ||
Object.getOwnPropertyNames(proto).forEach(prop => { | ||
if (prop === 'constructor') return; | ||
const descriptor = Object.getOwnPropertyDescriptor(proto, prop); | ||
if (descriptor && !instance.hasOwnProperty(prop)) { | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: createSpy(override), | ||
}); | ||
} else if (typeof descriptor.value === 'function') { | ||
Object.defineProperty(instance, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value.bind(instance)) : createSpy(), | ||
}); | ||
} | ||
} | ||
}); | ||
proto = Object.getPrototypeOf(proto); | ||
@@ -272,15 +219,25 @@ } | ||
return instance; | ||
} as unknown as T; | ||
}; | ||
// Set up prototype chain | ||
MockClass.prototype = Object.create(target.prototype); | ||
MockClass.prototype.constructor = MockClass; | ||
Object.setPrototypeOf(MockClass, target); | ||
// Handle static members | ||
Object.getOwnPropertyNames(target).forEach(name => { | ||
if (name === 'length' || name === 'prototype' || name === 'name') return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target, name); | ||
// Copy static properties | ||
Object.getOwnPropertyNames(target).forEach(prop => { | ||
if (prop === 'length' || prop === 'prototype' || prop === 'name') return; | ||
const descriptor = Object.getOwnPropertyDescriptor(target, prop); | ||
if (descriptor) { | ||
Object.defineProperty(MockClass, name, handleDescriptor(name, descriptor, target)); | ||
const override = config.overrides?.[prop]; | ||
if (override) { | ||
Object.defineProperty(MockClass, prop, { | ||
...descriptor, | ||
value: createSpy(override), | ||
}); | ||
} else if (typeof descriptor.value === 'function') { | ||
Object.defineProperty(MockClass, prop, { | ||
...descriptor, | ||
value: config.preservePrototype ? createSpy(descriptor.value) : createSpy(), | ||
}); | ||
} | ||
} | ||
@@ -292,3 +249,7 @@ }); | ||
// Mark the mock class as mocked | ||
(MockClass as any)[IS_MOCKED] = true; | ||
(MockClass as any).__is_mocked__ = true; | ||
return MockClass as unknown as ClsMock<T>; | ||
} |
@@ -153,3 +153,3 @@ import {Fn, MockFunction} from './types'; | ||
spy._this = thisArg; | ||
const result = target.apply(thisArg, argumentsList); | ||
const result = target.apply(thisArg, argumentsList as unknown as Parameters<T>); | ||
spy._this = null; | ||
@@ -156,0 +156,0 @@ return result; |
@@ -0,1 +1,2 @@ | ||
import {IS_MOCKED} from '../constants/mock-symbols'; | ||
import type {Constructor, DeepPartial, Fn, PropertyDescriptor, RecursivePartial} from './common'; | ||
@@ -201,3 +202,3 @@ | ||
*/ | ||
export interface MockFunction<T extends Fn = Fn> extends Function { | ||
export interface MockFunction<T extends Fn = Fn> { | ||
(...args: Parameters<T>): ReturnType<T>; | ||
@@ -372,9 +373,9 @@ _isMockFunction: boolean; | ||
/** | ||
* Represents a mocked class constructor | ||
* Mock class type that extends the original class type | ||
* Includes all mock-related properties and methods | ||
*/ | ||
export type ClsMock<T extends new (...args: any[]) => any> = { | ||
new (...args: ConstructorParameters<T>): MockOf<InstanceType<T>>; | ||
prototype: MockOf<InstanceType<T>>; | ||
} & { | ||
[K in keyof T]: T[K] extends (...args: any[]) => any ? MockFunction<T[K]> : T[K]; | ||
export type ClsMock<T extends Constructor<any>> = T & { | ||
__is_mocked__: boolean; | ||
[IS_MOCKED]: true; | ||
new (...args: ConstructorParameters<T>): InstanceType<T>; | ||
}; | ||
@@ -381,0 +382,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
53
859
521928
8137