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 +19 -8
- package/dist/expectation/it.d.ts +1 -1
- package/dist/expectation/matcher.d.ts +2 -2
- package/dist/expectation/repository/expectation-repository.d.ts +3 -3
- package/dist/expectation/repository/flexible-repository.d.ts +1 -1
- package/dist/expectation/repository/return-value.d.ts +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/mock/defaults.d.ts +1 -1
- package/dist/mock/map.d.ts +1 -1
- package/dist/mock/mock.d.ts +1 -1
- package/dist/mock/options.d.ts +1 -1
- package/dist/proxy.d.ts +1 -1
- package/dist/return/returns.d.ts +14 -4
- package/dist/when/pending-expectation.d.ts +1 -1
- package/package.json +9 -9
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
|
|
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
|
|
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(() =>
|
|
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
|
|
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
|
-
|
|
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 }))
|
package/dist/expectation/it.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const MATCHER_SYMBOL: unique symbol;
|
|
2
|
-
export
|
|
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
|
|
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
|
|
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
|
|
19
|
-
export
|
|
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
|
-
|
|
5
|
+
type CountableExpectation = {
|
|
6
6
|
expectation: Expectation;
|
|
7
7
|
matchCount: number;
|
|
8
8
|
};
|
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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"}
|
package/dist/mock/defaults.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MockOptions } from './options';
|
|
2
|
-
export
|
|
2
|
+
export type StrongMockDefaults = Required<MockOptions>;
|
|
3
3
|
export declare let currentDefaults: StrongMockDefaults;
|
|
4
4
|
/**
|
|
5
5
|
* Override strong-mock's defaults.
|
package/dist/mock/map.d.ts
CHANGED
|
@@ -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
|
-
|
|
8
|
+
type MockState = {
|
|
9
9
|
repository: ExpectationRepository;
|
|
10
10
|
pendingExpectation: PendingExpectation;
|
|
11
11
|
options: StrongMockDefaults;
|
package/dist/mock/mock.d.ts
CHANGED
package/dist/mock/options.d.ts
CHANGED
package/dist/proxy.d.ts
CHANGED
package/dist/return/returns.d.ts
CHANGED
|
@@ -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
|
|
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.
|
|
29
|
-
*
|
|
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
|
|
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
|
|
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.
|
|
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": "~
|
|
24
|
+
"jest-matcher-utils": "~29.3.0",
|
|
25
25
|
"lodash": "~4.17.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@nighttrax/eslint-config-ts": "~
|
|
29
|
-
"@tdd-buffet/jest-config": "~5.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": "~
|
|
32
|
-
"@types/node": "~
|
|
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.
|
|
36
|
-
"jest": "~
|
|
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.
|
|
42
|
+
"typescript": "~4.9.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"docs": "doctoc --title '**Table of Contents**' README.md",
|