strong-mock 8.0.0-beta.2 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -127,7 +127,7 @@ console.log(foo.bar(23)); // even more awesome
127
127
 
128
128
  ### Setting invocation count expectations
129
129
 
130
- By default, each call is expected to be called only once. You can expect a call to be made multiple times by using the invocation count helpers `between`, `atLeast`, `times`, `anyTimes` etc.:
130
+ By default, each call is expected to be made only once. You can expect a call to be made multiple times by using the invocation count helpers `between`, `atLeast`, `times`, `anyTimes` etc.:
131
131
 
132
132
  ```typescript
133
133
  const fn = mock<(x: number) => number>();
@@ -177,7 +177,7 @@ console.log(fn(1)); // 2
177
177
 
178
178
  ### Mocking promises
179
179
 
180
- If you're mocking something that returns a promise then you'll be able to use the promise helpers to set the return value.
180
+ If you're mocking something that returns a promise then you'll be able to use the `thenResolve` promise helper to set the return value.
181
181
 
182
182
  ```typescript
183
183
  type Fn = (x: number) => Promise<number>;
@@ -191,15 +191,21 @@ console.log(await fn()); // 2
191
191
 
192
192
  ### Throwing errors
193
193
 
194
+ Use `thenThrow` or `thenReject` to throw an `Error` instance. You can customize the error message, or even pass a derived class.
195
+
194
196
  ```typescript
195
197
  type Fn = (x: number) => void;
196
198
  type FnWithPromise = (x: number) => Promise<void>;
197
199
 
200
+ class MyError extends Error {}
201
+
198
202
  const fn = mock<Fn>();
199
203
  const fnWithPromise = mock<FnWithPromise>();
200
204
 
205
+ // All of these will throw an Error instance.
201
206
  when(() => fn(1)).thenThrow();
202
- when(() => fnWithPromise(1)).thenReject();
207
+ when(() => fn(2)).thenThrow(MyError);
208
+ when(() => fnWithPromise(1)).thenReject('oops');
203
209
  ```
204
210
 
205
211
  ### Verifying expectations
@@ -423,18 +429,23 @@ console.log(fn(1)); // throws
423
429
 
424
430
  ### Concrete matcher
425
431
 
426
- You can set the matcher that will be used in expectations with concrete values e.g. `42` or `{ foo: "bar" }`. Passing in a [matcher argument](#argument-matchers) will always take priority.
432
+ You can configure the [matcher](#argument-matchers) that will be used in expectations with concrete values e.g. `42` or `{ foo: "bar" }`. This matcher can always be overwritten inside an expectation with another matcher.
427
433
 
428
434
  ```typescript
429
435
  import { mock, when, It } from 'strong-mock';
430
436
 
431
437
  // Use strict equality instead of deep equality.
432
- const fn = mock<(x: number[]) => boolean>({
438
+ const fn = mock<(x: number[], y: string) => boolean>({
433
439
  concreteMatcher: It.is
434
440
  });
435
- when(() => fn([1, 2, 3])).thenReturn(true);
441
+ when(() => fn([1, 2, 3], 'foo')).thenReturn(true);
442
+
443
+ fn([1, 2, 3], 'foo'); // throws because different array instances
436
444
 
437
- fn([1, 2, 3]); // throws because different array instances
445
+ const arr = [1, 2, 3];
446
+ // The matcher will only apply to non-matcher arguments.
447
+ when(() => fn(arr, It.isString())).thenReturn(true);
448
+ console.log(fn(arr, 'any string')); // true
438
449
  ```
439
450
 
440
451
  ## FAQ
@@ -498,7 +509,7 @@ console.log(foo2.baz); // undefined
498
509
  Use the `It.deepEquals` matcher explicitly inside `when` and pass `{ strict: false }`:
499
510
 
500
511
  ```ts
501
- const fn = mock<(x: { foo: string }) => boolean>();
512
+ const fn = mock<(x: { foo: string, bar?: string }) => boolean>();
502
513
 
503
514
  when(() => fn(
504
515
  It.deepEquals({ foo: "bar" }, { strict: false }))
@@ -1,5 +1,5 @@
1
1
  import type { Matcher, TypeMatcher } from './matcher';
2
- declare type DeepPartial<T> = T extends object ? {
2
+ type DeepPartial<T> = T extends object ? {
3
3
  [K in keyof T]?: DeepPartial<T[K]>;
4
4
  } : T;
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  export declare const MATCHER_SYMBOL: unique symbol;
2
- export declare type Matcher = {
2
+ export type Matcher = {
3
3
  /**
4
4
  * Will be called with a value to match against.
5
5
  */
@@ -14,7 +14,7 @@ export declare type Matcher = {
14
14
  * This takes the shape of T to satisfy call sites, but strong-mock will only
15
15
  * care about the matcher type.
16
16
  */
17
- export declare type TypeMatcher<T> = T & Matcher;
17
+ export type TypeMatcher<T> = T & Matcher;
18
18
  /**
19
19
  * Used to test if an expectation on an argument is a custom matcher.
20
20
  */
@@ -1,6 +1,6 @@
1
1
  import type { Property } from '../../proxy';
2
2
  import type { Expectation } from '../expectation';
3
- export declare type Call = {
3
+ export type Call = {
4
4
  arguments: any[] | undefined;
5
5
  };
6
6
  /**
@@ -15,8 +15,8 @@ export declare type Call = {
15
15
  * ]
16
16
  * }
17
17
  */
18
- export declare type CallMap = Map<Property, Call[]>;
19
- export declare type CallStats = {
18
+ export type CallMap = Map<Property, Call[]>;
19
+ export type CallStats = {
20
20
  /**
21
21
  * Calls that matched existing expectations.
22
22
  */
@@ -2,7 +2,7 @@ import { UnexpectedProperty } from '../../mock/options';
2
2
  import type { Property } from '../../proxy';
3
3
  import type { Expectation } from '../expectation';
4
4
  import type { CallMap, ExpectationRepository } from './expectation-repository';
5
- declare type CountableExpectation = {
5
+ type CountableExpectation = {
6
6
  expectation: Expectation;
7
7
  matchCount: number;
8
8
  };
@@ -1,4 +1,4 @@
1
- export declare type ReturnValue = {
1
+ export type ReturnValue = {
2
2
  value: any;
3
3
  isPromise?: boolean;
4
4
  isError?: boolean;
package/dist/index.js CHANGED
@@ -295,6 +295,11 @@ class FlexibleRepository {
295
295
  case Symbol.toStringTag:
296
296
  case 'name':
297
297
  return 'mock';
298
+ // Promise.resolve() tries to see if it's a "thenable".
299
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#thenables
300
+
301
+ case 'then':
302
+ return undefined;
298
303
  // pretty-format
299
304
 
300
305
  case '$$typeof':
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/expectation/matcher.ts","../src/expectation/expectation.ts","../src/print.ts","../src/errors.ts","../src/mock/options.ts","../src/expectation/repository/return-value.ts","../src/expectation/repository/flexible-repository.ts","../src/expectation/strong-expectation.ts","../src/when/pending-expectation.ts","../src/expectation/it.ts","../src/mock/defaults.ts","../src/mock/map.ts","../src/proxy.ts","../src/mock/stub.ts","../src/mock/mock.ts","../src/return/invocation-count.ts","../src/return/returns.ts","../src/when/when.ts","../src/verify/reset.ts","../src/verify/verify.ts"],"sourcesContent":["export const MATCHER_SYMBOL = Symbol('matcher');\n\nexport type Matcher = {\n /**\n * Will be called with a value to match against.\n */\n matches: (arg: any) => boolean;\n\n [MATCHER_SYMBOL]: boolean;\n\n /**\n * Used by `pretty-format`.\n */\n toJSON(): string;\n};\n\n/**\n * This takes the shape of T to satisfy call sites, but strong-mock will only\n * care about the matcher type.\n */\nexport type TypeMatcher<T> = T & Matcher;\n\n/**\n * Used to test if an expectation on an argument is a custom matcher.\n */\nexport function isMatcher(f: unknown): f is Matcher {\n return !!(f && (<Matcher>f)[MATCHER_SYMBOL]);\n}\n","import type { Property } from '../proxy';\nimport type { Matcher } from './matcher';\nimport type { ReturnValue } from './repository/return-value';\n\n/**\n * Compare received arguments against matchers.\n */\nexport interface Expectation {\n property: Property;\n\n /**\n * `undefined` means this is a property expectation.\n * `[]` means this is a function call with no arguments.\n */\n args: Matcher[] | undefined;\n\n returnValue: ReturnValue;\n\n min: number;\n\n max: number;\n\n /**\n * How many times should this expectation match?\n */\n setInvocationCount(min: number, max: number): void;\n\n matches(args: any[] | undefined): boolean;\n\n /**\n * Used by `pretty-format`.\n */\n toJSON(): string;\n}\n\n/**\n * Special symbol denoting the call of a function.\n */\nexport const ApplyProp = Symbol('apply');\n","import { EXPECTED_COLOR, printExpected } from 'jest-matcher-utils';\nimport type { Expectation } from './expectation/expectation';\nimport { ApplyProp } from './expectation/expectation';\nimport { isMatcher } from './expectation/matcher';\nimport type { ReturnValue } from './expectation/repository/return-value';\nimport type { Property } from './proxy';\n\nexport const printProperty = (property: Property) => {\n if (property === ApplyProp) {\n return '';\n }\n\n if (typeof property === 'symbol') {\n return `[${property.toString()}]`;\n }\n\n return `.${property}`;\n};\n\nexport const printArg = (arg: unknown): string =>\n // Call toJSON on matchers directly to avoid wrapping them in quotes.\n isMatcher(arg) ? arg.toJSON() : printExpected(arg);\n\nexport const printCall = (property: Property, args: any[]) => {\n const prettyArgs = args.map((arg) => printArg(arg)).join(', ');\n const prettyProperty = printProperty(property);\n\n return `${prettyProperty}(${prettyArgs})`;\n};\n\nexport const printReturns = (\n { isError, isPromise, value }: ReturnValue,\n min: number,\n max: number\n) => {\n let thenPrefix = '';\n\n if (isPromise) {\n if (isError) {\n thenPrefix += 'thenReject';\n } else {\n thenPrefix += 'thenResolve';\n }\n } else if (isError) {\n thenPrefix += 'thenThrow';\n } else {\n thenPrefix += 'thenReturn';\n }\n\n return `.${thenPrefix}(${printExpected(value)}).between(${min}, ${max})`;\n};\n\nexport const printWhen = (property: Property, args: any[] | undefined) => {\n if (args) {\n return `when(() => ${EXPECTED_COLOR(`mock${printCall(property, args)}`)})`;\n }\n\n return `when(() => ${EXPECTED_COLOR(`mock${printProperty(property)}`)})`;\n};\n\nexport const printExpectation = (\n property: Property,\n args: any[] | undefined,\n returnValue: ReturnValue,\n min: number,\n max: number\n) => `${printWhen(property, args)}${printReturns(returnValue, min, max)}`;\n\nexport const printRemainingExpectations = (expectations: Expectation[]) =>\n expectations.length\n ? `Remaining unmet expectations:\n - ${expectations.map((e) => e.toJSON()).join('\\n - ')}`\n : 'There are no remaining unmet expectations.';\n","import { EXPECTED_COLOR } from 'jest-matcher-utils';\nimport type { Expectation } from './expectation/expectation';\nimport type { CallMap } from './expectation/repository/expectation-repository';\nimport { printCall, printProperty, printRemainingExpectations } from './print';\nimport type { Property } from './proxy';\nimport type { PendingExpectation } from './when/pending-expectation';\n\nexport class UnfinishedExpectation extends Error {\n constructor(pendingExpectation: PendingExpectation) {\n super(`There is an unfinished pending expectation:\n\n${pendingExpectation.toJSON()}\n\nPlease finish it by setting a return value even if the value\nis undefined.`);\n }\n}\n\nexport class MissingWhen extends Error {\n constructor() {\n super(`You tried setting a return value without an expectation.\n\nEvery call to set a return value must be preceded by an expectation.`);\n }\n}\n\nexport class UnexpectedAccess extends Error {\n constructor(property: Property, expectations: Expectation[]) {\n super(`Didn't expect ${EXPECTED_COLOR(\n `mock${printProperty(property)}`\n )} to be accessed.\n\nIf you expect this property to be accessed then please\nset an expectation for it.\n\n${printRemainingExpectations(expectations)}`);\n }\n}\n\nexport class UnexpectedCall extends Error {\n constructor(property: Property, args: any[], expectations: Expectation[]) {\n super(`Didn't expect ${EXPECTED_COLOR(\n `mock${printCall(property, args)}`\n )} to be called.\n\n${printRemainingExpectations(expectations)}`);\n }\n}\n\nexport class NotAMock extends Error {\n constructor() {\n super(`We couldn't find the mock.\n\nMake sure you're passing in an actual mock.`);\n }\n}\n\nexport class UnmetExpectations extends Error {\n constructor(expectations: Expectation[]) {\n super(`There are unmet expectations:\n\n - ${expectations.map((e) => e.toJSON()).join('\\n - ')}`);\n }\n}\n\n/**\n * Merge property accesses and method calls for the same property\n * into a single call.\n *\n * @example\n * mergeCalls({ foo: [{ arguments: undefined }, { arguments: [1, 2, 3] }] }\n * // returns { foo: [{ arguments: [1, 2, 3] } }\n */\nconst mergeCalls = (callMap: CallMap): CallMap =>\n new Map(\n Array.from(callMap.entries()).map(([property, calls]) => {\n const hasMethodCalls = calls.some((call) => call.arguments);\n const hasPropertyAccesses = calls.some((call) => !call.arguments);\n\n if (hasMethodCalls && hasPropertyAccesses) {\n return [property, calls.filter((call) => call.arguments)];\n }\n\n return [property, calls];\n })\n );\n\nexport class UnexpectedCalls extends Error {\n constructor(unexpectedCalls: CallMap, expectations: Expectation[]) {\n const printedCalls = Array.from(mergeCalls(unexpectedCalls).entries())\n .map(([property, calls]) =>\n calls\n .map((call) =>\n call.arguments\n ? EXPECTED_COLOR(`mock${printCall(property, call.arguments)}`)\n : EXPECTED_COLOR(`mock${printProperty(property)}`)\n )\n .join('\\n - ')\n )\n .join('\\n - ');\n\n super(`The following calls were unexpected:\n\n - ${printedCalls}\n\n${printRemainingExpectations(expectations)}`);\n }\n}\n\nexport class NestedWhen extends Error {\n constructor(parentProp: Property, childProp: Property) {\n const snippet = `\nconst parentMock = mock<T1>();\nconst childMock = mock<T2>();\n\nwhen(() => childMock${printProperty(childProp)}).thenReturn(...);\nwhen(() => parentMock${printProperty(parentProp)}).thenReturn(childMock)\n`;\n\n super(\n `Setting an expectation on a nested property is not supported.\n\nYou can return an object directly when the first property is accessed,\nor you can even return a separate mock:\n${snippet}`\n );\n }\n}\n","import type { Matcher } from '../expectation/matcher';\n\nexport type ConcreteMatcher = <T>(expected: T) => Matcher;\n\nexport enum UnexpectedProperty {\n /**\n * Throw an error immediately.\n *\n * @example\n * // Will throw \"Didn't expect foo to be accessed\".\n * const { foo } = service;\n *\n * // Will throw \"Didn't expect foo to be accessed\",\n * // without printing the arguments.\n * foo(42);\n */\n THROW,\n\n /**\n * Return a function that will throw if called. This can be useful if your\n * code destructures a function but never calls it.\n *\n * It will also improve error messages for unexpected calls because arguments\n * will be captured instead of throwing immediately on the property access.\n *\n * The function will be returned even if the property is not supposed to be a\n * function. This could cause weird behavior at runtime, when your code expects\n * e.g. a number and gets a function instead.\n *\n * @example\n * // This will NOT throw.\n * const { foo } = service;\n *\n * // This will NOT throw, and might produce unexpected results.\n * foo > 0\n *\n * // Will throw \"Didn't expect foo(42) to be called\".\n * foo(42);\n */\n CALL_THROW,\n}\n\nexport interface MockOptions {\n /**\n * Controls what should be returned for a property with no expectations.\n *\n * A property with no expectations is a property that has no `when`\n * expectations set on it. It can also be a property that ran out of `when`\n * expectations.\n *\n * The default is to return a function that will throw when called.\n *\n * @example\n * const foo = mock<{ bar: () => number }>();\n * foo.bar() // unexpected property access\n *\n * @example\n * const foo = mock<{ bar: () => number }>();\n * when(() => foo.bar()).thenReturn(42);\n * foo.bar() === 42\n * foo.bar() // unexpected property access\n */\n unexpectedProperty?: UnexpectedProperty;\n\n /**\n * If `true`, the number of received arguments in a function/method call has to\n * match the number of arguments set in the expectation.\n *\n * If `false`, extra parameters are considered optional and checked by the\n * TypeScript compiler instead.\n *\n * You may want to set this to `true` if you're not using TypeScript,\n * or if you want to be extra strict.\n *\n * @example\n * const fn = mock<(value?: number) => number>({ exactParams: true });\n * when(() => fn()).thenReturn(42);\n *\n * fn(100) // throws with exactParams, returns 42 without\n */\n exactParams?: boolean;\n\n /**\n * The matcher that will be used when one isn't specified explicitly.\n *\n * The most common use case is replacing the default {@link It.deepEquals}\n * matcher with {@link It.is}, but you can also use {@link It.matches} to\n * create a custom matcher.\n *\n * @param expected The concrete expected value received from the\n * {@link when} expectation.\n *\n * @example\n * const fn = mock<(value: number[]) => boolean>({\n * concreteMatcher: It.is\n * });\n *\n * const expected = [1, 2, 3];\n * when(() => fn(expected).thenReturn(true);\n *\n * fn([1, 2, 3]); // throws because different array instance\n * fn(expected); // OK\n */\n concreteMatcher?: ConcreteMatcher;\n}\n","export type ReturnValue = {\n value: any;\n isPromise?: boolean;\n isError?: boolean;\n};\n\n/**\n * Unbox the expectation's return value.\n *\n * If the value is an error then throw it.\n *\n * If the value is a promise then resolve/reject it.\n */\nexport const unboxReturnValue = ({\n isError,\n isPromise,\n value,\n}: ReturnValue) => {\n if (isError) {\n if (value instanceof Error) {\n if (isPromise) {\n return Promise.reject(value);\n }\n throw value;\n }\n\n if (isPromise) {\n return Promise.reject(new Error(value));\n }\n\n throw new Error(value);\n }\n\n if (isPromise) {\n return Promise.resolve(value);\n }\n\n return value;\n};\n","import { UnexpectedAccess, UnexpectedCall } from '../../errors';\nimport { UnexpectedProperty } from '../../mock/options';\nimport type { Property } from '../../proxy';\nimport type { Expectation } from '../expectation';\nimport { ApplyProp } from '../expectation';\nimport { MATCHER_SYMBOL } from '../matcher';\nimport type { CallMap, ExpectationRepository } from './expectation-repository';\nimport { unboxReturnValue } from './return-value';\n\ntype CountableExpectation = {\n expectation: Expectation;\n matchCount: number;\n};\n\n/**\n * An expectation repository with a configurable behavior for\n * unexpected property access.\n */\nexport class FlexibleRepository implements ExpectationRepository {\n constructor(\n private unexpectedProperty: UnexpectedProperty = UnexpectedProperty.THROW\n ) {}\n\n protected readonly expectations = new Map<Property, CountableExpectation[]>();\n\n private readonly expectedCallStats: CallMap = new Map();\n\n private readonly unexpectedCallStats: CallMap = new Map();\n\n add(expectation: Expectation): void {\n const { property } = expectation;\n\n const expectations = this.expectations.get(property) || [];\n\n this.expectations.set(property, [\n ...expectations,\n {\n expectation,\n matchCount: 0,\n },\n ]);\n }\n\n clear(): void {\n this.expectations.clear();\n this.expectedCallStats.clear();\n this.unexpectedCallStats.clear();\n }\n\n apply = (args: unknown[]): unknown => this.get(ApplyProp)(...args);\n\n // TODO: this returns any, but the interface returns unknown\n // unknown causes errors in apply tests, and any causes bugs in bootstrapped SM\n get(property: Property): any {\n const expectations = this.expectations.get(property);\n\n if (expectations && expectations.length) {\n return this.handlePropertyWithMatchingExpectations(\n property,\n expectations\n );\n }\n\n return this.handlePropertyWithNoExpectations(property);\n }\n\n private handlePropertyWithMatchingExpectations = (\n property: Property,\n expectations: CountableExpectation[]\n ) => {\n // Avoid recording call stats for function calls, since the property is an\n // internal detail.\n if (property !== ApplyProp) {\n // An unexpected call could still happen later, if the property returns a\n // function that will not match the given args.\n this.recordExpected(property, undefined);\n }\n\n const propertyExpectation = expectations.find((e) =>\n e.expectation.matches(undefined)\n );\n\n if (propertyExpectation) {\n this.countAndConsume(propertyExpectation);\n\n return unboxReturnValue(propertyExpectation.expectation.returnValue);\n }\n\n return (...args: any[]) => {\n const callExpectation = expectations.find((e) =>\n e.expectation.matches(args)\n );\n\n if (callExpectation) {\n this.recordExpected(property, args);\n this.countAndConsume(callExpectation);\n\n return unboxReturnValue(callExpectation.expectation.returnValue);\n }\n\n return this.getValueForUnexpectedCall(property, args);\n };\n };\n\n private handlePropertyWithNoExpectations = (property: Property) => {\n switch (property) {\n case 'toString':\n return () => 'mock';\n case '@@toStringTag':\n case Symbol.toStringTag:\n case 'name':\n return 'mock';\n\n // pretty-format\n case '$$typeof':\n case 'constructor':\n case '@@__IMMUTABLE_ITERABLE__@@':\n case '@@__IMMUTABLE_RECORD__@@':\n return null;\n\n case MATCHER_SYMBOL:\n return false;\n\n case ApplyProp:\n return (...args: any[]) =>\n this.getValueForUnexpectedCall(property, args);\n default:\n return this.getValueForUnexpectedAccess(property);\n }\n };\n\n getAllProperties(): Property[] {\n return Array.from(this.expectations.keys());\n }\n\n getCallStats() {\n return {\n expected: this.expectedCallStats,\n unexpected: this.unexpectedCallStats,\n };\n }\n\n getUnmet(): Expectation[] {\n return ([] as Expectation[]).concat(\n ...Array.from(this.expectations.values()).map((expectations) =>\n expectations\n .filter((e) => e.expectation.min > e.matchCount)\n .map((e) => e.expectation)\n )\n );\n }\n\n private recordExpected(property: Property, args: any[] | undefined) {\n const calls = this.expectedCallStats.get(property) || [];\n\n this.expectedCallStats.set(property, [...calls, { arguments: args }]);\n }\n\n private recordUnexpected(property: Property, args: any[] | undefined) {\n const calls = this.unexpectedCallStats.get(property) || [];\n\n this.unexpectedCallStats.set(property, [...calls, { arguments: args }]);\n }\n\n private countAndConsume(expectation: CountableExpectation) {\n // eslint-disable-next-line no-param-reassign\n expectation.matchCount++;\n\n this.consumeExpectation(expectation);\n }\n\n private consumeExpectation(expectation: CountableExpectation): void {\n const { property, max } = expectation.expectation;\n\n const expectations = this.expectations.get(property)!;\n\n if (expectation.matchCount === max) {\n this.expectations.set(\n property,\n expectations.filter((e) => e !== expectation)\n );\n }\n }\n\n private getValueForUnexpectedCall(property: Property, args: any[]): never {\n this.recordUnexpected(property, args);\n\n throw new UnexpectedCall(property, args, this.getUnmet());\n }\n\n private getValueForUnexpectedAccess(property: Property): unknown {\n if (this.unexpectedProperty === UnexpectedProperty.THROW) {\n this.recordUnexpected(property, undefined);\n\n throw new UnexpectedAccess(property, this.getUnmet());\n }\n\n return (...args: unknown[]) => {\n this.recordUnexpected(property, args);\n\n throw new UnexpectedCall(property, args, this.getUnmet());\n };\n }\n}\n","import { printExpectation } from '../print';\nimport type { Property } from '../proxy';\nimport type { Expectation } from './expectation';\nimport type { Matcher } from './matcher';\nimport type { ReturnValue } from './repository/return-value';\n\n/**\n * Matches a call with more parameters than expected because it is assumed the\n * compiler will check that those parameters are optional.\n *\n * @example\n * new StrongExpectation(\n * 'bar',\n * deepEquals([1, 2, 3]),\n * 23\n * ).matches('bar', [1, 2, 3]) === true;\n */\nexport class StrongExpectation implements Expectation {\n private matched = 0;\n\n public min: number = 1;\n\n public max: number = 1;\n\n constructor(\n public property: Property,\n public args: Matcher[] | undefined,\n public returnValue: ReturnValue,\n private exactParams: boolean = false\n ) {}\n\n setInvocationCount(min: number, max = 1) {\n this.min = min;\n this.max = max;\n }\n\n matches(args: any[] | undefined): boolean {\n if (!this.matchesArgs(args)) {\n return false;\n }\n\n this.matched++;\n\n return this.max === 0 || this.matched <= this.max;\n }\n\n isUnmet(): boolean {\n return this.matched < this.min;\n }\n\n private matchesArgs(received: any[] | undefined) {\n if (this.args === undefined) {\n return !received;\n }\n\n if (!received) {\n return false;\n }\n\n if (this.exactParams) {\n if (this.args.length !== received.length) {\n return false;\n }\n }\n\n return this.args.every((arg, i) => arg.matches(received[i]));\n }\n\n toJSON() {\n return printExpectation(\n this.property,\n this.args,\n this.returnValue,\n this.min,\n this.max\n );\n }\n}\n","import { MissingWhen, UnfinishedExpectation } from '../errors';\nimport type { Expectation } from '../expectation/expectation';\nimport type { ReturnValue } from '../expectation/repository/return-value';\nimport type { ConcreteMatcher } from '../mock/options';\nimport { printWhen } from '../print';\nimport type { Property } from '../proxy';\n\n/**\n * An expectation has to be built incrementally, starting first with the property\n * being accessed inside {@link createStub}, then any arguments passed to it, and ending\n * it with the returned value from {@link createReturns}.\n */\nexport interface PendingExpectation {\n setProperty(prop: Property): void;\n\n setArgs(args: any[] | undefined): void;\n\n finish(returnValue: ReturnValue): Expectation;\n\n /**\n * Used by `pretty-format`.\n */\n toJSON(): string;\n}\n\nexport type ExpectationFactory = (\n property: Property,\n args: any[] | undefined,\n returnValue: ReturnValue,\n concreteMatcher: ConcreteMatcher,\n exactParams: boolean\n) => Expectation;\n\nexport class PendingExpectationWithFactory implements PendingExpectation {\n private args: any[] | undefined;\n\n private property: Property | undefined;\n\n constructor(\n private createExpectation: ExpectationFactory,\n private concreteMatcher: ConcreteMatcher,\n private exactParams: boolean\n ) {}\n\n setProperty(value: Property) {\n if (this.property) {\n throw new UnfinishedExpectation(this);\n }\n\n this.property = value;\n }\n\n setArgs(value: any[] | undefined) {\n this.args = value;\n }\n\n finish(returnValue: ReturnValue): Expectation {\n if (!this.property) {\n throw new MissingWhen();\n }\n\n const expectation = this.createExpectation(\n this.property,\n this.args,\n returnValue,\n this.concreteMatcher,\n this.exactParams\n );\n\n this.property = undefined;\n this.args = undefined;\n\n return expectation;\n }\n\n toJSON() {\n return printWhen(this.property!, this.args);\n }\n}\n","import { printExpected } from 'jest-matcher-utils';\nimport {\n isEqual,\n isMatchWith,\n isObjectLike,\n isUndefined,\n omitBy,\n} from 'lodash';\nimport { printArg } from '../print';\nimport type { Matcher, TypeMatcher } from './matcher';\nimport { isMatcher, MATCHER_SYMBOL } from './matcher';\n\n/**\n * Match a custom predicate.\n *\n * @param cb Will receive the value and returns whether it matches.\n * @param toJSON An optional function that should return a string that will be\n * used when the matcher needs to be printed in an error message. By default,\n * it stringifies `cb`.\n *\n * @example\n * const fn = mock<(x: number) => number>();\n * when(() => fn(It.matches(x => x >= 0))).returns(42);\n *\n * fn(2) === 42\n * fn(-1) // throws\n */\nconst matches = <T>(\n cb: (actual: T) => boolean,\n { toJSON = () => `matches(${cb.toString()})` }: { toJSON?: () => string } = {}\n): TypeMatcher<T> => {\n const matcher: Matcher = {\n [MATCHER_SYMBOL]: true,\n matches: (arg: T) => cb(arg),\n toJSON,\n };\n\n return matcher as any;\n};\n\nconst removeUndefined = (object: any): any => {\n if (Array.isArray(object)) {\n return object.map((x) => removeUndefined(x));\n }\n\n if (!isObjectLike(object)) {\n return object;\n }\n\n return omitBy(object, isUndefined);\n};\n\n/**\n * Compare values using deep equality.\n *\n * @param expected\n * @param strict By default, this matcher will treat a missing key in an object\n * and a key with the value `undefined` as not equal. It will also consider\n * non `Object` instances with different constructors as not equal. Setting\n * this to `false` will consider the objects in both cases as equal.\n *\n * @see It.is A matcher that uses strict equality.\n */\nconst deepEquals = <T>(\n expected: T,\n { strict = true }: { strict?: boolean } = {}\n): TypeMatcher<T> =>\n matches(\n (actual) => {\n if (strict) {\n return isEqual(actual, expected);\n }\n\n return isEqual(removeUndefined(actual), removeUndefined(expected));\n },\n { toJSON: () => printArg(expected) }\n );\n\n/**\n * Compare values using `Object.is`.\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\n *\n * @see It.deepEquals A matcher that uses deep equality.\n */\nconst is = <T = unknown>(expected: T): TypeMatcher<T> =>\n matches((actual) => Object.is(actual, expected), {\n toJSON: () => `${printExpected(expected)}`,\n });\n\n/**\n * Match any value, including `undefined` and `null`.\n *\n * @example\n * const fn = mock<(x: number, y: string) => number>();\n * when(() => fn(It.isAny(), It.isAny())).thenReturn(1);\n *\n * fn(23, 'foobar') === 1\n */\nconst isAny = (): TypeMatcher<any> =>\n matches(() => true, { toJSON: () => 'anything' });\n\ntype DeepPartial<T> = T extends object\n ? { [K in keyof T]?: DeepPartial<T[K]> }\n : T;\n\n/**\n * Recursively match an object.\n *\n * Supports nested matcher.\n *\n * @param partial An optional subset of the expected objected.\n *\n * @example\n * const fn = mock<(foo: { x: number, y: number }) => number>();\n * when(() => fn(It.isObject({ x: 23 }))).returns(42);\n *\n * fn({ x: 100, y: 200 }) // throws\n * fn({ x: 23, y: 200 }) // returns 42\n *\n * @example\n * It.isObject({ foo: It.isString() })\n */\nconst isObject = <T extends object, K extends DeepPartial<T>>(\n partial?: K\n): TypeMatcher<T> =>\n matches(\n (actual) =>\n isMatchWith(actual, partial || {}, (argValue, partialValue) => {\n if (isMatcher(partialValue)) {\n return partialValue.matches(argValue);\n }\n\n // Let lodash handle it otherwise.\n return undefined;\n }),\n { toJSON: () => (partial ? `object(${printExpected(partial)})` : 'object') }\n );\n\n/**\n * Match any number.\n *\n * @example\n * const fn = mock<(x: number) => number>();\n * when(() => fn(It.isNumber())).returns(42);\n *\n * fn(20.5) === 42\n * fn(NaN) // throws\n */\nconst isNumber = (): TypeMatcher<number> =>\n matches((actual) => typeof actual === 'number' && !Number.isNaN(actual), {\n toJSON: () => 'number',\n });\n\n/**\n * Match a string, potentially by a pattern.\n *\n * @param matching The string has to match this RegExp.\n * @param containing The string has to contain this substring.\n *\n * @example\n * const fn = mock<(x: string, y: string) => number>();\n * when(() => fn(It.isString(), It.isString({ containing: 'bar' }))).returns(42);\n *\n * fn('foo', 'baz') // throws\n * fn('foo', 'bar') === 42\n */\nconst isString = ({\n matching,\n containing,\n}: { matching?: RegExp; containing?: string } = {}): TypeMatcher<string> => {\n if (matching && containing) {\n throw new Error('You can only pass `matching` or `containing`, not both.');\n }\n\n return matches(\n (actual) => {\n if (typeof actual !== 'string') {\n return false;\n }\n\n if (containing) {\n return actual.indexOf(containing) !== -1;\n }\n\n return matching?.test(actual) ?? true;\n },\n {\n toJSON: () =>\n containing || matching\n ? `string(${printExpected(containing || matching)})`\n : 'string',\n }\n );\n};\n\n/**\n * Match an array.\n *\n * Supports nested matchers.\n *\n * @param containing If given, the matched array has to contain ALL of these\n * elements in ANY order.\n *\n * @example\n * const fn = mock<(arr: number[]) => number>();\n * when(() => fn(It.isArray())).thenReturn(1);\n * when(() => fn(It.isArray([2, 3]))).thenReturn(2);\n *\n * fn({ length: 1, 0: 42 }) // throws\n * fn([]) === 1\n * fn([3, 2, 1]) === 2\n *\n * @example\n * It.isArray([It.isString({ containing: 'foobar' })])\n */\nconst isArray = <T extends any[]>(containing?: T): TypeMatcher<T> =>\n matches(\n (actual) => {\n if (!Array.isArray(actual)) {\n return false;\n }\n\n if (!containing) {\n return true;\n }\n\n return containing.every(\n (x) =>\n actual.find((y) => {\n if (isMatcher(x)) {\n return x.matches(y);\n }\n\n return deepEquals(x).matches(y);\n }) !== undefined\n );\n },\n {\n toJSON: () =>\n containing ? `array(${printExpected(containing)})` : 'array',\n }\n );\n\n/**\n * Matches anything and stores the received value.\n *\n * This should not be needed for most cases, but can be useful if you need\n * access to a complex argument outside the expectation e.g. to test a\n * callback.\n *\n * @param name If given, this name will be printed in error messages.\n *\n * @example\n * const fn = mock<(cb: (value: number) => number) => void>();\n * const matcher = It.willCapture();\n * when(() => fn(matcher)).thenReturn();\n *\n * fn(x => x + 1);\n * matcher.value?.(3) === 4\n */\nconst willCapture = <T = unknown>(\n name?: string\n): TypeMatcher<T> & { value: T | undefined } => {\n let capturedValue: T | undefined;\n\n const matcher: Matcher & { value: T | undefined } = {\n [MATCHER_SYMBOL]: true,\n matches: (actual) => {\n capturedValue = actual;\n\n return true;\n },\n toJSON: () => name ?? 'captures',\n get value(): T | undefined {\n return capturedValue;\n },\n };\n\n return matcher as any;\n};\n\n/**\n * Contains argument matchers that can be used to ignore arguments in an\n * expectation or to match complex arguments.\n */\nexport const It = {\n matches,\n deepEquals,\n is,\n isAny,\n isObject,\n isNumber,\n isString,\n isArray,\n willCapture,\n};\n","import { It } from '../expectation/it';\nimport type { MockOptions } from './options';\nimport { UnexpectedProperty } from './options';\n\nexport type StrongMockDefaults = Required<MockOptions>;\n\nconst defaults: StrongMockDefaults = {\n concreteMatcher: It.deepEquals,\n unexpectedProperty: UnexpectedProperty.CALL_THROW,\n exactParams: false,\n};\n\nexport let currentDefaults: StrongMockDefaults = defaults;\n\n/**\n * Override strong-mock's defaults.\n *\n * @param newDefaults These will be applied to the library defaults. Multiple\n * calls don't stack e.g. calling this with `{}` will clear any previously\n * applied defaults.\n */\nexport const setDefaults = (newDefaults: MockOptions): void => {\n currentDefaults = {\n ...defaults,\n ...newDefaults,\n };\n};\n","import { NotAMock } from '../errors';\nimport type { ExpectationRepository } from '../expectation/repository/expectation-repository';\nimport type { PendingExpectation } from '../when/pending-expectation';\nimport type { StrongMockDefaults } from './defaults';\nimport type { Mock } from './mock';\n\n/**\n * Since `when` doesn't receive the mock subject (because we can't make it\n * consistently return it from `mock()`, `mock.foo` and `mock.bar()`) we need\n * to store a global state for the currently active mock.\n *\n * We also want to throw in the following case:\n *\n * ```\n * when(() => mock()) // forgot returns here\n * when(() => mock()) // should throw\n * ```\n *\n * For that reason we can't just store the currently active mock, but also\n * whether we finished the expectation or not.\n */\nlet activeMock: Mock<any> | undefined;\n\nexport const setActiveMock = (mock: Mock<any>) => {\n activeMock = mock;\n};\n\nexport const clearActiveMock = () => {\n activeMock = undefined;\n};\n\nexport const getActiveMock = (): Mock<any> => activeMock;\n\ntype MockState = {\n repository: ExpectationRepository;\n pendingExpectation: PendingExpectation;\n options: StrongMockDefaults;\n};\n\n/**\n * Store a global map of all mocks created and their state.\n *\n * This is needed because we can't reliably pass the state between `when`\n * and `thenReturn`.\n */\nconst mockMap = new Map<Mock<any>, MockState>();\n\nexport const getMockState = (mock: Mock<any>): MockState => {\n if (mockMap.has(mock)) {\n return mockMap.get(mock)!;\n }\n\n throw new NotAMock();\n};\n\nexport const setMockState = (mock: Mock<any>, state: MockState): void => {\n mockMap.set(mock, state);\n};\n\nexport const getAllMocks = (): [Mock<any>, MockState][] =>\n Array.from(mockMap.entries());\n","import type { Mock } from './mock/mock';\n\nexport type Property = string | symbol;\n\nexport interface ProxyTraps {\n /**\n * Called when accessing any property on an object, except for\n * `.call`, `.apply` and `.bind`.\n */\n property: (property: Property) => unknown;\n\n /**\n * Called when calling a function.\n *\n * @example\n * ```\n * fn(...args)\n * ```\n *\n * @example\n * ```\n * fn.call(this, ...args)\n * ```\n *\n * @example\n * ```\n * fn.apply(this, [...args])\n * ```\n *\n * @example\n * ```\n * Reflect.apply(fn, this, [...args])\n * ```\n */\n apply: (args: any[]) => unknown;\n\n /**\n * Called when getting the proxy's own enumerable keys.\n *\n * @example\n * ```\n * Object.keys(proxy);\n * ```\n *\n * @example\n * ```\n * const foo = { ...proxy };\n * ```\n */\n ownKeys: () => Property[];\n}\n\nexport const createProxy = <T>(traps: ProxyTraps): Mock<T> =>\n // eslint-disable-next-line no-empty-function\n new Proxy(/* istanbul ignore next */ () => {}, {\n get: (target, prop: string | symbol) => {\n if (prop === 'bind') {\n return (thisArg: any, ...args: any[]) =>\n (...moreArgs: any[]) =>\n traps.apply([...args, ...moreArgs]);\n }\n\n if (prop === 'apply') {\n return (thisArg: any, args: any[] | undefined) =>\n traps.apply(args || []);\n }\n\n if (prop === 'call') {\n return (thisArg: any, ...args: any[]) => traps.apply(args);\n }\n\n return traps.property(prop);\n },\n\n apply: (target, thisArg: any, args: any[]) => traps.apply(args),\n\n ownKeys: () => traps.ownKeys(),\n\n getOwnPropertyDescriptor(\n target: () => void,\n prop: string | symbol\n ): PropertyDescriptor | undefined {\n const keys = traps.ownKeys();\n\n if (keys.includes(prop)) {\n return {\n configurable: true,\n enumerable: true,\n };\n }\n\n return undefined;\n },\n }) as unknown as Mock<T>;\n","import { NestedWhen } from '../errors';\nimport { ApplyProp } from '../expectation/expectation';\nimport type { ExpectationRepository } from '../expectation/repository/expectation-repository';\nimport type { Property } from '../proxy';\nimport { createProxy } from '../proxy';\nimport type { PendingExpectation } from '../when/pending-expectation';\nimport { setActiveMock } from './map';\nimport type { Mock } from './mock';\nimport { Mode } from './mock';\n\nexport const createStub = <T>(\n repo: ExpectationRepository,\n pendingExpectation: PendingExpectation,\n getCurrentMode: () => Mode\n): Mock<T> => {\n const stub = createProxy<T>({\n property: (property) => {\n if (getCurrentMode() === Mode.CALL) {\n return repo.get(property);\n }\n\n setActiveMock(stub);\n\n pendingExpectation.setProperty(property);\n\n return createProxy({\n property: (childProp: Property) => {\n throw new NestedWhen(property, childProp);\n },\n apply: (args: any[]) => {\n pendingExpectation.setArgs(args);\n },\n ownKeys: () => {\n throw new Error('Spreading during an expectation is not supported.');\n },\n });\n },\n apply: (args: any[]) => {\n if (getCurrentMode() === Mode.CALL) {\n return repo.apply(args);\n }\n\n setActiveMock(stub);\n\n pendingExpectation.setProperty(ApplyProp);\n pendingExpectation.setArgs(args);\n\n return undefined;\n },\n ownKeys: () => {\n if (getCurrentMode() === Mode.CALL) {\n return repo.getAllProperties();\n }\n\n throw new Error('Spreading during an expectation is not supported.');\n },\n });\n\n return stub;\n};\n","import { isMatcher } from '../expectation/matcher';\nimport { FlexibleRepository } from '../expectation/repository/flexible-repository';\nimport { StrongExpectation } from '../expectation/strong-expectation';\nimport type { ExpectationFactory } from '../when/pending-expectation';\nimport { PendingExpectationWithFactory } from '../when/pending-expectation';\nimport type { StrongMockDefaults } from './defaults';\nimport { currentDefaults } from './defaults';\nimport { setMockState } from './map';\nimport type { MockOptions } from './options';\nimport { createStub } from './stub';\n\nexport type Mock<T> = T;\n\nconst strongExpectationFactory: ExpectationFactory = (\n property,\n args,\n returnValue,\n concreteMatcher,\n exactParams\n) =>\n new StrongExpectation(\n property,\n // Wrap every non-matcher in the default matcher.\n args?.map((arg) => (isMatcher(arg) ? arg : concreteMatcher(arg))),\n returnValue,\n exactParams\n );\n\nexport enum Mode {\n EXPECT,\n CALL,\n}\n\nlet currentMode: Mode = Mode.CALL;\nexport const setMode = (mode: Mode) => {\n currentMode = mode;\n};\nconst getMode = () => currentMode;\n\n/**\n * Create a type safe mock.\n *\n * @see {@link when} Set expectations on the mock using `when`.\n *\n * @param options Configure the options for this specific mock, overriding any\n * defaults that were set with {@link setDefaults}.\n * @param options.unexpectedProperty Controls what happens when an unexpected\n * property is accessed.\n * @param options.concreteMatcher The matcher that will be used when one isn't\n * specified explicitly.\n * @param options.exactParams Controls whether the number of received arguments\n * has to match the expectation.\n *\n * @example\n * const fn = mock<() => number>();\n *\n * when(() => fn()).thenReturn(23);\n *\n * fn() === 23;\n */\nexport const mock = <T>({\n unexpectedProperty,\n concreteMatcher,\n exactParams,\n}: MockOptions = {}): Mock<T> => {\n const options: StrongMockDefaults = {\n unexpectedProperty:\n unexpectedProperty ?? currentDefaults.unexpectedProperty,\n concreteMatcher: concreteMatcher ?? currentDefaults.concreteMatcher,\n exactParams: exactParams ?? currentDefaults.exactParams,\n };\n\n const repository = new FlexibleRepository(options.unexpectedProperty);\n\n const pendingExpectation = new PendingExpectationWithFactory(\n strongExpectationFactory,\n options.concreteMatcher,\n options.exactParams\n );\n\n const stub = createStub<T>(repository, pendingExpectation, getMode);\n\n setMockState(stub, {\n repository,\n pendingExpectation,\n options,\n });\n\n return stub;\n};\n","import type { Expectation } from '../expectation/expectation';\n\nexport interface InvocationCount {\n /**\n * Expect a call to be made at least `min` times and at most `max` times.\n */\n between(min: number, max: number): void;\n\n /**\n * Expect a call to be made exactly `exact` times.\n *\n * Shortcut for `between(exact, exact)`.\n */\n times(exact: number): void;\n\n /**\n * Expect a call to be made any number of times, including never.\n *\n * Shortcut for `between(0, Infinity)`.\n */\n anyTimes(): void;\n\n /**\n * Expect a call to be made at least `min` times.\n *\n * Shortcut for `between(min, Infinity)`.\n */\n atLeast(min: number): void;\n\n /**\n * Expect a call to be made at most `max` times.\n *\n * Shortcut for `between(0, max)`.\n */\n atMost(max: number): void;\n\n /**\n * Expect a call to be made exactly once.\n *\n * Shortcut for `times(1)`.\n */\n once(): void;\n\n /**\n * Expect a call to be made exactly twice.\n *\n * Shortcut for `times(2)`.\n */\n twice(): void;\n}\n\nexport const createInvocationCount = (\n expectation: Expectation\n): InvocationCount => ({\n between(min: number, max: number) {\n expectation.setInvocationCount(min, max);\n },\n\n /* istanbul ignore next */\n times(exact: number) {\n expectation.setInvocationCount(exact, exact);\n },\n\n /* istanbul ignore next */\n anyTimes(): void {\n expectation.setInvocationCount(0, 0);\n },\n\n /* istanbul ignore next */\n atLeast(min: number) {\n expectation.setInvocationCount(min, Infinity);\n },\n\n /* istanbul ignore next */\n atMost(max: number) {\n expectation.setInvocationCount(0, max);\n },\n\n /* istanbul ignore next */\n once() {\n expectation.setInvocationCount(1, 1);\n },\n\n /* istanbul ignore next */\n twice() {\n expectation.setInvocationCount(2, 2);\n },\n /* eslint-enable no-param-reassign, no-multi-assign */\n});\n","import type { ExpectationRepository } from '../expectation/repository/expectation-repository';\nimport type { ReturnValue } from '../expectation/repository/return-value';\nimport type { PendingExpectation } from '../when/pending-expectation';\nimport type { InvocationCount } from './invocation-count';\nimport { createInvocationCount } from './invocation-count';\n\nexport type PromiseStub<R, P> = {\n /**\n * Set the return value for the current call.\n *\n * @param value This needs to be of the same type as the value returned\n * by the call inside `when`.\n *\n * @example\n * when(() => fn()).thenReturn(Promise.resolve(23));\n *\n * @example\n * when(() => fn()).thenReturn(Promise.reject({ foo: 'bar' });\n */\n thenReturn(value: P): InvocationCount;\n\n /**\n * Set the return value for the current call.\n *\n * @param promiseValue This needs to be of the same type as the value inside\n * the promise returned by the `when` callback.\n */\n thenResolve(promiseValue: R): InvocationCount;\n\n /**\n * Make the current call reject with the given error.\n *\n * @param error An `Error` instance. If you want to reject with a non error\n * then use the `thenReturn` method.\n */\n thenReject(error: Error): InvocationCount;\n\n /**\n * Make the current call reject with an error with the given message.\n *\n * @param message Will be wrapped in `new Error()`. If you want to reject\n * with a custom error then pass it here instead of the message. If you\n * want to reject with a non error then use `thenReturn`.\n */\n thenReject(message: string): InvocationCount;\n\n /**\n * Make the current call reject with `new Error()`.\n */\n thenReject(): InvocationCount;\n};\n\nexport type NonPromiseStub<R> = {\n /**\n * Set the return value for the current call.\n *\n * @param returnValue This needs to be of the same type as the value returned\n * by the `when` callback.\n */\n thenReturn(returnValue: R): InvocationCount;\n\n /**\n * Make the current call throw the given error.\n *\n * @param error The error instance. If you want to throw a simple `Error`\n * you can pass just the message.\n */\n thenThrow(error: Error): InvocationCount;\n\n /**\n * Make the current call throw an error with the given message.\n *\n * @param message Will be wrapped in `new Error()`. If you want to throw\n * a custom error pass it here instead of the message.\n */\n thenThrow(message: string): InvocationCount;\n\n /**\n * Make the current call throw `new Error()`.\n */\n thenThrow(): InvocationCount;\n};\n\nconst finishPendingExpectation = (\n returnValue: ReturnValue,\n pendingExpectation: PendingExpectation,\n repo: ExpectationRepository\n) => {\n const finishedExpectation = pendingExpectation.finish(returnValue);\n\n repo.add(finishedExpectation);\n\n return createInvocationCount(finishedExpectation);\n};\n\nconst getError = (errorOrMessage: Error | string | undefined): Error => {\n if (typeof errorOrMessage === 'string') {\n return new Error(errorOrMessage);\n }\n\n if (errorOrMessage instanceof Error) {\n return errorOrMessage;\n }\n\n return new Error();\n};\n\nexport const createReturns = (\n pendingExpectation: PendingExpectation,\n repository: ExpectationRepository\n) => ({\n thenReturn: (returnValue: any): InvocationCount =>\n finishPendingExpectation(\n // This will handle both thenReturn(23) and thenReturn(Promise.resolve(3)).\n { value: returnValue, isError: false, isPromise: false },\n pendingExpectation,\n repository\n ),\n thenThrow: (errorOrMessage?: Error | string): InvocationCount =>\n finishPendingExpectation(\n { value: getError(errorOrMessage), isError: true, isPromise: false },\n pendingExpectation,\n repository\n ),\n thenResolve: (promiseValue: any): InvocationCount =>\n finishPendingExpectation(\n {\n value: promiseValue,\n isError: false,\n isPromise: true,\n },\n pendingExpectation,\n repository\n ),\n\n thenReject: (errorOrMessage?: Error | string): InvocationCount =>\n finishPendingExpectation(\n {\n value: getError(errorOrMessage),\n isError: true,\n isPromise: true,\n },\n pendingExpectation,\n repository\n ),\n});\n","import { getActiveMock, getMockState } from '../mock/map';\nimport { Mode, setMode } from '../mock/mock';\nimport type { NonPromiseStub, PromiseStub } from '../return/returns';\nimport { createReturns } from '../return/returns';\n\ninterface When {\n <R>(expectation: () => Promise<R>): PromiseStub<R, Promise<R>>;\n <R>(expectation: () => R): NonPromiseStub<R>;\n}\n\n/**\n * Set an expectation on a mock.\n *\n * The expectation must be finished by setting a return value, even if the value\n * is `undefined`.\n *\n * If a call happens that was not expected then the mock will throw an error.\n * By default, the call is expected to only be made once. Use the invocation\n * count helpers to expect a call multiple times.\n *\n * @param expectation A callback to set the expectation on your mock. The\n * callback must return the value from the mock to properly infer types.\n *\n * @example\n * const fn = mock<() => void>();\n * when(() => fn()).thenReturn(undefined);\n *\n * @example\n * const fn = mock<() => number>();\n * when(() => fn()).thenReturn(42).atMost(3);\n *\n * @example\n * const fn = mock<(x: number) => Promise<number>();\n * when(() => fn(23)).thenResolve(42);\n */\nexport const when: When = <R>(expectation: () => R) => {\n setMode(Mode.EXPECT);\n expectation();\n setMode(Mode.CALL);\n\n const { pendingExpectation, repository } = getMockState(getActiveMock());\n\n return createReturns(pendingExpectation, repository);\n};\n","import { getAllMocks, getMockState } from '../mock/map';\nimport type { Mock } from '../mock/mock';\n\n/**\n * Remove any remaining expectations on the given mock.\n *\n * @example\n * const fn = mock<() => number>();\n *\n * when(() => fn()).thenReturn(23);\n *\n * reset(fn);\n *\n * fn(); // throws\n */\nexport const reset = (mock: Mock<any>): void => {\n getMockState(mock).repository.clear();\n};\n\n/**\n * Reset all existing mocks.\n *\n * @see reset\n */\nexport const resetAll = (): void => {\n getAllMocks().forEach(([mock]) => {\n reset(mock);\n });\n};\n","import { UnexpectedCalls, UnmetExpectations } from '../errors';\nimport type { ExpectationRepository } from '../expectation/repository/expectation-repository';\nimport { getAllMocks, getMockState } from '../mock/map';\nimport type { Mock } from '../mock/mock';\n\nexport const verifyRepo = (repository: ExpectationRepository) => {\n const unmetExpectations = repository.getUnmet();\n\n if (unmetExpectations.length) {\n throw new UnmetExpectations(unmetExpectations);\n }\n\n const callStats = repository.getCallStats();\n\n if (callStats.unexpected.size) {\n throw new UnexpectedCalls(callStats.unexpected, unmetExpectations);\n }\n};\n\n/**\n * Verify that all expectations on the given mock have been met.\n *\n * @throws Will throw if there are remaining expectations that were set\n * using `when` and that weren't met.\n *\n * @throws Will throw if any unexpected calls happened. Normally those\n * calls throw on their own, but the error might be caught by the code\n * being tested.\n *\n * @example\n * const fn = mock<() => number>();\n *\n * when(() => fn()).thenReturn(23);\n *\n * verify(fn); // throws\n */\nexport const verify = <T>(mock: Mock<T>): void => {\n const { repository } = getMockState(mock);\n\n verifyRepo(repository);\n};\n\n/**\n * Verify all existing mocks.\n *\n * @see verify\n */\nexport const verifyAll = (): void => {\n getAllMocks().forEach(([mock]) => {\n verify(mock);\n });\n};\n"],"names":["MATCHER_SYMBOL","Symbol","isMatcher","f","ApplyProp","printProperty","property","toString","printArg","arg","toJSON","printExpected","printCall","args","prettyArgs","map","join","prettyProperty","printReturns","isError","isPromise","value","min","max","thenPrefix","printWhen","EXPECTED_COLOR","printExpectation","returnValue","printRemainingExpectations","expectations","length","e","UnfinishedExpectation","Error","constructor","pendingExpectation","MissingWhen","UnexpectedAccess","UnexpectedCall","NotAMock","UnmetExpectations","mergeCalls","callMap","Map","Array","from","entries","calls","hasMethodCalls","some","call","arguments","hasPropertyAccesses","filter","UnexpectedCalls","unexpectedCalls","printedCalls","NestedWhen","parentProp","childProp","snippet","UnexpectedProperty","unboxReturnValue","Promise","reject","resolve","FlexibleRepository","unexpectedProperty","THROW","expectedCallStats","unexpectedCallStats","apply","get","handlePropertyWithMatchingExpectations","recordExpected","undefined","propertyExpectation","find","expectation","matches","countAndConsume","callExpectation","getValueForUnexpectedCall","handlePropertyWithNoExpectations","toStringTag","getValueForUnexpectedAccess","add","set","matchCount","clear","getAllProperties","keys","getCallStats","expected","unexpected","getUnmet","concat","values","recordUnexpected","consumeExpectation","StrongExpectation","exactParams","matched","setInvocationCount","matchesArgs","isUnmet","received","every","i","PendingExpectationWithFactory","createExpectation","concreteMatcher","setProperty","setArgs","finish","cb","matcher","removeUndefined","object","isArray","x","isObjectLike","omitBy","isUndefined","deepEquals","strict","actual","isEqual","is","Object","isAny","isObject","partial","isMatchWith","argValue","partialValue","isNumber","Number","isNaN","isString","matching","containing","indexOf","test","y","willCapture","name","capturedValue","It","defaults","CALL_THROW","currentDefaults","setDefaults","newDefaults","activeMock","setActiveMock","mock","getActiveMock","mockMap","getMockState","has","setMockState","state","getAllMocks","createProxy","traps","Proxy","target","prop","thisArg","moreArgs","ownKeys","getOwnPropertyDescriptor","includes","configurable","enumerable","createStub","repo","getCurrentMode","stub","Mode","CALL","strongExpectationFactory","currentMode","setMode","mode","getMode","options","repository","createInvocationCount","between","times","exact","anyTimes","atLeast","Infinity","atMost","once","twice","finishPendingExpectation","finishedExpectation","getError","errorOrMessage","createReturns","thenReturn","thenThrow","thenResolve","promiseValue","thenReject","when","EXPECT","reset","resetAll","forEach","verifyRepo","unmetExpectations","callStats","size","verify","verifyAll"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/expectation/matcher.ts","../src/expectation/expectation.ts","../src/print.ts","../src/errors.ts","../src/mock/options.ts","../src/expectation/repository/return-value.ts","../src/expectation/repository/flexible-repository.ts","../src/expectation/strong-expectation.ts","../src/when/pending-expectation.ts","../src/expectation/it.ts","../src/mock/defaults.ts","../src/mock/map.ts","../src/proxy.ts","../src/mock/stub.ts","../src/mock/mock.ts","../src/return/invocation-count.ts","../src/return/returns.ts","../src/when/when.ts","../src/verify/reset.ts","../src/verify/verify.ts"],"sourcesContent":["export const MATCHER_SYMBOL = Symbol('matcher');\n\nexport type Matcher = {\n /**\n * Will be called with a value to match against.\n */\n matches: (arg: any) => boolean;\n\n [MATCHER_SYMBOL]: boolean;\n\n /**\n * Used by `pretty-format`.\n */\n toJSON(): string;\n};\n\n/**\n * This takes the shape of T to satisfy call sites, but strong-mock will only\n * care about the matcher type.\n */\nexport type TypeMatcher<T> = T & Matcher;\n\n/**\n * Used to test if an expectation on an argument is a custom matcher.\n */\nexport function isMatcher(f: unknown): f is Matcher {\n return !!(f && (<Matcher>f)[MATCHER_SYMBOL]);\n}\n","import type { Property } from '../proxy';\nimport type { Matcher } from './matcher';\nimport type { ReturnValue } from './repository/return-value';\n\n/**\n * Compare received arguments against matchers.\n */\nexport interface Expectation {\n property: Property;\n\n /**\n * `undefined` means this is a property expectation.\n * `[]` means this is a function call with no arguments.\n */\n args: Matcher[] | undefined;\n\n returnValue: ReturnValue;\n\n min: number;\n\n max: number;\n\n /**\n * How many times should this expectation match?\n */\n setInvocationCount(min: number, max: number): void;\n\n matches(args: any[] | undefined): boolean;\n\n /**\n * Used by `pretty-format`.\n */\n toJSON(): string;\n}\n\n/**\n * Special symbol denoting the call of a function.\n */\nexport const ApplyProp = Symbol('apply');\n","import { EXPECTED_COLOR, printExpected } from 'jest-matcher-utils';\nimport type { Expectation } from './expectation/expectation';\nimport { ApplyProp } from './expectation/expectation';\nimport { isMatcher } from './expectation/matcher';\nimport type { ReturnValue } from './expectation/repository/return-value';\nimport type { Property } from './proxy';\n\nexport const printProperty = (property: Property) => {\n if (property === ApplyProp) {\n return '';\n }\n\n if (typeof property === 'symbol') {\n return `[${property.toString()}]`;\n }\n\n return `.${property}`;\n};\n\nexport const printArg = (arg: unknown): string =>\n // Call toJSON on matchers directly to avoid wrapping them in quotes.\n isMatcher(arg) ? arg.toJSON() : printExpected(arg);\n\nexport const printCall = (property: Property, args: any[]) => {\n const prettyArgs = args.map((arg) => printArg(arg)).join(', ');\n const prettyProperty = printProperty(property);\n\n return `${prettyProperty}(${prettyArgs})`;\n};\n\nexport const printReturns = (\n { isError, isPromise, value }: ReturnValue,\n min: number,\n max: number\n) => {\n let thenPrefix = '';\n\n if (isPromise) {\n if (isError) {\n thenPrefix += 'thenReject';\n } else {\n thenPrefix += 'thenResolve';\n }\n } else if (isError) {\n thenPrefix += 'thenThrow';\n } else {\n thenPrefix += 'thenReturn';\n }\n\n return `.${thenPrefix}(${printExpected(value)}).between(${min}, ${max})`;\n};\n\nexport const printWhen = (property: Property, args: any[] | undefined) => {\n if (args) {\n return `when(() => ${EXPECTED_COLOR(`mock${printCall(property, args)}`)})`;\n }\n\n return `when(() => ${EXPECTED_COLOR(`mock${printProperty(property)}`)})`;\n};\n\nexport const printExpectation = (\n property: Property,\n args: any[] | undefined,\n returnValue: ReturnValue,\n min: number,\n max: number\n) => `${printWhen(property, args)}${printReturns(returnValue, min, max)}`;\n\nexport const printRemainingExpectations = (expectations: Expectation[]) =>\n expectations.length\n ? `Remaining unmet expectations:\n - ${expectations.map((e) => e.toJSON()).join('\\n - ')}`\n : 'There are no remaining unmet expectations.';\n","import { EXPECTED_COLOR } from 'jest-matcher-utils';\nimport type { Expectation } from './expectation/expectation';\nimport type { CallMap } from './expectation/repository/expectation-repository';\nimport { printCall, printProperty, printRemainingExpectations } from './print';\nimport type { Property } from './proxy';\nimport type { PendingExpectation } from './when/pending-expectation';\n\nexport class UnfinishedExpectation extends Error {\n constructor(pendingExpectation: PendingExpectation) {\n super(`There is an unfinished pending expectation:\n\n${pendingExpectation.toJSON()}\n\nPlease finish it by setting a return value even if the value\nis undefined.`);\n }\n}\n\nexport class MissingWhen extends Error {\n constructor() {\n super(`You tried setting a return value without an expectation.\n\nEvery call to set a return value must be preceded by an expectation.`);\n }\n}\n\nexport class UnexpectedAccess extends Error {\n constructor(property: Property, expectations: Expectation[]) {\n super(`Didn't expect ${EXPECTED_COLOR(\n `mock${printProperty(property)}`\n )} to be accessed.\n\nIf you expect this property to be accessed then please\nset an expectation for it.\n\n${printRemainingExpectations(expectations)}`);\n }\n}\n\nexport class UnexpectedCall extends Error {\n constructor(property: Property, args: any[], expectations: Expectation[]) {\n super(`Didn't expect ${EXPECTED_COLOR(\n `mock${printCall(property, args)}`\n )} to be called.\n\n${printRemainingExpectations(expectations)}`);\n }\n}\n\nexport class NotAMock extends Error {\n constructor() {\n super(`We couldn't find the mock.\n\nMake sure you're passing in an actual mock.`);\n }\n}\n\nexport class UnmetExpectations extends Error {\n constructor(expectations: Expectation[]) {\n super(`There are unmet expectations:\n\n - ${expectations.map((e) => e.toJSON()).join('\\n - ')}`);\n }\n}\n\n/**\n * Merge property accesses and method calls for the same property\n * into a single call.\n *\n * @example\n * mergeCalls({ foo: [{ arguments: undefined }, { arguments: [1, 2, 3] }] }\n * // returns { foo: [{ arguments: [1, 2, 3] } }\n */\nconst mergeCalls = (callMap: CallMap): CallMap =>\n new Map(\n Array.from(callMap.entries()).map(([property, calls]) => {\n const hasMethodCalls = calls.some((call) => call.arguments);\n const hasPropertyAccesses = calls.some((call) => !call.arguments);\n\n if (hasMethodCalls && hasPropertyAccesses) {\n return [property, calls.filter((call) => call.arguments)];\n }\n\n return [property, calls];\n })\n );\n\nexport class UnexpectedCalls extends Error {\n constructor(unexpectedCalls: CallMap, expectations: Expectation[]) {\n const printedCalls = Array.from(mergeCalls(unexpectedCalls).entries())\n .map(([property, calls]) =>\n calls\n .map((call) =>\n call.arguments\n ? EXPECTED_COLOR(`mock${printCall(property, call.arguments)}`)\n : EXPECTED_COLOR(`mock${printProperty(property)}`)\n )\n .join('\\n - ')\n )\n .join('\\n - ');\n\n super(`The following calls were unexpected:\n\n - ${printedCalls}\n\n${printRemainingExpectations(expectations)}`);\n }\n}\n\nexport class NestedWhen extends Error {\n constructor(parentProp: Property, childProp: Property) {\n const snippet = `\nconst parentMock = mock<T1>();\nconst childMock = mock<T2>();\n\nwhen(() => childMock${printProperty(childProp)}).thenReturn(...);\nwhen(() => parentMock${printProperty(parentProp)}).thenReturn(childMock)\n`;\n\n super(\n `Setting an expectation on a nested property is not supported.\n\nYou can return an object directly when the first property is accessed,\nor you can even return a separate mock:\n${snippet}`\n );\n }\n}\n","import type { Matcher } from '../expectation/matcher';\n\nexport type ConcreteMatcher = <T>(expected: T) => Matcher;\n\nexport enum UnexpectedProperty {\n /**\n * Throw an error immediately.\n *\n * @example\n * // Will throw \"Didn't expect foo to be accessed\".\n * const { foo } = service;\n *\n * // Will throw \"Didn't expect foo to be accessed\",\n * // without printing the arguments.\n * foo(42);\n */\n THROW,\n\n /**\n * Return a function that will throw if called. This can be useful if your\n * code destructures a function but never calls it.\n *\n * It will also improve error messages for unexpected calls because arguments\n * will be captured instead of throwing immediately on the property access.\n *\n * The function will be returned even if the property is not supposed to be a\n * function. This could cause weird behavior at runtime, when your code expects\n * e.g. a number and gets a function instead.\n *\n * @example\n * // This will NOT throw.\n * const { foo } = service;\n *\n * // This will NOT throw, and might produce unexpected results.\n * foo > 0\n *\n * // Will throw \"Didn't expect foo(42) to be called\".\n * foo(42);\n */\n CALL_THROW,\n}\n\nexport interface MockOptions {\n /**\n * Controls what should be returned for a property with no expectations.\n *\n * A property with no expectations is a property that has no `when`\n * expectations set on it. It can also be a property that ran out of `when`\n * expectations.\n *\n * The default is to return a function that will throw when called.\n *\n * @example\n * const foo = mock<{ bar: () => number }>();\n * foo.bar() // unexpected property access\n *\n * @example\n * const foo = mock<{ bar: () => number }>();\n * when(() => foo.bar()).thenReturn(42);\n * foo.bar() === 42\n * foo.bar() // unexpected property access\n */\n unexpectedProperty?: UnexpectedProperty;\n\n /**\n * If `true`, the number of received arguments in a function/method call has to\n * match the number of arguments set in the expectation.\n *\n * If `false`, extra parameters are considered optional and checked by the\n * TypeScript compiler instead.\n *\n * You may want to set this to `true` if you're not using TypeScript,\n * or if you want to be extra strict.\n *\n * @example\n * const fn = mock<(value?: number) => number>({ exactParams: true });\n * when(() => fn()).thenReturn(42);\n *\n * fn(100) // throws with exactParams, returns 42 without\n */\n exactParams?: boolean;\n\n /**\n * The matcher that will be used when one isn't specified explicitly.\n *\n * The most common use case is replacing the default {@link It.deepEquals}\n * matcher with {@link It.is}, but you can also use {@link It.matches} to\n * create a custom matcher.\n *\n * @param expected The concrete expected value received from the\n * {@link when} expectation.\n *\n * @example\n * const fn = mock<(value: number[]) => boolean>({\n * concreteMatcher: It.is\n * });\n *\n * const expected = [1, 2, 3];\n * when(() => fn(expected).thenReturn(true);\n *\n * fn([1, 2, 3]); // throws because different array instance\n * fn(expected); // OK\n */\n concreteMatcher?: ConcreteMatcher;\n}\n","export type ReturnValue = {\n value: any;\n isPromise?: boolean;\n isError?: boolean;\n};\n\n/**\n * Unbox the expectation's return value.\n *\n * If the value is an error then throw it.\n *\n * If the value is a promise then resolve/reject it.\n */\nexport const unboxReturnValue = ({\n isError,\n isPromise,\n value,\n}: ReturnValue) => {\n if (isError) {\n if (value instanceof Error) {\n if (isPromise) {\n return Promise.reject(value);\n }\n throw value;\n }\n\n if (isPromise) {\n return Promise.reject(new Error(value));\n }\n\n throw new Error(value);\n }\n\n if (isPromise) {\n return Promise.resolve(value);\n }\n\n return value;\n};\n","import { UnexpectedAccess, UnexpectedCall } from '../../errors';\nimport { UnexpectedProperty } from '../../mock/options';\nimport type { Property } from '../../proxy';\nimport type { Expectation } from '../expectation';\nimport { ApplyProp } from '../expectation';\nimport { MATCHER_SYMBOL } from '../matcher';\nimport type { CallMap, ExpectationRepository } from './expectation-repository';\nimport { unboxReturnValue } from './return-value';\n\ntype CountableExpectation = {\n expectation: Expectation;\n matchCount: number;\n};\n\n/**\n * An expectation repository with a configurable behavior for\n * unexpected property access.\n */\nexport class FlexibleRepository implements ExpectationRepository {\n constructor(\n private unexpectedProperty: UnexpectedProperty = UnexpectedProperty.THROW\n ) {}\n\n protected readonly expectations = new Map<Property, CountableExpectation[]>();\n\n private readonly expectedCallStats: CallMap = new Map();\n\n private readonly unexpectedCallStats: CallMap = new Map();\n\n add(expectation: Expectation): void {\n const { property } = expectation;\n\n const expectations = this.expectations.get(property) || [];\n\n this.expectations.set(property, [\n ...expectations,\n {\n expectation,\n matchCount: 0,\n },\n ]);\n }\n\n clear(): void {\n this.expectations.clear();\n this.expectedCallStats.clear();\n this.unexpectedCallStats.clear();\n }\n\n apply = (args: unknown[]): unknown => this.get(ApplyProp)(...args);\n\n // TODO: this returns any, but the interface returns unknown\n // unknown causes errors in apply tests, and any causes bugs in bootstrapped SM\n get(property: Property): any {\n const expectations = this.expectations.get(property);\n\n if (expectations && expectations.length) {\n return this.handlePropertyWithMatchingExpectations(\n property,\n expectations\n );\n }\n\n return this.handlePropertyWithNoExpectations(property);\n }\n\n private handlePropertyWithMatchingExpectations = (\n property: Property,\n expectations: CountableExpectation[]\n ) => {\n // Avoid recording call stats for function calls, since the property is an\n // internal detail.\n if (property !== ApplyProp) {\n // An unexpected call could still happen later, if the property returns a\n // function that will not match the given args.\n this.recordExpected(property, undefined);\n }\n\n const propertyExpectation = expectations.find((e) =>\n e.expectation.matches(undefined)\n );\n\n if (propertyExpectation) {\n this.countAndConsume(propertyExpectation);\n\n return unboxReturnValue(propertyExpectation.expectation.returnValue);\n }\n\n return (...args: any[]) => {\n const callExpectation = expectations.find((e) =>\n e.expectation.matches(args)\n );\n\n if (callExpectation) {\n this.recordExpected(property, args);\n this.countAndConsume(callExpectation);\n\n return unboxReturnValue(callExpectation.expectation.returnValue);\n }\n\n return this.getValueForUnexpectedCall(property, args);\n };\n };\n\n private handlePropertyWithNoExpectations = (property: Property) => {\n switch (property) {\n case 'toString':\n return () => 'mock';\n case '@@toStringTag':\n case Symbol.toStringTag:\n case 'name':\n return 'mock';\n\n // Promise.resolve() tries to see if it's a \"thenable\".\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#thenables\n case 'then':\n return undefined;\n\n // pretty-format\n case '$$typeof':\n case 'constructor':\n case '@@__IMMUTABLE_ITERABLE__@@':\n case '@@__IMMUTABLE_RECORD__@@':\n return null;\n\n case MATCHER_SYMBOL:\n return false;\n\n case ApplyProp:\n return (...args: any[]) =>\n this.getValueForUnexpectedCall(property, args);\n default:\n return this.getValueForUnexpectedAccess(property);\n }\n };\n\n getAllProperties(): Property[] {\n return Array.from(this.expectations.keys());\n }\n\n getCallStats() {\n return {\n expected: this.expectedCallStats,\n unexpected: this.unexpectedCallStats,\n };\n }\n\n getUnmet(): Expectation[] {\n return ([] as Expectation[]).concat(\n ...Array.from(this.expectations.values()).map((expectations) =>\n expectations\n .filter((e) => e.expectation.min > e.matchCount)\n .map((e) => e.expectation)\n )\n );\n }\n\n private recordExpected(property: Property, args: any[] | undefined) {\n const calls = this.expectedCallStats.get(property) || [];\n\n this.expectedCallStats.set(property, [...calls, { arguments: args }]);\n }\n\n private recordUnexpected(property: Property, args: any[] | undefined) {\n const calls = this.unexpectedCallStats.get(property) || [];\n\n this.unexpectedCallStats.set(property, [...calls, { arguments: args }]);\n }\n\n private countAndConsume(expectation: CountableExpectation) {\n // eslint-disable-next-line no-param-reassign\n expectation.matchCount++;\n\n this.consumeExpectation(expectation);\n }\n\n private consumeExpectation(expectation: CountableExpectation): void {\n const { property, max } = expectation.expectation;\n\n const expectations = this.expectations.get(property)!;\n\n if (expectation.matchCount === max) {\n this.expectations.set(\n property,\n expectations.filter((e) => e !== expectation)\n );\n }\n }\n\n private getValueForUnexpectedCall(property: Property, args: any[]): never {\n this.recordUnexpected(property, args);\n\n throw new UnexpectedCall(property, args, this.getUnmet());\n }\n\n private getValueForUnexpectedAccess(property: Property): unknown {\n if (this.unexpectedProperty === UnexpectedProperty.THROW) {\n this.recordUnexpected(property, undefined);\n\n throw new UnexpectedAccess(property, this.getUnmet());\n }\n\n return (...args: unknown[]) => {\n this.recordUnexpected(property, args);\n\n throw new UnexpectedCall(property, args, this.getUnmet());\n };\n }\n}\n","import { printExpectation } from '../print';\nimport type { Property } from '../proxy';\nimport type { Expectation } from './expectation';\nimport type { Matcher } from './matcher';\nimport type { ReturnValue } from './repository/return-value';\n\n/**\n * Matches a call with more parameters than expected because it is assumed the\n * compiler will check that those parameters are optional.\n *\n * @example\n * new StrongExpectation(\n * 'bar',\n * deepEquals([1, 2, 3]),\n * 23\n * ).matches('bar', [1, 2, 3]) === true;\n */\nexport class StrongExpectation implements Expectation {\n private matched = 0;\n\n public min: number = 1;\n\n public max: number = 1;\n\n constructor(\n public property: Property,\n public args: Matcher[] | undefined,\n public returnValue: ReturnValue,\n private exactParams: boolean = false\n ) {}\n\n setInvocationCount(min: number, max = 1) {\n this.min = min;\n this.max = max;\n }\n\n matches(args: any[] | undefined): boolean {\n if (!this.matchesArgs(args)) {\n return false;\n }\n\n this.matched++;\n\n return this.max === 0 || this.matched <= this.max;\n }\n\n isUnmet(): boolean {\n return this.matched < this.min;\n }\n\n private matchesArgs(received: any[] | undefined) {\n if (this.args === undefined) {\n return !received;\n }\n\n if (!received) {\n return false;\n }\n\n if (this.exactParams) {\n if (this.args.length !== received.length) {\n return false;\n }\n }\n\n return this.args.every((arg, i) => arg.matches(received[i]));\n }\n\n toJSON() {\n return printExpectation(\n this.property,\n this.args,\n this.returnValue,\n this.min,\n this.max\n );\n }\n}\n","import { MissingWhen, UnfinishedExpectation } from '../errors';\nimport type { Expectation } from '../expectation/expectation';\nimport type { ReturnValue } from '../expectation/repository/return-value';\nimport type { ConcreteMatcher } from '../mock/options';\nimport { printWhen } from '../print';\nimport type { Property } from '../proxy';\n\n/**\n * An expectation has to be built incrementally, starting first with the property\n * being accessed inside {@link createStub}, then any arguments passed to it, and ending\n * it with the returned value from {@link createReturns}.\n */\nexport interface PendingExpectation {\n setProperty(prop: Property): void;\n\n setArgs(args: any[] | undefined): void;\n\n finish(returnValue: ReturnValue): Expectation;\n\n /**\n * Used by `pretty-format`.\n */\n toJSON(): string;\n}\n\nexport type ExpectationFactory = (\n property: Property,\n args: any[] | undefined,\n returnValue: ReturnValue,\n concreteMatcher: ConcreteMatcher,\n exactParams: boolean\n) => Expectation;\n\nexport class PendingExpectationWithFactory implements PendingExpectation {\n private args: any[] | undefined;\n\n private property: Property | undefined;\n\n constructor(\n private createExpectation: ExpectationFactory,\n private concreteMatcher: ConcreteMatcher,\n private exactParams: boolean\n ) {}\n\n setProperty(value: Property) {\n if (this.property) {\n throw new UnfinishedExpectation(this);\n }\n\n this.property = value;\n }\n\n setArgs(value: any[] | undefined) {\n this.args = value;\n }\n\n finish(returnValue: ReturnValue): Expectation {\n if (!this.property) {\n throw new MissingWhen();\n }\n\n const expectation = this.createExpectation(\n this.property,\n this.args,\n returnValue,\n this.concreteMatcher,\n this.exactParams\n );\n\n this.property = undefined;\n this.args = undefined;\n\n return expectation;\n }\n\n toJSON() {\n return printWhen(this.property!, this.args);\n }\n}\n","import { printExpected } from 'jest-matcher-utils';\nimport {\n isEqual,\n isMatchWith,\n isObjectLike,\n isUndefined,\n omitBy,\n} from 'lodash';\nimport { printArg } from '../print';\nimport type { Matcher, TypeMatcher } from './matcher';\nimport { isMatcher, MATCHER_SYMBOL } from './matcher';\n\n/**\n * Match a custom predicate.\n *\n * @param cb Will receive the value and returns whether it matches.\n * @param toJSON An optional function that should return a string that will be\n * used when the matcher needs to be printed in an error message. By default,\n * it stringifies `cb`.\n *\n * @example\n * const fn = mock<(x: number) => number>();\n * when(() => fn(It.matches(x => x >= 0))).returns(42);\n *\n * fn(2) === 42\n * fn(-1) // throws\n */\nconst matches = <T>(\n cb: (actual: T) => boolean,\n { toJSON = () => `matches(${cb.toString()})` }: { toJSON?: () => string } = {}\n): TypeMatcher<T> => {\n const matcher: Matcher = {\n [MATCHER_SYMBOL]: true,\n matches: (arg: T) => cb(arg),\n toJSON,\n };\n\n return matcher as any;\n};\n\nconst removeUndefined = (object: any): any => {\n if (Array.isArray(object)) {\n return object.map((x) => removeUndefined(x));\n }\n\n if (!isObjectLike(object)) {\n return object;\n }\n\n return omitBy(object, isUndefined);\n};\n\n/**\n * Compare values using deep equality.\n *\n * @param expected\n * @param strict By default, this matcher will treat a missing key in an object\n * and a key with the value `undefined` as not equal. It will also consider\n * non `Object` instances with different constructors as not equal. Setting\n * this to `false` will consider the objects in both cases as equal.\n *\n * @see It.is A matcher that uses strict equality.\n */\nconst deepEquals = <T>(\n expected: T,\n { strict = true }: { strict?: boolean } = {}\n): TypeMatcher<T> =>\n matches(\n (actual) => {\n if (strict) {\n return isEqual(actual, expected);\n }\n\n return isEqual(removeUndefined(actual), removeUndefined(expected));\n },\n { toJSON: () => printArg(expected) }\n );\n\n/**\n * Compare values using `Object.is`.\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\n *\n * @see It.deepEquals A matcher that uses deep equality.\n */\nconst is = <T = unknown>(expected: T): TypeMatcher<T> =>\n matches((actual) => Object.is(actual, expected), {\n toJSON: () => `${printExpected(expected)}`,\n });\n\n/**\n * Match any value, including `undefined` and `null`.\n *\n * @example\n * const fn = mock<(x: number, y: string) => number>();\n * when(() => fn(It.isAny(), It.isAny())).thenReturn(1);\n *\n * fn(23, 'foobar') === 1\n */\nconst isAny = (): TypeMatcher<any> =>\n matches(() => true, { toJSON: () => 'anything' });\n\ntype DeepPartial<T> = T extends object\n ? { [K in keyof T]?: DeepPartial<T[K]> }\n : T;\n\n/**\n * Recursively match an object.\n *\n * Supports nested matcher.\n *\n * @param partial An optional subset of the expected objected.\n *\n * @example\n * const fn = mock<(foo: { x: number, y: number }) => number>();\n * when(() => fn(It.isObject({ x: 23 }))).returns(42);\n *\n * fn({ x: 100, y: 200 }) // throws\n * fn({ x: 23, y: 200 }) // returns 42\n *\n * @example\n * It.isObject({ foo: It.isString() })\n */\nconst isObject = <T extends object, K extends DeepPartial<T>>(\n partial?: K\n): TypeMatcher<T> =>\n matches(\n (actual) =>\n isMatchWith(actual, partial || {}, (argValue, partialValue) => {\n if (isMatcher(partialValue)) {\n return partialValue.matches(argValue);\n }\n\n // Let lodash handle it otherwise.\n return undefined;\n }),\n { toJSON: () => (partial ? `object(${printExpected(partial)})` : 'object') }\n );\n\n/**\n * Match any number.\n *\n * @example\n * const fn = mock<(x: number) => number>();\n * when(() => fn(It.isNumber())).returns(42);\n *\n * fn(20.5) === 42\n * fn(NaN) // throws\n */\nconst isNumber = (): TypeMatcher<number> =>\n matches((actual) => typeof actual === 'number' && !Number.isNaN(actual), {\n toJSON: () => 'number',\n });\n\n/**\n * Match a string, potentially by a pattern.\n *\n * @param matching The string has to match this RegExp.\n * @param containing The string has to contain this substring.\n *\n * @example\n * const fn = mock<(x: string, y: string) => number>();\n * when(() => fn(It.isString(), It.isString({ containing: 'bar' }))).returns(42);\n *\n * fn('foo', 'baz') // throws\n * fn('foo', 'bar') === 42\n */\nconst isString = ({\n matching,\n containing,\n}: { matching?: RegExp; containing?: string } = {}): TypeMatcher<string> => {\n if (matching && containing) {\n throw new Error('You can only pass `matching` or `containing`, not both.');\n }\n\n return matches(\n (actual) => {\n if (typeof actual !== 'string') {\n return false;\n }\n\n if (containing) {\n return actual.indexOf(containing) !== -1;\n }\n\n return matching?.test(actual) ?? true;\n },\n {\n toJSON: () =>\n containing || matching\n ? `string(${printExpected(containing || matching)})`\n : 'string',\n }\n );\n};\n\n/**\n * Match an array.\n *\n * Supports nested matchers.\n *\n * @param containing If given, the matched array has to contain ALL of these\n * elements in ANY order.\n *\n * @example\n * const fn = mock<(arr: number[]) => number>();\n * when(() => fn(It.isArray())).thenReturn(1);\n * when(() => fn(It.isArray([2, 3]))).thenReturn(2);\n *\n * fn({ length: 1, 0: 42 }) // throws\n * fn([]) === 1\n * fn([3, 2, 1]) === 2\n *\n * @example\n * It.isArray([It.isString({ containing: 'foobar' })])\n */\nconst isArray = <T extends any[]>(containing?: T): TypeMatcher<T> =>\n matches(\n (actual) => {\n if (!Array.isArray(actual)) {\n return false;\n }\n\n if (!containing) {\n return true;\n }\n\n return containing.every(\n (x) =>\n actual.find((y) => {\n if (isMatcher(x)) {\n return x.matches(y);\n }\n\n return deepEquals(x).matches(y);\n }) !== undefined\n );\n },\n {\n toJSON: () =>\n containing ? `array(${printExpected(containing)})` : 'array',\n }\n );\n\n/**\n * Matches anything and stores the received value.\n *\n * This should not be needed for most cases, but can be useful if you need\n * access to a complex argument outside the expectation e.g. to test a\n * callback.\n *\n * @param name If given, this name will be printed in error messages.\n *\n * @example\n * const fn = mock<(cb: (value: number) => number) => void>();\n * const matcher = It.willCapture();\n * when(() => fn(matcher)).thenReturn();\n *\n * fn(x => x + 1);\n * matcher.value?.(3) === 4\n */\nconst willCapture = <T = unknown>(\n name?: string\n): TypeMatcher<T> & { value: T | undefined } => {\n let capturedValue: T | undefined;\n\n const matcher: Matcher & { value: T | undefined } = {\n [MATCHER_SYMBOL]: true,\n matches: (actual) => {\n capturedValue = actual;\n\n return true;\n },\n toJSON: () => name ?? 'captures',\n get value(): T | undefined {\n return capturedValue;\n },\n };\n\n return matcher as any;\n};\n\n/**\n * Contains argument matchers that can be used to ignore arguments in an\n * expectation or to match complex arguments.\n */\nexport const It = {\n matches,\n deepEquals,\n is,\n isAny,\n isObject,\n isNumber,\n isString,\n isArray,\n willCapture,\n};\n","import { It } from '../expectation/it';\nimport type { MockOptions } from './options';\nimport { UnexpectedProperty } from './options';\n\nexport type StrongMockDefaults = Required<MockOptions>;\n\nconst defaults: StrongMockDefaults = {\n concreteMatcher: It.deepEquals,\n unexpectedProperty: UnexpectedProperty.CALL_THROW,\n exactParams: false,\n};\n\nexport let currentDefaults: StrongMockDefaults = defaults;\n\n/**\n * Override strong-mock's defaults.\n *\n * @param newDefaults These will be applied to the library defaults. Multiple\n * calls don't stack e.g. calling this with `{}` will clear any previously\n * applied defaults.\n */\nexport const setDefaults = (newDefaults: MockOptions): void => {\n currentDefaults = {\n ...defaults,\n ...newDefaults,\n };\n};\n","import { NotAMock } from '../errors';\nimport type { ExpectationRepository } from '../expectation/repository/expectation-repository';\nimport type { PendingExpectation } from '../when/pending-expectation';\nimport type { StrongMockDefaults } from './defaults';\nimport type { Mock } from './mock';\n\n/**\n * Since `when` doesn't receive the mock subject (because we can't make it\n * consistently return it from `mock()`, `mock.foo` and `mock.bar()`) we need\n * to store a global state for the currently active mock.\n *\n * We also want to throw in the following case:\n *\n * ```\n * when(() => mock()) // forgot returns here\n * when(() => mock()) // should throw\n * ```\n *\n * For that reason we can't just store the currently active mock, but also\n * whether we finished the expectation or not.\n */\nlet activeMock: Mock<any> | undefined;\n\nexport const setActiveMock = (mock: Mock<any>) => {\n activeMock = mock;\n};\n\nexport const clearActiveMock = () => {\n activeMock = undefined;\n};\n\nexport const getActiveMock = (): Mock<any> => activeMock;\n\ntype MockState = {\n repository: ExpectationRepository;\n pendingExpectation: PendingExpectation;\n options: StrongMockDefaults;\n};\n\n/**\n * Store a global map of all mocks created and their state.\n *\n * This is needed because we can't reliably pass the state between `when`\n * and `thenReturn`.\n */\nconst mockMap = new Map<Mock<any>, MockState>();\n\nexport const getMockState = (mock: Mock<any>): MockState => {\n if (mockMap.has(mock)) {\n return mockMap.get(mock)!;\n }\n\n throw new NotAMock();\n};\n\nexport const setMockState = (mock: Mock<any>, state: MockState): void => {\n mockMap.set(mock, state);\n};\n\nexport const getAllMocks = (): [Mock<any>, MockState][] =>\n Array.from(mockMap.entries());\n","import type { Mock } from './mock/mock';\n\nexport type Property = string | symbol;\n\nexport interface ProxyTraps {\n /**\n * Called when accessing any property on an object, except for\n * `.call`, `.apply` and `.bind`.\n */\n property: (property: Property) => unknown;\n\n /**\n * Called when calling a function.\n *\n * @example\n * ```\n * fn(...args)\n * ```\n *\n * @example\n * ```\n * fn.call(this, ...args)\n * ```\n *\n * @example\n * ```\n * fn.apply(this, [...args])\n * ```\n *\n * @example\n * ```\n * Reflect.apply(fn, this, [...args])\n * ```\n */\n apply: (args: any[]) => unknown;\n\n /**\n * Called when getting the proxy's own enumerable keys.\n *\n * @example\n * ```\n * Object.keys(proxy);\n * ```\n *\n * @example\n * ```\n * const foo = { ...proxy };\n * ```\n */\n ownKeys: () => Property[];\n}\n\nexport const createProxy = <T>(traps: ProxyTraps): Mock<T> =>\n // eslint-disable-next-line no-empty-function\n new Proxy(/* istanbul ignore next */ () => {}, {\n get: (target, prop: string | symbol) => {\n if (prop === 'bind') {\n return (thisArg: any, ...args: any[]) =>\n (...moreArgs: any[]) =>\n traps.apply([...args, ...moreArgs]);\n }\n\n if (prop === 'apply') {\n return (thisArg: any, args: any[] | undefined) =>\n traps.apply(args || []);\n }\n\n if (prop === 'call') {\n return (thisArg: any, ...args: any[]) => traps.apply(args);\n }\n\n return traps.property(prop);\n },\n\n apply: (target, thisArg: any, args: any[]) => traps.apply(args),\n\n ownKeys: () => traps.ownKeys(),\n\n getOwnPropertyDescriptor(\n target: () => void,\n prop: string | symbol\n ): PropertyDescriptor | undefined {\n const keys = traps.ownKeys();\n\n if (keys.includes(prop)) {\n return {\n configurable: true,\n enumerable: true,\n };\n }\n\n return undefined;\n },\n }) as unknown as Mock<T>;\n","import { NestedWhen } from '../errors';\nimport { ApplyProp } from '../expectation/expectation';\nimport type { ExpectationRepository } from '../expectation/repository/expectation-repository';\nimport type { Property } from '../proxy';\nimport { createProxy } from '../proxy';\nimport type { PendingExpectation } from '../when/pending-expectation';\nimport { setActiveMock } from './map';\nimport type { Mock } from './mock';\nimport { Mode } from './mock';\n\nexport const createStub = <T>(\n repo: ExpectationRepository,\n pendingExpectation: PendingExpectation,\n getCurrentMode: () => Mode\n): Mock<T> => {\n const stub = createProxy<T>({\n property: (property) => {\n if (getCurrentMode() === Mode.CALL) {\n return repo.get(property);\n }\n\n setActiveMock(stub);\n\n pendingExpectation.setProperty(property);\n\n return createProxy({\n property: (childProp: Property) => {\n throw new NestedWhen(property, childProp);\n },\n apply: (args: any[]) => {\n pendingExpectation.setArgs(args);\n },\n ownKeys: () => {\n throw new Error('Spreading during an expectation is not supported.');\n },\n });\n },\n apply: (args: any[]) => {\n if (getCurrentMode() === Mode.CALL) {\n return repo.apply(args);\n }\n\n setActiveMock(stub);\n\n pendingExpectation.setProperty(ApplyProp);\n pendingExpectation.setArgs(args);\n\n return undefined;\n },\n ownKeys: () => {\n if (getCurrentMode() === Mode.CALL) {\n return repo.getAllProperties();\n }\n\n throw new Error('Spreading during an expectation is not supported.');\n },\n });\n\n return stub;\n};\n","import { isMatcher } from '../expectation/matcher';\nimport { FlexibleRepository } from '../expectation/repository/flexible-repository';\nimport { StrongExpectation } from '../expectation/strong-expectation';\nimport type { ExpectationFactory } from '../when/pending-expectation';\nimport { PendingExpectationWithFactory } from '../when/pending-expectation';\nimport type { StrongMockDefaults } from './defaults';\nimport { currentDefaults } from './defaults';\nimport { setMockState } from './map';\nimport type { MockOptions } from './options';\nimport { createStub } from './stub';\n\nexport type Mock<T> = T;\n\nconst strongExpectationFactory: ExpectationFactory = (\n property,\n args,\n returnValue,\n concreteMatcher,\n exactParams\n) =>\n new StrongExpectation(\n property,\n // Wrap every non-matcher in the default matcher.\n args?.map((arg) => (isMatcher(arg) ? arg : concreteMatcher(arg))),\n returnValue,\n exactParams\n );\n\nexport enum Mode {\n EXPECT,\n CALL,\n}\n\nlet currentMode: Mode = Mode.CALL;\n\nexport const setMode = (mode: Mode) => {\n currentMode = mode;\n};\nconst getMode = () => currentMode;\n\n/**\n * Create a type safe mock.\n *\n * @see {@link when} Set expectations on the mock using `when`.\n *\n * @param options Configure the options for this specific mock, overriding any\n * defaults that were set with {@link setDefaults}.\n * @param options.unexpectedProperty Controls what happens when an unexpected\n * property is accessed.\n * @param options.concreteMatcher The matcher that will be used when one isn't\n * specified explicitly.\n * @param options.exactParams Controls whether the number of received arguments\n * has to match the expectation.\n *\n * @example\n * const fn = mock<() => number>();\n *\n * when(() => fn()).thenReturn(23);\n *\n * fn() === 23;\n */\nexport const mock = <T>({\n unexpectedProperty,\n concreteMatcher,\n exactParams,\n}: MockOptions = {}): Mock<T> => {\n const options: StrongMockDefaults = {\n unexpectedProperty:\n unexpectedProperty ?? currentDefaults.unexpectedProperty,\n concreteMatcher: concreteMatcher ?? currentDefaults.concreteMatcher,\n exactParams: exactParams ?? currentDefaults.exactParams,\n };\n\n const repository = new FlexibleRepository(options.unexpectedProperty);\n\n const pendingExpectation = new PendingExpectationWithFactory(\n strongExpectationFactory,\n options.concreteMatcher,\n options.exactParams\n );\n\n const stub = createStub<T>(repository, pendingExpectation, getMode);\n\n setMockState(stub, {\n repository,\n pendingExpectation,\n options,\n });\n\n return stub;\n};\n","import type { Expectation } from '../expectation/expectation';\n\nexport interface InvocationCount {\n /**\n * Expect a call to be made at least `min` times and at most `max` times.\n */\n between(min: number, max: number): void;\n\n /**\n * Expect a call to be made exactly `exact` times.\n *\n * Shortcut for `between(exact, exact)`.\n */\n times(exact: number): void;\n\n /**\n * Expect a call to be made any number of times, including never.\n *\n * Shortcut for `between(0, Infinity)`.\n */\n anyTimes(): void;\n\n /**\n * Expect a call to be made at least `min` times.\n *\n * Shortcut for `between(min, Infinity)`.\n */\n atLeast(min: number): void;\n\n /**\n * Expect a call to be made at most `max` times.\n *\n * Shortcut for `between(0, max)`.\n */\n atMost(max: number): void;\n\n /**\n * Expect a call to be made exactly once.\n *\n * Shortcut for `times(1)`.\n */\n once(): void;\n\n /**\n * Expect a call to be made exactly twice.\n *\n * Shortcut for `times(2)`.\n */\n twice(): void;\n}\n\nexport const createInvocationCount = (\n expectation: Expectation\n): InvocationCount => ({\n between(min: number, max: number) {\n expectation.setInvocationCount(min, max);\n },\n\n /* istanbul ignore next */\n times(exact: number) {\n expectation.setInvocationCount(exact, exact);\n },\n\n /* istanbul ignore next */\n anyTimes(): void {\n expectation.setInvocationCount(0, 0);\n },\n\n /* istanbul ignore next */\n atLeast(min: number) {\n expectation.setInvocationCount(min, Infinity);\n },\n\n /* istanbul ignore next */\n atMost(max: number) {\n expectation.setInvocationCount(0, max);\n },\n\n /* istanbul ignore next */\n once() {\n expectation.setInvocationCount(1, 1);\n },\n\n /* istanbul ignore next */\n twice() {\n expectation.setInvocationCount(2, 2);\n },\n /* eslint-enable no-param-reassign, no-multi-assign */\n});\n","import type { ExpectationRepository } from '../expectation/repository/expectation-repository';\nimport type { ReturnValue } from '../expectation/repository/return-value';\nimport type { PendingExpectation } from '../when/pending-expectation';\nimport type { InvocationCount } from './invocation-count';\nimport { createInvocationCount } from './invocation-count';\n\nexport type PromiseStub<R, P> = {\n /**\n * Set the return value for the current call.\n *\n * @param value This needs to be of the same type as the value returned\n * by the call inside `when`.\n *\n * @example\n * when(() => fn()).thenReturn(Promise.resolve(23));\n *\n * @example\n * when(() => fn()).thenReturn(Promise.reject({ foo: 'bar' });\n */\n thenReturn(value: P): InvocationCount;\n\n /**\n * Set the return value for the current call.\n *\n * @param promiseValue This needs to be of the same type as the value inside\n * the promise returned by the `when` callback.\n *\n * @example\n * when(() => fn()).thenResolve('foo');\n */\n thenResolve(promiseValue: R): InvocationCount;\n\n /**\n * Make the current call reject with the given error.\n *\n * @param error An `Error` instance. You can pass just a message, and\n * it will be wrapped in an `Error` instance. If you want to reject with\n * a non error then use the {@link thenReturn} method.\n *\n * @example\n * when(() => fn()).thenReject(new Error('oops'));\n */\n thenReject(error: Error): InvocationCount;\n\n /**\n * Make the current call reject with an error with the given message.\n *\n * @param message Will be wrapped in `new Error()`. If you want to reject\n * with a custom error then pass it here instead of the message. If you\n * want to reject with a non error then use `thenReturn`.\n *\n * @example\n * when(() => fn()).thenReject('oops');\n */\n thenReject(message: string): InvocationCount;\n\n /**\n * Make the current call reject with `new Error()`.\n */\n thenReject(): InvocationCount;\n};\n\nexport type NonPromiseStub<R> = {\n /**\n * Set the return value for the current call.\n *\n * @param returnValue This needs to be of the same type as the value returned\n * by the `when` callback.\n */\n thenReturn(returnValue: R): InvocationCount;\n\n /**\n * Make the current call throw the given error.\n *\n * @param error The error instance. If you want to throw a simple `Error`\n * you can pass just the message.\n */\n thenThrow(error: Error): InvocationCount;\n\n /**\n * Make the current call throw an error with the given message.\n *\n * @param message Will be wrapped in `new Error()`. If you want to throw\n * a custom error pass it here instead of the message.\n */\n thenThrow(message: string): InvocationCount;\n\n /**\n * Make the current call throw `new Error()`.\n */\n thenThrow(): InvocationCount;\n};\n\nconst finishPendingExpectation = (\n returnValue: ReturnValue,\n pendingExpectation: PendingExpectation,\n repo: ExpectationRepository\n) => {\n const finishedExpectation = pendingExpectation.finish(returnValue);\n\n repo.add(finishedExpectation);\n\n return createInvocationCount(finishedExpectation);\n};\n\nconst getError = (errorOrMessage: Error | string | undefined): Error => {\n if (typeof errorOrMessage === 'string') {\n return new Error(errorOrMessage);\n }\n\n if (errorOrMessage instanceof Error) {\n return errorOrMessage;\n }\n\n return new Error();\n};\n\nexport const createReturns = (\n pendingExpectation: PendingExpectation,\n repository: ExpectationRepository\n) => ({\n thenReturn: (returnValue: any): InvocationCount =>\n finishPendingExpectation(\n // This will handle both thenReturn(23) and thenReturn(Promise.resolve(3)).\n { value: returnValue, isError: false, isPromise: false },\n pendingExpectation,\n repository\n ),\n thenThrow: (errorOrMessage?: Error | string): InvocationCount =>\n finishPendingExpectation(\n { value: getError(errorOrMessage), isError: true, isPromise: false },\n pendingExpectation,\n repository\n ),\n thenResolve: (promiseValue: any): InvocationCount =>\n finishPendingExpectation(\n {\n value: promiseValue,\n isError: false,\n isPromise: true,\n },\n pendingExpectation,\n repository\n ),\n\n thenReject: (errorOrMessage?: Error | string): InvocationCount =>\n finishPendingExpectation(\n {\n value: getError(errorOrMessage),\n isError: true,\n isPromise: true,\n },\n pendingExpectation,\n repository\n ),\n});\n","import { getActiveMock, getMockState } from '../mock/map';\nimport { Mode, setMode } from '../mock/mock';\nimport type { NonPromiseStub, PromiseStub } from '../return/returns';\nimport { createReturns } from '../return/returns';\n\ninterface When {\n <R>(expectation: () => Promise<R>): PromiseStub<R, Promise<R>>;\n <R>(expectation: () => R): NonPromiseStub<R>;\n}\n\n/**\n * Set an expectation on a mock.\n *\n * The expectation must be finished by setting a return value, even if the value\n * is `undefined`.\n *\n * If a call happens that was not expected then the mock will throw an error.\n * By default, the call is expected to only be made once. Use the invocation\n * count helpers to expect a call multiple times.\n *\n * @param expectation A callback to set the expectation on your mock. The\n * callback must return the value from the mock to properly infer types.\n *\n * @example\n * const fn = mock<() => void>();\n * when(() => fn()).thenReturn(undefined);\n *\n * @example\n * const fn = mock<() => number>();\n * when(() => fn()).thenReturn(42).atMost(3);\n *\n * @example\n * const fn = mock<(x: number) => Promise<number>();\n * when(() => fn(23)).thenResolve(42);\n */\nexport const when: When = <R>(expectation: () => R) => {\n setMode(Mode.EXPECT);\n expectation();\n setMode(Mode.CALL);\n\n const { pendingExpectation, repository } = getMockState(getActiveMock());\n\n return createReturns(pendingExpectation, repository);\n};\n","import { getAllMocks, getMockState } from '../mock/map';\nimport type { Mock } from '../mock/mock';\n\n/**\n * Remove any remaining expectations on the given mock.\n *\n * @example\n * const fn = mock<() => number>();\n *\n * when(() => fn()).thenReturn(23);\n *\n * reset(fn);\n *\n * fn(); // throws\n */\nexport const reset = (mock: Mock<any>): void => {\n getMockState(mock).repository.clear();\n};\n\n/**\n * Reset all existing mocks.\n *\n * @see reset\n */\nexport const resetAll = (): void => {\n getAllMocks().forEach(([mock]) => {\n reset(mock);\n });\n};\n","import { UnexpectedCalls, UnmetExpectations } from '../errors';\nimport type { ExpectationRepository } from '../expectation/repository/expectation-repository';\nimport { getAllMocks, getMockState } from '../mock/map';\nimport type { Mock } from '../mock/mock';\n\nexport const verifyRepo = (repository: ExpectationRepository) => {\n const unmetExpectations = repository.getUnmet();\n\n if (unmetExpectations.length) {\n throw new UnmetExpectations(unmetExpectations);\n }\n\n const callStats = repository.getCallStats();\n\n if (callStats.unexpected.size) {\n throw new UnexpectedCalls(callStats.unexpected, unmetExpectations);\n }\n};\n\n/**\n * Verify that all expectations on the given mock have been met.\n *\n * @throws Will throw if there are remaining expectations that were set\n * using `when` and that weren't met.\n *\n * @throws Will throw if any unexpected calls happened. Normally those\n * calls throw on their own, but the error might be caught by the code\n * being tested.\n *\n * @example\n * const fn = mock<() => number>();\n *\n * when(() => fn()).thenReturn(23);\n *\n * verify(fn); // throws\n */\nexport const verify = <T>(mock: Mock<T>): void => {\n const { repository } = getMockState(mock);\n\n verifyRepo(repository);\n};\n\n/**\n * Verify all existing mocks.\n *\n * @see verify\n */\nexport const verifyAll = (): void => {\n getAllMocks().forEach(([mock]) => {\n verify(mock);\n });\n};\n"],"names":["MATCHER_SYMBOL","Symbol","isMatcher","f","ApplyProp","printProperty","property","toString","printArg","arg","toJSON","printExpected","printCall","args","prettyArgs","map","join","prettyProperty","printReturns","isError","isPromise","value","min","max","thenPrefix","printWhen","EXPECTED_COLOR","printExpectation","returnValue","printRemainingExpectations","expectations","length","e","UnfinishedExpectation","Error","constructor","pendingExpectation","MissingWhen","UnexpectedAccess","UnexpectedCall","NotAMock","UnmetExpectations","mergeCalls","callMap","Map","Array","from","entries","calls","hasMethodCalls","some","call","arguments","hasPropertyAccesses","filter","UnexpectedCalls","unexpectedCalls","printedCalls","NestedWhen","parentProp","childProp","snippet","UnexpectedProperty","unboxReturnValue","Promise","reject","resolve","FlexibleRepository","unexpectedProperty","THROW","expectedCallStats","unexpectedCallStats","apply","get","handlePropertyWithMatchingExpectations","recordExpected","undefined","propertyExpectation","find","expectation","matches","countAndConsume","callExpectation","getValueForUnexpectedCall","handlePropertyWithNoExpectations","toStringTag","getValueForUnexpectedAccess","add","set","matchCount","clear","getAllProperties","keys","getCallStats","expected","unexpected","getUnmet","concat","values","recordUnexpected","consumeExpectation","StrongExpectation","exactParams","matched","setInvocationCount","matchesArgs","isUnmet","received","every","i","PendingExpectationWithFactory","createExpectation","concreteMatcher","setProperty","setArgs","finish","cb","matcher","removeUndefined","object","isArray","x","isObjectLike","omitBy","isUndefined","deepEquals","strict","actual","isEqual","is","Object","isAny","isObject","partial","isMatchWith","argValue","partialValue","isNumber","Number","isNaN","isString","matching","containing","indexOf","test","y","willCapture","name","capturedValue","It","defaults","CALL_THROW","currentDefaults","setDefaults","newDefaults","activeMock","setActiveMock","mock","getActiveMock","mockMap","getMockState","has","setMockState","state","getAllMocks","createProxy","traps","Proxy","target","prop","thisArg","moreArgs","ownKeys","getOwnPropertyDescriptor","includes","configurable","enumerable","createStub","repo","getCurrentMode","stub","Mode","CALL","strongExpectationFactory","currentMode","setMode","mode","getMode","options","repository","createInvocationCount","between","times","exact","anyTimes","atLeast","Infinity","atMost","once","twice","finishPendingExpectation","finishedExpectation","getError","errorOrMessage","createReturns","thenReturn","thenThrow","thenResolve","promiseValue","thenReject","when","EXPECT","reset","resetAll","forEach","verifyRepo","unmetExpectations","callStats","size","verify","verifyAll"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { MockOptions } from './options';
2
- export declare type StrongMockDefaults = Required<MockOptions>;
2
+ export type StrongMockDefaults = Required<MockOptions>;
3
3
  export declare let currentDefaults: StrongMockDefaults;
4
4
  /**
5
5
  * Override strong-mock's defaults.
@@ -5,7 +5,7 @@ import type { Mock } from './mock';
5
5
  export declare const setActiveMock: (mock: Mock<any>) => void;
6
6
  export declare const clearActiveMock: () => void;
7
7
  export declare const getActiveMock: () => Mock<any>;
8
- declare type MockState = {
8
+ type MockState = {
9
9
  repository: ExpectationRepository;
10
10
  pendingExpectation: PendingExpectation;
11
11
  options: StrongMockDefaults;
@@ -1,5 +1,5 @@
1
1
  import type { MockOptions } from './options';
2
- export declare type Mock<T> = T;
2
+ export type Mock<T> = T;
3
3
  export declare enum Mode {
4
4
  EXPECT = 0,
5
5
  CALL = 1
@@ -1,5 +1,5 @@
1
1
  import type { Matcher } from '../expectation/matcher';
2
- export declare type ConcreteMatcher = <T>(expected: T) => Matcher;
2
+ export type ConcreteMatcher = <T>(expected: T) => Matcher;
3
3
  export declare enum UnexpectedProperty {
4
4
  /**
5
5
  * Throw an error immediately.
package/dist/proxy.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Mock } from './mock/mock';
2
- export declare type Property = string | symbol;
2
+ export type Property = string | symbol;
3
3
  export interface ProxyTraps {
4
4
  /**
5
5
  * Called when accessing any property on an object, except for
@@ -1,7 +1,7 @@
1
1
  import type { ExpectationRepository } from '../expectation/repository/expectation-repository';
2
2
  import type { PendingExpectation } from '../when/pending-expectation';
3
3
  import type { InvocationCount } from './invocation-count';
4
- export declare type PromiseStub<R, P> = {
4
+ export type PromiseStub<R, P> = {
5
5
  /**
6
6
  * Set the return value for the current call.
7
7
  *
@@ -20,13 +20,20 @@ export declare type PromiseStub<R, P> = {
20
20
  *
21
21
  * @param promiseValue This needs to be of the same type as the value inside
22
22
  * the promise returned by the `when` callback.
23
+ *
24
+ * @example
25
+ * when(() => fn()).thenResolve('foo');
23
26
  */
24
27
  thenResolve(promiseValue: R): InvocationCount;
25
28
  /**
26
29
  * Make the current call reject with the given error.
27
30
  *
28
- * @param error An `Error` instance. If you want to reject with a non error
29
- * then use the `thenReturn` method.
31
+ * @param error An `Error` instance. You can pass just a message, and
32
+ * it will be wrapped in an `Error` instance. If you want to reject with
33
+ * a non error then use the {@link thenReturn} method.
34
+ *
35
+ * @example
36
+ * when(() => fn()).thenReject(new Error('oops'));
30
37
  */
31
38
  thenReject(error: Error): InvocationCount;
32
39
  /**
@@ -35,6 +42,9 @@ export declare type PromiseStub<R, P> = {
35
42
  * @param message Will be wrapped in `new Error()`. If you want to reject
36
43
  * with a custom error then pass it here instead of the message. If you
37
44
  * want to reject with a non error then use `thenReturn`.
45
+ *
46
+ * @example
47
+ * when(() => fn()).thenReject('oops');
38
48
  */
39
49
  thenReject(message: string): InvocationCount;
40
50
  /**
@@ -42,7 +52,7 @@ export declare type PromiseStub<R, P> = {
42
52
  */
43
53
  thenReject(): InvocationCount;
44
54
  };
45
- export declare type NonPromiseStub<R> = {
55
+ export type NonPromiseStub<R> = {
46
56
  /**
47
57
  * Set the return value for the current call.
48
58
  *
@@ -16,7 +16,7 @@ export interface PendingExpectation {
16
16
  */
17
17
  toJSON(): string;
18
18
  }
19
- export declare type ExpectationFactory = (property: Property, args: any[] | undefined, returnValue: ReturnValue, concreteMatcher: ConcreteMatcher, exactParams: boolean) => Expectation;
19
+ export type ExpectationFactory = (property: Property, args: any[] | undefined, returnValue: ReturnValue, concreteMatcher: ConcreteMatcher, exactParams: boolean) => Expectation;
20
20
  export declare class PendingExpectationWithFactory implements PendingExpectation {
21
21
  private createExpectation;
22
22
  private concreteMatcher;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strong-mock",
3
- "version": "8.0.0-beta.2",
3
+ "version": "8.0.1",
4
4
  "description": "Simple type safe mocking library",
5
5
  "keywords": [
6
6
  "tdd",
@@ -21,25 +21,25 @@
21
21
  "dist"
22
22
  ],
23
23
  "dependencies": {
24
- "jest-matcher-utils": "~28.1.0",
24
+ "jest-matcher-utils": "~29.3.0",
25
25
  "lodash": "~4.17.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@nighttrax/eslint-config-ts": "~10.0.0-beta.2",
29
- "@tdd-buffet/jest-config": "~5.0.0",
28
+ "@nighttrax/eslint-config-ts": "~11.0.0",
29
+ "@tdd-buffet/jest-config": "~5.0.1",
30
30
  "@tdd-buffet/tsconfig": "~1.0.0",
31
- "@types/jest": "~28.1.6",
32
- "@types/node": "~17.0.8",
31
+ "@types/jest": "~29.2.0",
32
+ "@types/node": "~18.11.0",
33
33
  "@types/lodash": "~4.14.0",
34
34
  "doctoc": "~2.2.0",
35
- "eslint": "~8.24.0",
36
- "jest": "~28.1.3",
35
+ "eslint": "~8.32.0",
36
+ "jest": "~29.3.0",
37
37
  "microbundle": "~0.15.0",
38
38
  "standard-version": "~9.5.0",
39
39
  "strip-ansi": "~6.0.0",
40
40
  "strong-mock": "~6.0.0",
41
41
  "tslib": "~2.4.0",
42
- "typescript": "~4.8.0"
42
+ "typescript": "~4.9.0"
43
43
  },
44
44
  "scripts": {
45
45
  "docs": "doctoc --title '**Table of Contents**' README.md",