diff options
Diffstat (limited to 'node_modules/jest-mock/build')
| -rw-r--r-- | node_modules/jest-mock/build/index.d.ts | 185 | ||||
| -rw-r--r-- | node_modules/jest-mock/build/index.js | 964 | 
2 files changed, 1149 insertions, 0 deletions
diff --git a/node_modules/jest-mock/build/index.d.ts b/node_modules/jest-mock/build/index.d.ts new file mode 100644 index 0000000..f345294 --- /dev/null +++ b/node_modules/jest-mock/build/index.d.ts @@ -0,0 +1,185 @@ +/** + * 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 declare type MockFunctionMetadataType = 'object' | 'array' | 'regexp' | 'function' | 'constant' | 'collection' | 'null' | 'undefined'; +export declare type MockFunctionMetadata<T, Y extends Array<unknown>, Type = MockFunctionMetadataType> = { +    ref?: number; +    members?: Record<string, MockFunctionMetadata<T, Y>>; +    mockImpl?: (...args: Y) => T; +    name?: string; +    refID?: number; +    type?: Type; +    value?: T; +    length?: number; +}; +export declare type MockableFunction = (...args: Array<any>) => any; +export declare type MethodKeysOf<T> = { +    [K in keyof T]: T[K] extends MockableFunction ? K : never; +}[keyof T]; +export declare type PropertyKeysOf<T> = { +    [K in keyof T]: T[K] extends MockableFunction ? never : K; +}[keyof T]; +export declare type ArgumentsOf<T> = T extends (...args: infer A) => any ? A : never; +export declare type ConstructorArgumentsOf<T> = T extends new (...args: infer A) => any ? A : never; +export declare type MaybeMockedConstructor<T> = T extends new (...args: Array<any>) => infer R ? MockInstance<R, ConstructorArgumentsOf<T>> : T; +export declare type MockedFunction<T extends MockableFunction> = MockWithArgs<T> & { +    [K in keyof T]: T[K]; +}; +export declare type MockedFunctionDeep<T extends MockableFunction> = MockWithArgs<T> & MockedObjectDeep<T>; +export declare type MockedObject<T> = MaybeMockedConstructor<T> & { +    [K in MethodKeysOf<T>]: T[K] extends MockableFunction ? MockedFunction<T[K]> : T[K]; +} & { +    [K in PropertyKeysOf<T>]: T[K]; +}; +export declare type MockedObjectDeep<T> = MaybeMockedConstructor<T> & { +    [K in MethodKeysOf<T>]: T[K] extends MockableFunction ? MockedFunctionDeep<T[K]> : T[K]; +} & { +    [K in PropertyKeysOf<T>]: MaybeMockedDeep<T[K]>; +}; +export declare type MaybeMockedDeep<T> = T extends MockableFunction ? MockedFunctionDeep<T> : T extends object ? MockedObjectDeep<T> : T; +export declare type MaybeMocked<T> = T extends MockableFunction ? MockedFunction<T> : T extends object ? MockedObject<T> : T; +export declare type ArgsType<T> = T extends (...args: infer A) => any ? A : never; +export declare type Mocked<T> = { +    [P in keyof T]: T[P] extends (...args: Array<any>) => any ? MockInstance<ReturnType<T[P]>, ArgsType<T[P]>> : T[P] extends Constructable ? MockedClass<T[P]> : T[P]; +} & T; +export declare type MockedClass<T extends Constructable> = MockInstance<InstanceType<T>, T extends new (...args: infer P) => any ? P : never> & { +    prototype: T extends { +        prototype: any; +    } ? Mocked<T['prototype']> : never; +} & T; +export interface Constructable { +    new (...args: Array<any>): any; +} +export interface MockWithArgs<T extends MockableFunction> extends MockInstance<ReturnType<T>, ArgumentsOf<T>> { +    new (...args: ConstructorArgumentsOf<T>): T; +    (...args: ArgumentsOf<T>): ReturnType<T>; +} +export interface Mock<T, Y extends Array<unknown> = Array<unknown>> extends Function, MockInstance<T, Y> { +    new (...args: Y): T; +    (...args: Y): T; +} +export interface SpyInstance<T, Y extends Array<unknown>> extends MockInstance<T, Y> { +} +export interface MockInstance<T, Y extends Array<unknown>> { +    _isMockFunction: true; +    _protoImpl: Function; +    getMockName(): string; +    getMockImplementation(): Function | undefined; +    mock: MockFunctionState<T, Y>; +    mockClear(): this; +    mockReset(): this; +    mockRestore(): void; +    mockImplementation(fn: (...args: Y) => T): this; +    mockImplementation(fn: () => Promise<T>): this; +    mockImplementationOnce(fn: (...args: Y) => T): this; +    mockImplementationOnce(fn: () => Promise<T>): this; +    mockName(name: string): this; +    mockReturnThis(): this; +    mockReturnValue(value: T): this; +    mockReturnValueOnce(value: T): this; +    mockResolvedValue(value: Unpromisify<T>): this; +    mockResolvedValueOnce(value: Unpromisify<T>): this; +    mockRejectedValue(value: unknown): this; +    mockRejectedValueOnce(value: unknown): this; +} +declare type Unpromisify<T> = T extends Promise<infer R> ? R : never; +/** + * Possible types of a MockFunctionResult. + * 'return': The call completed by returning normally. + * 'throw': The call completed by throwing a value. + * 'incomplete': The call has not completed yet. This is possible if you read + *               the  mock function result from within the mock function itself + *               (or a function called by the mock function). + */ +declare type MockFunctionResultType = 'return' | 'throw' | 'incomplete'; +/** + * Represents the result of a single call to a mock function. + */ +declare type MockFunctionResult = { +    /** +     * Indicates how the call completed. +     */ +    type: MockFunctionResultType; +    /** +     * The value that was either thrown or returned by the function. +     * Undefined when type === 'incomplete'. +     */ +    value: unknown; +}; +declare type MockFunctionState<T, Y extends Array<unknown>> = { +    calls: Array<Y>; +    instances: Array<T>; +    invocationCallOrder: Array<number>; +    /** +     * Getter for retrieving the last call arguments +     */ +    lastCall?: Y; +    /** +     * List of results of calls to the mock function. +     */ +    results: Array<MockFunctionResult>; +}; +declare type NonFunctionPropertyNames<T> = { +    [K in keyof T]: T[K] extends (...args: Array<any>) => any ? never : K; +}[keyof T] & string; +declare type FunctionPropertyNames<T> = { +    [K in keyof T]: T[K] extends (...args: Array<any>) => any ? K : never; +}[keyof T] & string; +export declare class ModuleMocker { +    private _environmentGlobal; +    private _mockState; +    private _mockConfigRegistry; +    private _spyState; +    private _invocationCallCounter; +    /** +     * @see README.md +     * @param global Global object of the test environment, used to create +     * mocks +     */ +    constructor(global: typeof globalThis); +    private _getSlots; +    private _ensureMockConfig; +    private _ensureMockState; +    private _defaultMockConfig; +    private _defaultMockState; +    private _makeComponent; +    private _createMockFunction; +    private _generateMock; +    /** +     * @see README.md +     * @param _metadata Metadata for the mock in the schema returned by the +     * getMetadata method of this module. +     */ +    generateFromMetadata<T, Y extends Array<unknown>>(_metadata: MockFunctionMetadata<T, Y>): Mock<T, Y>; +    /** +     * @see README.md +     * @param component The component for which to retrieve metadata. +     */ +    getMetadata<T, Y extends Array<unknown>>(component: T, _refs?: Map<T, number>): MockFunctionMetadata<T, Y> | null; +    isMockFunction<T>(fn: unknown): fn is Mock<T>; +    fn<T, Y extends Array<unknown>>(implementation?: (...args: Y) => T): Mock<T, Y>; +    spyOn<T extends {}, M extends NonFunctionPropertyNames<T>>(object: T, methodName: M, accessType: 'get'): SpyInstance<T[M], []>; +    spyOn<T extends {}, M extends NonFunctionPropertyNames<T>>(object: T, methodName: M, accessType: 'set'): SpyInstance<void, [T[M]]>; +    spyOn<T extends {}, M extends FunctionPropertyNames<T>>(object: T, methodName: M): T[M] extends (...args: Array<any>) => any ? SpyInstance<ReturnType<T[M]>, Parameters<T[M]>> : never; +    private _spyOnProperty; +    clearAllMocks(): void; +    resetAllMocks(): void; +    restoreAllMocks(): void; +    private _typeOf; +    mocked<T>(item: T, deep?: false): MaybeMocked<T>; +    mocked<T>(item: T, deep: true): MaybeMockedDeep<T>; +} +export declare const fn: <T, Y extends unknown[]>(implementation?: ((...args: Y) => T) | undefined) => Mock<T, Y>; +export declare const spyOn: { +    <T extends {}, M extends NonFunctionPropertyNames<T>>(object: T, methodName: M, accessType: 'get'): SpyInstance<T[M], []>; +    <T_2 extends {}, M_2 extends NonFunctionPropertyNames<T_2>>(object: T_2, methodName: M_2, accessType: 'set'): SpyInstance<void, [T_2[M_2]]>; +    <T_4 extends {}, M_4 extends FunctionPropertyNames<T_4>>(object: T_4, methodName: M_4): T_4[M_4] extends (...args: Array<any>) => any ? SpyInstance<ReturnType<T_4[M_4]>, Parameters<T_4[M_4]>> : never; +}; +export declare const mocked: { +    <T>(item: T, deep?: false | undefined): MaybeMocked<T>; +    <T_2>(item: T_2, deep: true): MaybeMockedDeep<T_2>; +}; +export {}; diff --git a/node_modules/jest-mock/build/index.js b/node_modules/jest-mock/build/index.js new file mode 100644 index 0000000..cacd81a --- /dev/null +++ b/node_modules/jest-mock/build/index.js @@ -0,0 +1,964 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { +  value: true +}); +exports.spyOn = exports.mocked = exports.fn = exports.ModuleMocker = void 0; + +function _defineProperty(obj, key, value) { +  if (key in obj) { +    Object.defineProperty(obj, key, { +      value: value, +      enumerable: true, +      configurable: true, +      writable: true +    }); +  } else { +    obj[key] = value; +  } +  return obj; +} + +/** + * 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. + */ + +/* eslint-disable local/ban-types-eventually, local/prefer-rest-params-eventually */ + +/** + * Possible types of a MockFunctionResult. + * 'return': The call completed by returning normally. + * 'throw': The call completed by throwing a value. + * 'incomplete': The call has not completed yet. This is possible if you read + *               the  mock function result from within the mock function itself + *               (or a function called by the mock function). + */ + +/** + * Represents the result of a single call to a mock function. + */ +// see https://github.com/Microsoft/TypeScript/issues/25215 +const MOCK_CONSTRUCTOR_NAME = 'mockConstructor'; +const FUNCTION_NAME_RESERVED_PATTERN = /[\s!-\/:-@\[-`{-~]/; +const FUNCTION_NAME_RESERVED_REPLACE = new RegExp( +  FUNCTION_NAME_RESERVED_PATTERN.source, +  'g' +); +const RESERVED_KEYWORDS = new Set([ +  'arguments', +  'await', +  'break', +  'case', +  'catch', +  'class', +  'const', +  'continue', +  'debugger', +  'default', +  'delete', +  'do', +  'else', +  'enum', +  'eval', +  'export', +  'extends', +  'false', +  'finally', +  'for', +  'function', +  'if', +  'implements', +  'import', +  'in', +  'instanceof', +  'interface', +  'let', +  'new', +  'null', +  'package', +  'private', +  'protected', +  'public', +  'return', +  'static', +  'super', +  'switch', +  'this', +  'throw', +  'true', +  'try', +  'typeof', +  'var', +  'void', +  'while', +  'with', +  'yield' +]); + +function matchArity(fn, length) { +  let mockConstructor; + +  switch (length) { +    case 1: +      mockConstructor = function (_a) { +        return fn.apply(this, arguments); +      }; + +      break; + +    case 2: +      mockConstructor = function (_a, _b) { +        return fn.apply(this, arguments); +      }; + +      break; + +    case 3: +      mockConstructor = function (_a, _b, _c) { +        return fn.apply(this, arguments); +      }; + +      break; + +    case 4: +      mockConstructor = function (_a, _b, _c, _d) { +        return fn.apply(this, arguments); +      }; + +      break; + +    case 5: +      mockConstructor = function (_a, _b, _c, _d, _e) { +        return fn.apply(this, arguments); +      }; + +      break; + +    case 6: +      mockConstructor = function (_a, _b, _c, _d, _e, _f) { +        return fn.apply(this, arguments); +      }; + +      break; + +    case 7: +      mockConstructor = function (_a, _b, _c, _d, _e, _f, _g) { +        return fn.apply(this, arguments); +      }; + +      break; + +    case 8: +      mockConstructor = function (_a, _b, _c, _d, _e, _f, _g, _h) { +        return fn.apply(this, arguments); +      }; + +      break; + +    case 9: +      mockConstructor = function (_a, _b, _c, _d, _e, _f, _g, _h, _i) { +        return fn.apply(this, arguments); +      }; + +      break; + +    default: +      mockConstructor = function () { +        return fn.apply(this, arguments); +      }; + +      break; +  } + +  return mockConstructor; +} + +function getObjectType(value) { +  return Object.prototype.toString.apply(value).slice(8, -1); +} + +function getType(ref) { +  const typeName = getObjectType(ref); + +  if ( +    typeName === 'Function' || +    typeName === 'AsyncFunction' || +    typeName === 'GeneratorFunction' +  ) { +    return 'function'; +  } else if (Array.isArray(ref)) { +    return 'array'; +  } else if (typeName === 'Object') { +    return 'object'; +  } else if ( +    typeName === 'Number' || +    typeName === 'String' || +    typeName === 'Boolean' || +    typeName === 'Symbol' +  ) { +    return 'constant'; +  } else if ( +    typeName === 'Map' || +    typeName === 'WeakMap' || +    typeName === 'Set' +  ) { +    return 'collection'; +  } else if (typeName === 'RegExp') { +    return 'regexp'; +  } else if (ref === undefined) { +    return 'undefined'; +  } else if (ref === null) { +    return 'null'; +  } else { +    return null; +  } +} + +function isReadonlyProp(object, prop) { +  if ( +    prop === 'arguments' || +    prop === 'caller' || +    prop === 'callee' || +    prop === 'name' || +    prop === 'length' +  ) { +    const typeName = getObjectType(object); +    return ( +      typeName === 'Function' || +      typeName === 'AsyncFunction' || +      typeName === 'GeneratorFunction' +    ); +  } + +  if ( +    prop === 'source' || +    prop === 'global' || +    prop === 'ignoreCase' || +    prop === 'multiline' +  ) { +    return getObjectType(object) === 'RegExp'; +  } + +  return false; +} + +class ModuleMocker { +  /** +   * @see README.md +   * @param global Global object of the test environment, used to create +   * mocks +   */ +  constructor(global) { +    _defineProperty(this, '_environmentGlobal', void 0); + +    _defineProperty(this, '_mockState', void 0); + +    _defineProperty(this, '_mockConfigRegistry', void 0); + +    _defineProperty(this, '_spyState', void 0); + +    _defineProperty(this, '_invocationCallCounter', void 0); + +    this._environmentGlobal = global; +    this._mockState = new WeakMap(); +    this._mockConfigRegistry = new WeakMap(); +    this._spyState = new Set(); +    this._invocationCallCounter = 1; +  } + +  _getSlots(object) { +    if (!object) { +      return []; +    } + +    const slots = new Set(); +    const EnvObjectProto = this._environmentGlobal.Object.prototype; +    const EnvFunctionProto = this._environmentGlobal.Function.prototype; +    const EnvRegExpProto = this._environmentGlobal.RegExp.prototype; // Also check the builtins in the current context as they leak through +    // core node modules. + +    const ObjectProto = Object.prototype; +    const FunctionProto = Function.prototype; +    const RegExpProto = RegExp.prototype; // Properties of Object.prototype, Function.prototype and RegExp.prototype +    // are never reported as slots + +    while ( +      object != null && +      object !== EnvObjectProto && +      object !== EnvFunctionProto && +      object !== EnvRegExpProto && +      object !== ObjectProto && +      object !== FunctionProto && +      object !== RegExpProto +    ) { +      const ownNames = Object.getOwnPropertyNames(object); + +      for (let i = 0; i < ownNames.length; i++) { +        const prop = ownNames[i]; + +        if (!isReadonlyProp(object, prop)) { +          const propDesc = Object.getOwnPropertyDescriptor(object, prop); + +          if ((propDesc !== undefined && !propDesc.get) || object.__esModule) { +            slots.add(prop); +          } +        } +      } + +      object = Object.getPrototypeOf(object); +    } + +    return Array.from(slots); +  } + +  _ensureMockConfig(f) { +    let config = this._mockConfigRegistry.get(f); + +    if (!config) { +      config = this._defaultMockConfig(); + +      this._mockConfigRegistry.set(f, config); +    } + +    return config; +  } + +  _ensureMockState(f) { +    let state = this._mockState.get(f); + +    if (!state) { +      state = this._defaultMockState(); + +      this._mockState.set(f, state); +    } + +    if (state.calls.length > 0) { +      state.lastCall = state.calls[state.calls.length - 1]; +    } + +    return state; +  } + +  _defaultMockConfig() { +    return { +      mockImpl: undefined, +      mockName: 'jest.fn()', +      specificMockImpls: [], +      specificReturnValues: [] +    }; +  } + +  _defaultMockState() { +    return { +      calls: [], +      instances: [], +      invocationCallOrder: [], +      results: [] +    }; +  } + +  _makeComponent(metadata, restore) { +    if (metadata.type === 'object') { +      return new this._environmentGlobal.Object(); +    } else if (metadata.type === 'array') { +      return new this._environmentGlobal.Array(); +    } else if (metadata.type === 'regexp') { +      return new this._environmentGlobal.RegExp(''); +    } else if ( +      metadata.type === 'constant' || +      metadata.type === 'collection' || +      metadata.type === 'null' || +      metadata.type === 'undefined' +    ) { +      return metadata.value; +    } else if (metadata.type === 'function') { +      const prototype = +        (metadata.members && +          metadata.members.prototype && +          metadata.members.prototype.members) || +        {}; + +      const prototypeSlots = this._getSlots(prototype); + +      const mocker = this; +      const mockConstructor = matchArity(function (...args) { +        const mockState = mocker._ensureMockState(f); + +        const mockConfig = mocker._ensureMockConfig(f); + +        mockState.instances.push(this); +        mockState.calls.push(args); // Create and record an "incomplete" mock result immediately upon +        // calling rather than waiting for the mock to return. This avoids +        // issues caused by recursion where results can be recorded in the +        // wrong order. + +        const mockResult = { +          type: 'incomplete', +          value: undefined +        }; +        mockState.results.push(mockResult); +        mockState.invocationCallOrder.push(mocker._invocationCallCounter++); // Will be set to the return value of the mock if an error is not thrown + +        let finalReturnValue; // Will be set to the error that is thrown by the mock (if it throws) + +        let thrownError; // Will be set to true if the mock throws an error. The presence of a +        // value in `thrownError` is not a 100% reliable indicator because a +        // function could throw a value of undefined. + +        let callDidThrowError = false; + +        try { +          // The bulk of the implementation is wrapped in an immediately +          // executed arrow function so the return value of the mock function +          // can be easily captured and recorded, despite the many separate +          // return points within the logic. +          finalReturnValue = (() => { +            if (this instanceof f) { +              // This is probably being called as a constructor +              prototypeSlots.forEach(slot => { +                // Copy prototype methods to the instance to make +                // it easier to interact with mock instance call and +                // return values +                if (prototype[slot].type === 'function') { +                  // @ts-expect-error no index signature +                  const protoImpl = this[slot]; // @ts-expect-error no index signature + +                  this[slot] = mocker.generateFromMetadata(prototype[slot]); // @ts-expect-error no index signature + +                  this[slot]._protoImpl = protoImpl; +                } +              }); // Run the mock constructor implementation + +              const mockImpl = mockConfig.specificMockImpls.length +                ? mockConfig.specificMockImpls.shift() +                : mockConfig.mockImpl; +              return mockImpl && mockImpl.apply(this, arguments); +            } // If mockImplementationOnce()/mockImplementation() is last set, +            // implementation use the mock + +            let specificMockImpl = mockConfig.specificMockImpls.shift(); + +            if (specificMockImpl === undefined) { +              specificMockImpl = mockConfig.mockImpl; +            } + +            if (specificMockImpl) { +              return specificMockImpl.apply(this, arguments); +            } // Otherwise use prototype implementation + +            if (f._protoImpl) { +              return f._protoImpl.apply(this, arguments); +            } + +            return undefined; +          })(); +        } catch (error) { +          // Store the thrown error so we can record it, then re-throw it. +          thrownError = error; +          callDidThrowError = true; +          throw error; +        } finally { +          // Record the result of the function. +          // NOTE: Intentionally NOT pushing/indexing into the array of mock +          //       results here to avoid corrupting results data if mockClear() +          //       is called during the execution of the mock. +          mockResult.type = callDidThrowError ? 'throw' : 'return'; +          mockResult.value = callDidThrowError ? thrownError : finalReturnValue; +        } + +        return finalReturnValue; +      }, metadata.length || 0); + +      const f = this._createMockFunction(metadata, mockConstructor); + +      f._isMockFunction = true; + +      f.getMockImplementation = () => this._ensureMockConfig(f).mockImpl; + +      if (typeof restore === 'function') { +        this._spyState.add(restore); +      } + +      this._mockState.set(f, this._defaultMockState()); + +      this._mockConfigRegistry.set(f, this._defaultMockConfig()); + +      Object.defineProperty(f, 'mock', { +        configurable: false, +        enumerable: true, +        get: () => this._ensureMockState(f), +        set: val => this._mockState.set(f, val) +      }); + +      f.mockClear = () => { +        this._mockState.delete(f); + +        return f; +      }; + +      f.mockReset = () => { +        f.mockClear(); + +        this._mockConfigRegistry.delete(f); + +        return f; +      }; + +      f.mockRestore = () => { +        f.mockReset(); +        return restore ? restore() : undefined; +      }; + +      f.mockReturnValueOnce = ( +        value // next function call will return this value or default return value +      ) => f.mockImplementationOnce(() => value); + +      f.mockResolvedValueOnce = value => +        f.mockImplementationOnce(() => Promise.resolve(value)); + +      f.mockRejectedValueOnce = value => +        f.mockImplementationOnce(() => Promise.reject(value)); + +      f.mockReturnValue = ( +        value // next function call will return specified return value or this one +      ) => f.mockImplementation(() => value); + +      f.mockResolvedValue = value => +        f.mockImplementation(() => Promise.resolve(value)); + +      f.mockRejectedValue = value => +        f.mockImplementation(() => Promise.reject(value)); + +      f.mockImplementationOnce = fn => { +        // next function call will use this mock implementation return value +        // or default mock implementation return value +        const mockConfig = this._ensureMockConfig(f); + +        mockConfig.specificMockImpls.push(fn); +        return f; +      }; + +      f.mockImplementation = fn => { +        // next function call will use mock implementation return value +        const mockConfig = this._ensureMockConfig(f); + +        mockConfig.mockImpl = fn; +        return f; +      }; + +      f.mockReturnThis = () => +        f.mockImplementation(function () { +          return this; +        }); + +      f.mockName = name => { +        if (name) { +          const mockConfig = this._ensureMockConfig(f); + +          mockConfig.mockName = name; +        } + +        return f; +      }; + +      f.getMockName = () => { +        const mockConfig = this._ensureMockConfig(f); + +        return mockConfig.mockName || 'jest.fn()'; +      }; + +      if (metadata.mockImpl) { +        f.mockImplementation(metadata.mockImpl); +      } + +      return f; +    } else { +      const unknownType = metadata.type || 'undefined type'; +      throw new Error('Unrecognized type ' + unknownType); +    } +  } + +  _createMockFunction(metadata, mockConstructor) { +    let name = metadata.name; + +    if (!name) { +      return mockConstructor; +    } // Preserve `name` property of mocked function. + +    const boundFunctionPrefix = 'bound '; +    let bindCall = ''; // if-do-while for perf reasons. The common case is for the if to fail. + +    if (name && name.startsWith(boundFunctionPrefix)) { +      do { +        name = name.substring(boundFunctionPrefix.length); // Call bind() just to alter the function name. + +        bindCall = '.bind(null)'; +      } while (name && name.startsWith(boundFunctionPrefix)); +    } // Special case functions named `mockConstructor` to guard for infinite +    // loops. + +    if (name === MOCK_CONSTRUCTOR_NAME) { +      return mockConstructor; +    } + +    if ( +      // It's a syntax error to define functions with a reserved keyword +      // as name. +      RESERVED_KEYWORDS.has(name) || // It's also a syntax error to define functions with a name that starts with a number +      /^\d/.test(name) +    ) { +      name = '$' + name; +    } // It's also a syntax error to define a function with a reserved character +    // as part of it's name. + +    if (FUNCTION_NAME_RESERVED_PATTERN.test(name)) { +      name = name.replace(FUNCTION_NAME_RESERVED_REPLACE, '$'); +    } + +    const body = +      'return function ' + +      name + +      '() {' + +      'return ' + +      MOCK_CONSTRUCTOR_NAME + +      '.apply(this,arguments);' + +      '}' + +      bindCall; +    const createConstructor = new this._environmentGlobal.Function( +      MOCK_CONSTRUCTOR_NAME, +      body +    ); +    return createConstructor(mockConstructor); +  } + +  _generateMock(metadata, callbacks, refs) { +    // metadata not compatible but it's the same type, maybe problem with +    // overloading of _makeComponent and not _generateMock? +    // @ts-expect-error +    const mock = this._makeComponent(metadata); + +    if (metadata.refID != null) { +      refs[metadata.refID] = mock; +    } + +    this._getSlots(metadata.members).forEach(slot => { +      const slotMetadata = (metadata.members && metadata.members[slot]) || {}; + +      if (slotMetadata.ref != null) { +        callbacks.push( +          (function (ref) { +            return () => (mock[slot] = refs[ref]); +          })(slotMetadata.ref) +        ); +      } else { +        mock[slot] = this._generateMock(slotMetadata, callbacks, refs); +      } +    }); + +    if ( +      metadata.type !== 'undefined' && +      metadata.type !== 'null' && +      mock.prototype && +      typeof mock.prototype === 'object' +    ) { +      mock.prototype.constructor = mock; +    } + +    return mock; +  } +  /** +   * @see README.md +   * @param _metadata Metadata for the mock in the schema returned by the +   * getMetadata method of this module. +   */ + +  generateFromMetadata(_metadata) { +    const callbacks = []; +    const refs = {}; + +    const mock = this._generateMock(_metadata, callbacks, refs); + +    callbacks.forEach(setter => setter()); +    return mock; +  } +  /** +   * @see README.md +   * @param component The component for which to retrieve metadata. +   */ + +  getMetadata(component, _refs) { +    const refs = _refs || new Map(); +    const ref = refs.get(component); + +    if (ref != null) { +      return { +        ref +      }; +    } + +    const type = getType(component); + +    if (!type) { +      return null; +    } + +    const metadata = { +      type +    }; + +    if ( +      type === 'constant' || +      type === 'collection' || +      type === 'undefined' || +      type === 'null' +    ) { +      metadata.value = component; +      return metadata; +    } else if (type === 'function') { +      // @ts-expect-error this is a function so it has a name +      metadata.name = component.name; // @ts-expect-error may be a mock + +      if (component._isMockFunction === true) { +        // @ts-expect-error may be a mock +        metadata.mockImpl = component.getMockImplementation(); +      } +    } + +    metadata.refID = refs.size; +    refs.set(component, metadata.refID); +    let members = null; // Leave arrays alone + +    if (type !== 'array') { +      this._getSlots(component).forEach(slot => { +        if ( +          type === 'function' && // @ts-expect-error may be a mock +          component._isMockFunction === true && +          slot.match(/^mock/) +        ) { +          return; +        } // @ts-expect-error no index signature + +        const slotMetadata = this.getMetadata(component[slot], refs); + +        if (slotMetadata) { +          if (!members) { +            members = {}; +          } + +          members[slot] = slotMetadata; +        } +      }); +    } + +    if (members) { +      metadata.members = members; +    } + +    return metadata; +  } + +  isMockFunction(fn) { +    return !!fn && fn._isMockFunction === true; +  } + +  fn(implementation) { +    const length = implementation ? implementation.length : 0; + +    const fn = this._makeComponent({ +      length, +      type: 'function' +    }); + +    if (implementation) { +      fn.mockImplementation(implementation); +    } + +    return fn; +  } + +  // 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') { +      throw new Error( +        'Cannot spyOn on a primitive value; ' + this._typeOf(object) + ' given' +      ); +    } + +    const original = object[methodName]; + +    if (!this.isMockFunction(original)) { +      if (typeof original !== 'function') { +        throw new Error( +          'Cannot spy the ' + +            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); +      }); +    } + +    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 (!obj) { +      throw new Error( +        'spyOn could not find an object to spy upon for ' + propertyName + '' +      ); +    } + +    if (!propertyName) { +      throw new Error('No property name supplied'); +    } + +    let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName); +    let proto = Object.getPrototypeOf(obj); + +    while (!descriptor && proto !== null) { +      descriptor = Object.getOwnPropertyDescriptor(proto, propertyName); +      proto = Object.getPrototypeOf(proto); +    } + +    if (!descriptor) { +      throw new Error(propertyName + ' property does not exist'); +    } + +    if (!descriptor.configurable) { +      throw new Error(propertyName + ' is not declared configurable'); +    } + +    if (!descriptor[accessType]) { +      throw new Error( +        'Property ' + propertyName + ' does not have access type ' + accessType +      ); +    } + +    const original = descriptor[accessType]; + +    if (!this.isMockFunction(original)) { +      if (typeof original !== 'function') { +        throw new Error( +          'Cannot spy the ' + +            propertyName + +            ' property because it is not a function; ' + +            this._typeOf(original) + +            ' given instead' +        ); +      } // @ts-expect-error: mock is assignable + +      descriptor[accessType] = this._makeComponent( +        { +          type: 'function' +        }, +        () => { +          // @ts-expect-error: mock is assignable +          descriptor[accessType] = original; +          Object.defineProperty(obj, propertyName, descriptor); +        } +      ); +      descriptor[accessType].mockImplementation(function () { +        // @ts-expect-error +        return original.apply(this, arguments); +      }); +    } + +    Object.defineProperty(obj, propertyName, descriptor); +    return descriptor[accessType]; +  } + +  clearAllMocks() { +    this._mockState = new WeakMap(); +  } + +  resetAllMocks() { +    this._mockConfigRegistry = new WeakMap(); +    this._mockState = new WeakMap(); +  } + +  restoreAllMocks() { +    this._spyState.forEach(restore => restore()); + +    this._spyState = new Set(); +  } + +  _typeOf(value) { +    return value == null ? '' + value : typeof value; +  } // the typings test helper + +  mocked(item, _deep = false) { +    return item; +  } +} + +exports.ModuleMocker = ModuleMocker; +const JestMock = new ModuleMocker(global); +const fn = JestMock.fn.bind(JestMock); +exports.fn = fn; +const spyOn = JestMock.spyOn.bind(JestMock); +exports.spyOn = spyOn; +const mocked = JestMock.mocked.bind(JestMock); +exports.mocked = mocked;  | 
