strong-mock 7.2.0 → 8.0.0-beta.0

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/dist/index.js CHANGED
@@ -1,144 +1,719 @@
1
- 'use strict';
1
+ var jestMatcherUtils = require('jest-matcher-utils');
2
+ var lodash = require('lodash');
2
3
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
+ const MATCHER_SYMBOL = Symbol('matcher');
5
+ /**
6
+ * Used to test if an expectation on an argument is a custom matcher.
7
+ */
4
8
 
5
- var jestMatcherUtils = require('jest-matcher-utils');
6
- var isEqual = require('lodash/isEqual');
7
- var isMatchWith = require('lodash/isMatchWith');
8
-
9
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
-
11
- var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
12
- var isMatchWith__default = /*#__PURE__*/_interopDefaultLegacy(isMatchWith);
13
-
14
- /*! *****************************************************************************
15
- Copyright (c) Microsoft Corporation.
16
-
17
- Permission to use, copy, modify, and/or distribute this software for any
18
- purpose with or without fee is hereby granted.
19
-
20
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
21
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
23
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
24
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
25
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
26
- PERFORMANCE OF THIS SOFTWARE.
27
- ***************************************************************************** */
28
- /* global Reflect, Promise */
29
-
30
- var extendStatics = function(d, b) {
31
- extendStatics = Object.setPrototypeOf ||
32
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
33
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
34
- return extendStatics(d, b);
35
- };
36
-
37
- function __extends(d, b) {
38
- if (typeof b !== "function" && b !== null)
39
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
40
- extendStatics(d, b);
41
- function __() { this.constructor = d; }
42
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
43
- }
44
-
45
- var __assign = function() {
46
- __assign = Object.assign || function __assign(t) {
47
- for (var s, i = 1, n = arguments.length; i < n; i++) {
48
- s = arguments[i];
49
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
50
- }
51
- return t;
52
- };
53
- return __assign.apply(this, arguments);
54
- };
55
-
56
- function __read(o, n) {
57
- var m = typeof Symbol === "function" && o[Symbol.iterator];
58
- if (!m) return o;
59
- var i = m.call(o), r, ar = [], e;
60
- try {
61
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
62
- }
63
- catch (error) { e = { error: error }; }
64
- finally {
65
- try {
66
- if (r && !r.done && (m = i["return"])) m.call(i);
67
- }
68
- finally { if (e) throw e.error; }
69
- }
70
- return ar;
71
- }
72
-
73
- function __spreadArray(to, from) {
74
- for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
75
- to[j] = from[i];
76
- return to;
9
+ function isMatcher(f) {
10
+ return !!(f && f[MATCHER_SYMBOL]);
77
11
  }
78
12
 
79
13
  /**
80
14
  * Special symbol denoting the call of a function.
81
- */
82
- var ApplyProp = Symbol('apply');
15
+ */
16
+ const ApplyProp = Symbol('apply');
17
+
18
+ const printProperty = property => {
19
+ if (property === ApplyProp) {
20
+ return '';
21
+ }
22
+
23
+ if (typeof property === 'symbol') {
24
+ return `[${property.toString()}]`;
25
+ }
26
+
27
+ return `.${property}`;
28
+ };
29
+ const printArg = arg => // Call toJSON on matchers directly to avoid wrapping them in quotes.
30
+ isMatcher(arg) ? arg.toJSON() : jestMatcherUtils.printExpected(arg);
31
+ const printCall = (property, args) => {
32
+ const prettyArgs = args.map(arg => printArg(arg)).join(', ');
33
+ const prettyProperty = printProperty(property);
34
+ return `${prettyProperty}(${prettyArgs})`;
35
+ };
36
+ const printReturns = ({
37
+ isError,
38
+ isPromise,
39
+ value
40
+ }, min, max) => {
41
+ let thenPrefix = '';
42
+
43
+ if (isPromise) {
44
+ if (isError) {
45
+ thenPrefix += 'thenReject';
46
+ } else {
47
+ thenPrefix += 'thenResolve';
48
+ }
49
+ } else if (isError) {
50
+ thenPrefix += 'thenThrow';
51
+ } else {
52
+ thenPrefix += 'thenReturn';
53
+ }
54
+
55
+ return `.${thenPrefix}(${jestMatcherUtils.printExpected(value)}).between(${min}, ${max})`;
56
+ };
57
+ const printWhen = (property, args) => {
58
+ if (args) {
59
+ return `when(${jestMatcherUtils.EXPECTED_COLOR(`mock${printCall(property, args)}`)})`;
60
+ }
61
+
62
+ return `when(${jestMatcherUtils.EXPECTED_COLOR(`mock${printProperty(property)}`)})`;
63
+ };
64
+ const printExpectation = (property, args, returnValue, min, max) => `${printWhen(property, args)}${printReturns(returnValue, min, max)}`;
65
+ const printRemainingExpectations = expectations => expectations.length ? `Remaining unmet expectations:
66
+ - ${expectations.map(e => e.toJSON()).join('\n - ')}` : 'There are no remaining unmet expectations.';
67
+
68
+ class UnfinishedExpectation extends Error {
69
+ constructor(pendingExpectation) {
70
+ super(`There is an unfinished pending expectation:
71
+
72
+ ${pendingExpectation.toJSON()}
73
+
74
+ Please finish it by setting a return value even if the value
75
+ is undefined.`);
76
+ }
77
+
78
+ }
79
+ class MissingWhen extends Error {
80
+ constructor() {
81
+ super(`You tried setting a return value without an expectation.
82
+
83
+ Every call to set a return value must be preceded by an expectation.`);
84
+ }
85
+
86
+ }
87
+ class UnexpectedAccess extends Error {
88
+ constructor(property, expectations) {
89
+ super(`Didn't expect ${jestMatcherUtils.EXPECTED_COLOR(`mock${printProperty(property)}`)} to be accessed.
90
+
91
+ If you expect this property to be accessed then please
92
+ set an expectation for it.
93
+
94
+ ${printRemainingExpectations(expectations)}`);
95
+ }
96
+
97
+ }
98
+ class UnexpectedCall extends Error {
99
+ constructor(property, args, expectations) {
100
+ super(`Didn't expect ${jestMatcherUtils.EXPECTED_COLOR(`mock${printCall(property, args)}`)} to be called.
101
+
102
+ ${printRemainingExpectations(expectations)}`);
103
+ }
104
+
105
+ }
106
+ class NotAMock extends Error {
107
+ constructor() {
108
+ super(`We couldn't find the mock.
109
+
110
+ Make sure you're passing in an actual mock.`);
111
+ }
112
+
113
+ }
114
+ class UnmetExpectations extends Error {
115
+ constructor(expectations) {
116
+ super(`There are unmet expectations:
117
+
118
+ - ${expectations.map(e => e.toJSON()).join('\n - ')}`);
119
+ }
83
120
 
121
+ }
84
122
  /**
85
- * Use to test if an expectation on an argument is a custom matcher.
86
- */
87
- function isMatcher(f) {
88
- return !!(f && f.__isMatcher);
89
- }
123
+ * Merge property accesses and method calls for the same property
124
+ * into a single call.
125
+ *
126
+ * @example
127
+ * mergeCalls({ foo: [{ arguments: undefined }, { arguments: [1, 2, 3] }] }
128
+ * // returns { foo: [{ arguments: [1, 2, 3] } }
129
+ */
130
+
131
+ const mergeCalls = callMap => new Map(Array.from(callMap.entries()).map(([property, calls]) => {
132
+ const hasMethodCalls = calls.some(call => call.arguments);
133
+ const hasPropertyAccesses = calls.some(call => !call.arguments);
134
+
135
+ if (hasMethodCalls && hasPropertyAccesses) {
136
+ return [property, calls.filter(call => call.arguments)];
137
+ }
138
+
139
+ return [property, calls];
140
+ }));
141
+
142
+ class UnexpectedCalls extends Error {
143
+ constructor(unexpectedCalls, expectations) {
144
+ const printedCalls = Array.from(mergeCalls(unexpectedCalls).entries()).map(([property, calls]) => calls.map(call => call.arguments ? jestMatcherUtils.EXPECTED_COLOR(`mock${printCall(property, call.arguments)}`) : jestMatcherUtils.EXPECTED_COLOR(`mock${printProperty(property)}`)).join('\n - ')).join('\n - ');
145
+ super(`The following calls were unexpected:
146
+
147
+ - ${printedCalls}
148
+
149
+ ${printRemainingExpectations(expectations)}`);
150
+ }
151
+
152
+ }
153
+ class NestedWhen extends Error {
154
+ constructor(parentProp, childProp) {
155
+ const snippet = `
156
+ const parentMock = mock<T1>();
157
+ const childMock = mock<T2>();
158
+
159
+ when(() => childMock${printProperty(childProp)}).thenReturn(...);
160
+ when(() => parentMock${printProperty(parentProp)}).thenReturn(childMock)
161
+ `;
162
+ super(`Setting an expectation on a nested property is not supported.
163
+
164
+ You can return an object directly when the first property is accessed,
165
+ or you can even return a separate mock:
166
+ ${snippet}`);
167
+ }
168
+
169
+ }
170
+
171
+ const createProxy = traps => // eslint-disable-next-line no-empty-function
172
+ new Proxy(
173
+ /* istanbul ignore next */
174
+ () => {}, {
175
+ get: (target, prop) => {
176
+ if (prop === 'bind') {
177
+ return (thisArg, ...args) => (...moreArgs) => traps.apply([...args, ...moreArgs]);
178
+ }
179
+
180
+ if (prop === 'apply') {
181
+ return (thisArg, args) => traps.apply(args || []);
182
+ }
183
+
184
+ if (prop === 'call') {
185
+ return (thisArg, ...args) => traps.apply(args);
186
+ }
187
+
188
+ return traps.property(prop);
189
+ },
190
+ apply: (target, thisArg, args) => traps.apply(args),
191
+ ownKeys: () => traps.ownKeys(),
192
+
193
+ getOwnPropertyDescriptor(target, prop) {
194
+ const keys = traps.ownKeys();
195
+
196
+ if (keys.includes(prop)) {
197
+ return {
198
+ configurable: true,
199
+ enumerable: true
200
+ };
201
+ }
202
+
203
+ return undefined;
204
+ }
205
+
206
+ });
207
+
90
208
  /**
91
- * The default matcher that checks for deep equality.
92
- */
93
- var deepEquals = function (expected) {
94
- return ({
95
- matches: function (received) { return isEqual__default['default'](received, expected); },
96
- __isMatcher: true,
97
- toJSON: function () {
98
- return printArg(expected);
99
- },
100
- });
101
- };
209
+ * Since `when` doesn't receive the mock subject (because we can't make it
210
+ * consistently return it from `mock()`, `mock.foo` and `mock.bar()`) we need
211
+ * to store a global state for the currently active mock.
212
+ *
213
+ * We also want to throw in the following case:
214
+ *
215
+ * ```
216
+ * when(() => mock()) // forgot returns here
217
+ * when(() => mock()) // should throw
218
+ * ```
219
+ *
220
+ * For that reason we can't just store the currently active mock, but also
221
+ * whether we finished the expectation or not.
222
+ */
223
+
224
+ let activeMock;
225
+ const setActiveMock = mock => {
226
+ activeMock = mock;
227
+ };
228
+ const getActiveMock = () => activeMock;
102
229
  /**
103
- * Match any value, including `undefined` and `null`.
230
+ * Store a global map of all mocks created and their state.
104
231
  *
105
- * @example
106
- * const fn = mock<(x: number, y: string) => number>();
107
- * when(fn(It.isAny(), It.isAny()).thenReturn(1);
232
+ * This is needed because we can't reliably pass the state between `when`
233
+ * and `thenReturn`.
234
+ */
235
+
236
+ const mockMap = new Map();
237
+ const getMockState = mock => {
238
+ if (mockMap.has(mock)) {
239
+ return mockMap.get(mock);
240
+ }
241
+
242
+ throw new NotAMock();
243
+ };
244
+ const setMockState = (mock, state) => {
245
+ mockMap.set(mock, state);
246
+ };
247
+ const getAllMocks = () => Array.from(mockMap.entries());
248
+
249
+ /**
250
+ * Return the expectation's return value.
251
+ *
252
+ * If the value is an error then throw it.
108
253
  *
109
- * instance(fn)(23, 'foobar') === 1
110
- */
111
- var isAny = function () { return ({
112
- matches: function () { return true; },
113
- __isMatcher: true,
114
- /**
115
- * Used by `pretty-format`.
116
- */
117
- toJSON: function () {
118
- return 'anything';
119
- },
120
- }); };
254
+ * If the value is a promise then resolve/reject it.
255
+ */
256
+
257
+ const returnOrThrow = ({
258
+ isError,
259
+ isPromise,
260
+ value
261
+ }) => {
262
+ if (isError) {
263
+ if (isPromise) {
264
+ return Promise.reject(value);
265
+ }
266
+
267
+ if (value instanceof Error) {
268
+ throw value;
269
+ }
270
+
271
+ throw new Error(value);
272
+ }
273
+
274
+ if (isPromise) {
275
+ return Promise.resolve(value);
276
+ }
277
+
278
+ return value;
279
+ };
280
+ const createStub = (repo, pendingExpectation, isRecording = () => true) => {
281
+ const stub = createProxy({
282
+ property: property => {
283
+ if (!isRecording()) {
284
+ return returnOrThrow(repo.get(property));
285
+ }
286
+
287
+ setActiveMock(stub);
288
+ pendingExpectation.start(repo); // eslint-disable-next-line no-param-reassign
289
+
290
+ pendingExpectation.property = property;
291
+ return createProxy({
292
+ property: childProp => {
293
+ pendingExpectation.clear();
294
+ throw new NestedWhen(property, childProp);
295
+ },
296
+ apply: args => {
297
+ // eslint-disable-next-line no-param-reassign
298
+ pendingExpectation.args = args;
299
+ },
300
+ ownKeys: () => {
301
+ throw new Error('Spreading during an expectation is not supported.');
302
+ }
303
+ });
304
+ },
305
+ apply: args => {
306
+ if (!isRecording()) {
307
+ const fn = repo.get(ApplyProp); // This is not using `returnOrThrow` because the repo will use it.
308
+
309
+ return fn.value(...args);
310
+ }
311
+
312
+ setActiveMock(stub);
313
+ pendingExpectation.start(repo); // eslint-disable-next-line no-param-reassign
314
+
315
+ pendingExpectation.property = ApplyProp; // eslint-disable-next-line no-param-reassign
316
+
317
+ pendingExpectation.args = args;
318
+ return undefined;
319
+ },
320
+ ownKeys: () => {
321
+ if (!isRecording()) {
322
+ return repo.getAllProperties();
323
+ }
324
+
325
+ throw new Error('Spreading during an expectation is not supported.');
326
+ }
327
+ });
328
+ return stub;
329
+ };
330
+
331
+ class BaseRepository {
332
+ constructor() {
333
+ this.expectations = new Map();
334
+ this.expectedCallStats = new Map();
335
+ this.unexpectedCallStats = new Map();
336
+ }
337
+
338
+ add(expectation) {
339
+ const {
340
+ property
341
+ } = expectation;
342
+ const expectations = this.expectations.get(property) || [];
343
+ this.expectations.set(property, [...expectations, {
344
+ expectation,
345
+ matchCount: 0
346
+ }]);
347
+ }
348
+
349
+ clear() {
350
+ this.expectations.clear();
351
+ this.expectedCallStats.clear();
352
+ this.unexpectedCallStats.clear();
353
+ }
354
+
355
+ get(property) {
356
+ const expectations = this.expectations.get(property);
357
+
358
+ if (expectations && expectations.length) {
359
+ // We record that an expected property access has happened, but an
360
+ // unexpected call could still happen later.
361
+ this.recordExpected(property, undefined);
362
+ const propertyExpectation = expectations.find(e => e.expectation.matches(undefined));
363
+
364
+ if (propertyExpectation) {
365
+ this.countAndConsume(propertyExpectation);
366
+ return propertyExpectation.expectation.returnValue;
367
+ }
368
+
369
+ return {
370
+ value: (...args) => {
371
+ const callExpectation = expectations.find(e => e.expectation.matches(args));
372
+
373
+ if (callExpectation) {
374
+ this.recordExpected(property, args);
375
+ this.countAndConsume(callExpectation); // TODO: this is duplicated in stub
376
+
377
+ return returnOrThrow(callExpectation.expectation.returnValue);
378
+ }
379
+
380
+ this.recordUnexpected(property, args);
381
+ return this.getValueForUnexpectedCall(property, args);
382
+ }
383
+ };
384
+ }
385
+
386
+ switch (property) {
387
+ case 'toString':
388
+ return {
389
+ value: () => 'mock'
390
+ };
391
+
392
+ case '@@toStringTag':
393
+ case Symbol.toStringTag:
394
+ case 'name':
395
+ return {
396
+ value: 'mock'
397
+ };
398
+ // pretty-format
399
+
400
+ case '$$typeof':
401
+ case 'constructor':
402
+ case '@@__IMMUTABLE_ITERABLE__@@':
403
+ case '@@__IMMUTABLE_RECORD__@@':
404
+ return {
405
+ value: null
406
+ };
407
+
408
+ case MATCHER_SYMBOL:
409
+ return {
410
+ value: false
411
+ };
412
+
413
+ case ApplyProp:
414
+ return {
415
+ value: (...args) => {
416
+ this.recordUnexpected(property, args);
417
+ return this.getValueForUnexpectedCall(property, args);
418
+ }
419
+ };
420
+
421
+ default:
422
+ this.recordUnexpected(property, undefined);
423
+ return this.getValueForUnexpectedAccess(property);
424
+ }
425
+ }
426
+
427
+ getAllProperties() {
428
+ return Array.from(this.expectations.keys());
429
+ }
430
+
431
+ getCallStats() {
432
+ return {
433
+ expected: this.expectedCallStats,
434
+ unexpected: this.unexpectedCallStats
435
+ };
436
+ }
437
+
438
+ getUnmet() {
439
+ return [].concat(...Array.from(this.expectations.values()).map(expectations => expectations.filter(e => e.expectation.min > e.matchCount).map(e => e.expectation)));
440
+ }
441
+ /**
442
+ * Record an expected property access/method call.
443
+ */
444
+
445
+
446
+ recordExpected(property, args) {
447
+ const calls = this.expectedCallStats.get(property) || [];
448
+ this.expectedCallStats.set(property, [...calls, {
449
+ arguments: args
450
+ }]);
451
+ }
452
+ /**
453
+ * Record an unexpected property access/method call.
454
+ */
455
+
456
+
457
+ recordUnexpected(property, args) {
458
+ const calls = this.unexpectedCallStats.get(property) || [];
459
+ this.unexpectedCallStats.set(property, [...calls, {
460
+ arguments: args
461
+ }]);
462
+ }
463
+
464
+ countAndConsume(expectation) {
465
+ // eslint-disable-next-line no-param-reassign
466
+ expectation.matchCount++;
467
+ this.consumeExpectation(expectation);
468
+ }
469
+
470
+ }
471
+
472
+ /**
473
+ * Throw if no expectation matches.
474
+ */
475
+
476
+ class StrongRepository extends BaseRepository {
477
+ consumeExpectation(expectation) {
478
+ const {
479
+ property,
480
+ max
481
+ } = expectation.expectation;
482
+ const expectations = this.expectations.get(property);
483
+
484
+ if (expectation.matchCount === max) {
485
+ this.expectations.set(property, expectations.filter(e => e !== expectation));
486
+ }
487
+ }
488
+
489
+ getValueForUnexpectedCall(property, args) {
490
+ throw new UnexpectedCall(property, args, this.getUnmet());
491
+ }
492
+
493
+ getValueForUnexpectedAccess(property) {
494
+ throw new UnexpectedAccess(property, this.getUnmet());
495
+ }
496
+
497
+ }
498
+
499
+ /**
500
+ * Matches a call with more parameters than expected because it is assumed the
501
+ * compiler will check that those parameters are optional.
502
+ *
503
+ * @example
504
+ * new StrongExpectation(
505
+ * 'bar',
506
+ * deepEquals([1, 2, 3]),
507
+ * 23
508
+ * ).matches('bar', [1, 2, 3]) === true;
509
+ */
510
+
511
+ class StrongExpectation {
512
+ constructor(property, args, returnValue) {
513
+ this.property = void 0;
514
+ this.args = void 0;
515
+ this.returnValue = void 0;
516
+ this.matched = 0;
517
+ this.min = 1;
518
+ this.max = 1;
519
+ this.property = property;
520
+ this.args = args;
521
+ this.returnValue = returnValue;
522
+ }
523
+
524
+ setInvocationCount(min, max = 1) {
525
+ this.min = min;
526
+ this.max = max;
527
+ }
528
+
529
+ matches(args) {
530
+ if (!this.matchesArgs(args)) {
531
+ return false;
532
+ }
533
+
534
+ this.matched++;
535
+ return this.max === 0 || this.matched <= this.max;
536
+ }
537
+
538
+ isUnmet() {
539
+ return this.matched < this.min;
540
+ }
541
+
542
+ matchesArgs(received) {
543
+ if (this.args === undefined) {
544
+ return !received;
545
+ }
546
+
547
+ if (!received) {
548
+ return false;
549
+ }
550
+
551
+ return this.args.every((arg, i) => arg.matches(received[i]));
552
+ }
553
+
554
+ toJSON() {
555
+ return printExpectation(this.property, this.args, this.returnValue, this.min, this.max);
556
+ }
557
+
558
+ }
559
+
560
+ class RepoSideEffectPendingExpectation {
561
+ constructor(createExpectation) {
562
+ this.createExpectation = void 0;
563
+ this._repo = void 0;
564
+ this._args = void 0;
565
+ this._property = '';
566
+ this.createExpectation = createExpectation;
567
+ }
568
+
569
+ start(repo) {
570
+ if (this._repo) {
571
+ throw new UnfinishedExpectation(this);
572
+ }
573
+
574
+ this.clear();
575
+ this._repo = repo;
576
+ }
577
+
578
+ set property(value) {
579
+ this._property = value;
580
+ }
581
+
582
+ set args(value) {
583
+ this._args = value;
584
+ }
585
+
586
+ finish(returnValue) {
587
+ if (!this._repo) {
588
+ throw new MissingWhen();
589
+ }
590
+
591
+ const expectation = this.createExpectation(this._property, this._args, returnValue);
592
+
593
+ this._repo.add(expectation);
594
+
595
+ this.clear();
596
+ return expectation;
597
+ }
598
+
599
+ clear() {
600
+ this._repo = undefined;
601
+ this._args = undefined;
602
+ this._property = '';
603
+ }
604
+
605
+ toJSON() {
606
+ return printWhen(this._property, this._args);
607
+ }
608
+
609
+ }
610
+
611
+ function _extends() {
612
+ _extends = Object.assign || function (target) {
613
+ for (var i = 1; i < arguments.length; i++) {
614
+ var source = arguments[i];
615
+
616
+ for (var key in source) {
617
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
618
+ target[key] = source[key];
619
+ }
620
+ }
621
+ }
622
+
623
+ return target;
624
+ };
625
+
626
+ return _extends.apply(this, arguments);
627
+ }
628
+
121
629
  /**
122
630
  * Match a custom predicate.
123
631
  *
124
632
  * @param cb Will receive the value and returns whether it matches.
633
+ * @param toJSON An optional function that should return a string that will be
634
+ * used when the matcher needs to be printed in an error message. By default,
635
+ * it stringifies `cb`.
125
636
  *
126
637
  * @example
127
638
  * const fn = mock<(x: number) => number>();
128
- * when(fn(It.matches(x => x >= 0)).returns(42);
639
+ * when(() => fn(It.matches(x => x >= 0))).returns(42);
640
+ *
641
+ * fn(2) === 42
642
+ * fn(-1) // throws
643
+ */
644
+
645
+ const matches = (cb, {
646
+ toJSON = () => `matches(${cb.toString()})`
647
+ } = {}) => {
648
+ const matcher = {
649
+ [MATCHER_SYMBOL]: true,
650
+ matches: arg => cb(arg),
651
+ toJSON
652
+ };
653
+ return matcher;
654
+ };
655
+
656
+ const removeUndefined = object => {
657
+ if (Array.isArray(object)) {
658
+ return object.map(x => removeUndefined(x));
659
+ }
660
+
661
+ if (!lodash.isObjectLike(object)) {
662
+ return object;
663
+ }
664
+
665
+ return lodash.omitBy(object, lodash.isUndefined);
666
+ };
667
+ /**
668
+ * Compare values using deep equality.
669
+ *
670
+ * @param expected
671
+ * @param strict By default, this matcher will treat a missing key in an object
672
+ * and a key with the value `undefined` as not equal. It will also consider
673
+ * non `Object` instances with different constructors as not equal. Setting
674
+ * this to `false` will consider the objects in both cases as equal.
675
+ *
676
+ * @see It.is A matcher that uses strict equality.
677
+ */
678
+
679
+
680
+ const deepEquals = (expected, {
681
+ strict = true
682
+ } = {}) => matches(actual => {
683
+ if (strict) {
684
+ return lodash.isEqual(actual, expected);
685
+ }
686
+
687
+ return lodash.isEqual(removeUndefined(actual), removeUndefined(expected));
688
+ }, {
689
+ toJSON: () => printArg(expected)
690
+ });
691
+ /**
692
+ * Compare values using `Object.is`.
693
+ *
694
+ * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
695
+ *
696
+ * @see It.deepEquals A matcher that uses deep equality.
697
+ */
698
+
699
+
700
+ const is = expected => matches(actual => Object.is(actual, expected), {
701
+ toJSON: () => `${jestMatcherUtils.printExpected(expected)}`
702
+ });
703
+ /**
704
+ * Match any value, including `undefined` and `null`.
129
705
  *
130
- * instance(fn)(2) === 42
131
- * instance(fn)(-1) // throws
132
- */
133
- var matches = function (cb) {
134
- return ({
135
- matches: function (arg) { return cb(arg); },
136
- __isMatcher: true,
137
- toJSON: function () {
138
- return "matches(" + cb.toString() + ")";
139
- },
140
- });
141
- };
706
+ * @example
707
+ * const fn = mock<(x: number, y: string) => number>();
708
+ * when(() => fn(It.isAny(), It.isAny())).thenReturn(1);
709
+ *
710
+ * fn(23, 'foobar') === 1
711
+ */
712
+
713
+
714
+ const isAny = () => matches(() => true, {
715
+ toJSON: () => 'anything'
716
+ });
142
717
  /**
143
718
  * Recursively match an object.
144
719
  *
@@ -148,48 +723,41 @@ var matches = function (cb) {
148
723
  *
149
724
  * @example
150
725
  * const fn = mock<(foo: { x: number, y: number }) => number>();
151
- * when(fn(It.isObject({ x: 23 }).returns(42);
726
+ * when(() => fn(It.isObject({ x: 23 }))).returns(42);
152
727
  *
153
- * instance(fn)({ x: 100, y: 200 }) // throws
154
- * instance(fn)({ x: 23, y: 200 }) // returns 42
728
+ * fn({ x: 100, y: 200 }) // throws
729
+ * fn({ x: 23, y: 200 }) // returns 42
155
730
  *
156
731
  * @example
157
732
  * It.isObject({ foo: It.isString() })
158
- */
159
- var isObject = function (partial) {
160
- return ({
161
- __isMatcher: true,
162
- matches: function (arg) {
163
- return isMatchWith__default['default'](arg, partial || {}, function (argValue, partialValue) {
164
- if (isMatcher(partialValue)) {
165
- return partialValue.matches(argValue);
166
- }
167
- // Let lodash handle it otherwise.
168
- return undefined;
169
- });
170
- },
171
- toJSON: function () {
172
- return partial ? "object(" + jestMatcherUtils.printExpected(partial) + ")" : 'object';
173
- },
174
- });
175
- };
733
+ */
734
+
735
+
736
+ const isObject = partial => matches(actual => lodash.isMatchWith(actual, partial || {}, (argValue, partialValue) => {
737
+ if (isMatcher(partialValue)) {
738
+ return partialValue.matches(argValue);
739
+ } // Let lodash handle it otherwise.
740
+
741
+
742
+ return undefined;
743
+ }), {
744
+ toJSON: () => partial ? `object(${jestMatcherUtils.printExpected(partial)})` : 'object'
745
+ });
176
746
  /**
177
747
  * Match any number.
178
748
  *
179
749
  * @example
180
750
  * const fn = mock<(x: number) => number>();
181
- * when(fn(It.isNumber()).returns(42);
751
+ * when(() => fn(It.isNumber())).returns(42);
182
752
  *
183
- * instance(fn)(20.5) === 42
184
- * instance(fn)(NaN) // throws
185
- */
186
- var isNumber = function () {
187
- return ({
188
- __isMatcher: true,
189
- matches: function (arg) { return typeof arg === 'number' && !Number.isNaN(arg); },
190
- toJSON: function () { return 'number'; },
191
- });
192
- };
753
+ * fn(20.5) === 42
754
+ * fn(NaN) // throws
755
+ */
756
+
757
+
758
+ const isNumber = () => matches(actual => typeof actual === 'number' && !Number.isNaN(actual), {
759
+ toJSON: () => 'number'
760
+ });
193
761
  /**
194
762
  * Match a string, potentially by a pattern.
195
763
  *
@@ -198,35 +766,37 @@ var isNumber = function () {
198
766
  *
199
767
  * @example
200
768
  * const fn = mock<(x: string, y: string) => number>();
201
- * when(fn(It.isString(), It.isString({ containing: 'bar' }).returns(42);
769
+ * when(() => fn(It.isString(), It.isString({ containing: 'bar' }))).returns(42);
202
770
  *
203
- * instance(fn)('foo', 'baz') // throws
204
- * instance(fn)('foo', 'bar') === 42
205
- */
206
- var isString = function (_a) {
207
- var _b = _a === void 0 ? {} : _a, matching = _b.matching, containing = _b.containing;
208
- if (matching && containing) {
209
- throw new Error('You can only pass `matching` or `containing`, not both.');
210
- }
211
- return {
212
- __isMatcher: true,
213
- matches: function (arg) {
214
- var _a;
215
- if (typeof arg !== 'string') {
216
- return false;
217
- }
218
- if (containing) {
219
- return arg.indexOf(containing) !== -1;
220
- }
221
- return (_a = matching === null || matching === void 0 ? void 0 : matching.test(arg)) !== null && _a !== void 0 ? _a : true;
222
- },
223
- toJSON: function () {
224
- return containing || matching
225
- ? "string(" + jestMatcherUtils.printExpected(containing || matching) + ")"
226
- : 'string';
227
- },
228
- };
229
- };
771
+ * fn('foo', 'baz') // throws
772
+ * fn('foo', 'bar') === 42
773
+ */
774
+
775
+
776
+ const isString = ({
777
+ matching,
778
+ containing
779
+ } = {}) => {
780
+ if (matching && containing) {
781
+ throw new Error('You can only pass `matching` or `containing`, not both.');
782
+ }
783
+
784
+ return matches(actual => {
785
+ var _matching$test;
786
+
787
+ if (typeof actual !== 'string') {
788
+ return false;
789
+ }
790
+
791
+ if (containing) {
792
+ return actual.indexOf(containing) !== -1;
793
+ }
794
+
795
+ return (_matching$test = matching == null ? void 0 : matching.test(actual)) != null ? _matching$test : true;
796
+ }, {
797
+ toJSON: () => containing || matching ? `string(${jestMatcherUtils.printExpected(containing || matching)})` : 'string'
798
+ });
799
+ };
230
800
  /**
231
801
  * Match an array.
232
802
  *
@@ -237,45 +807,42 @@ var isString = function (_a) {
237
807
  *
238
808
  * @example
239
809
  * const fn = mock<(arr: number[]) => number>();
240
- * when(fn(It.isArray())).thenReturn(1);
241
- * when(fn(It.isArray([2, 3))).thenReturn(2);
810
+ * when(() => fn(It.isArray())).thenReturn(1);
811
+ * when(() => fn(It.isArray([2, 3]))).thenReturn(2);
242
812
  *
243
- * instance(fn)({ length: 1, 0: 42 }) // throws
244
- * instance(fn)([]]) === 1
245
- * instance(fn)([3, 2, 1) === 2
813
+ * fn({ length: 1, 0: 42 }) // throws
814
+ * fn([]) === 1
815
+ * fn([3, 2, 1]) === 2
246
816
  *
247
817
  * @example
248
- * It.isArray([It.isString({ containing: 'foobar' }))
249
- */
250
- var isArray = function (containing) {
251
- return ({
252
- __isMatcher: true,
253
- matches: function (arg) {
254
- if (!Array.isArray(arg)) {
255
- return false;
256
- }
257
- if (!containing) {
258
- return true;
259
- }
260
- return containing.every(function (x) {
261
- return arg.find(function (y) {
262
- if (isMatcher(x)) {
263
- return x.matches(y);
264
- }
265
- return isEqual__default['default'](x, y);
266
- }) !== undefined;
267
- });
268
- },
269
- toJSON: function () {
270
- return containing ? "array(" + jestMatcherUtils.printExpected(containing) + ")" : 'array';
271
- },
272
- });
273
- };
818
+ * It.isArray([It.isString({ containing: 'foobar' })])
819
+ */
820
+
821
+
822
+ const isArray = containing => matches(actual => {
823
+ if (!Array.isArray(actual)) {
824
+ return false;
825
+ }
826
+
827
+ if (!containing) {
828
+ return true;
829
+ }
830
+
831
+ return containing.every(x => actual.find(y => {
832
+ if (isMatcher(x)) {
833
+ return x.matches(y);
834
+ }
835
+
836
+ return deepEquals(x).matches(y);
837
+ }) !== undefined);
838
+ }, {
839
+ toJSON: () => containing ? `array(${jestMatcherUtils.printExpected(containing)})` : 'array'
840
+ });
274
841
  /**
275
842
  * Matches anything and stores the received value.
276
843
  *
277
844
  * This should not be needed for most cases, but can be useful if you need
278
- * access to a complex argument outside of the expectation e.g. to test a
845
+ * access to a complex argument outside the expectation e.g. to test a
279
846
  * callback.
280
847
  *
281
848
  * @param name If given, this name will be printed in error messages.
@@ -283,620 +850,230 @@ var isArray = function (containing) {
283
850
  * @example
284
851
  * const fn = mock<(cb: (value: number) => number) => void>();
285
852
  * const matcher = It.willCapture();
286
- * when(fn(matcher)).thenReturn();
853
+ * when(() => fn(matcher)).thenReturn();
287
854
  *
288
- * instance(fn)(x => x + 1);
855
+ * fn(x => x + 1);
289
856
  * matcher.value?.(3) === 4
290
- */
291
- var willCapture = function (name) {
292
- var capturedValue;
293
- return {
294
- __isMatcher: true,
295
- matches: function (value) {
296
- capturedValue = value;
297
- return true;
298
- },
299
- toJSON: function () {
300
- return name !== null && name !== void 0 ? name : 'captures';
301
- },
302
- get value() {
303
- return capturedValue;
304
- },
305
- };
306
- };
857
+ */
858
+
859
+
860
+ const willCapture = name => {
861
+ let capturedValue;
862
+ const matcher = {
863
+ [MATCHER_SYMBOL]: true,
864
+ matches: actual => {
865
+ capturedValue = actual;
866
+ return true;
867
+ },
868
+ toJSON: () => name != null ? name : 'captures',
869
+
870
+ get value() {
871
+ return capturedValue;
872
+ }
873
+
874
+ };
875
+ return matcher;
876
+ };
307
877
  /**
308
878
  * Contains argument matchers that can be used to ignore arguments in an
309
879
  * expectation or to match complex arguments.
310
- */
311
- var It = {
312
- isAny: isAny,
313
- matches: matches,
314
- isObject: isObject,
315
- isNumber: isNumber,
316
- isString: isString,
317
- isArray: isArray,
318
- willCapture: willCapture,
319
- };
880
+ */
881
+
320
882
 
321
- var printProperty = function (property) {
322
- if (property === ApplyProp) {
323
- return '';
324
- }
325
- if (typeof property === 'symbol') {
326
- return "[" + property.toString() + "]";
327
- }
328
- return "." + property;
329
- };
330
- var printArg = function (arg) {
331
- // Call toJSON on matchers directly to avoid wrapping them in quotes.
332
- return isMatcher(arg) ? arg.toJSON() : jestMatcherUtils.printExpected(arg);
333
- };
334
- var printCall = function (property, args) {
335
- // TODO: don't leak the matcher concept here
336
- var prettyArgs = args.map(function (arg) { return printArg(arg); }).join(', ');
337
- var prettyProperty = printProperty(property);
338
- return prettyProperty + "(" + prettyArgs + ")";
339
- };
340
- var printReturns = function (_a, min, max) {
341
- var isError = _a.isError, isPromise = _a.isPromise, value = _a.value;
342
- var thenPrefix = '';
343
- if (isPromise) {
344
- if (isError) {
345
- thenPrefix += 'thenReject';
346
- }
347
- else {
348
- thenPrefix += 'thenResolve';
349
- }
350
- }
351
- else if (isError) {
352
- thenPrefix += 'thenThrow';
353
- }
354
- else {
355
- thenPrefix += 'thenReturn';
356
- }
357
- return "." + thenPrefix + "(" + jestMatcherUtils.printExpected(value) + ").between(" + min + ", " + max + ")";
358
- };
359
- var printWhen = function (property, args) {
360
- if (args) {
361
- return "when(" + jestMatcherUtils.EXPECTED_COLOR("mock" + printCall(property, args)) + ")";
362
- }
363
- return "when(" + jestMatcherUtils.EXPECTED_COLOR("mock" + printProperty(property)) + ")";
364
- };
365
- var printExpectation = function (property, args, returnValue, min, max) { return "" + printWhen(property, args) + printReturns(returnValue, min, max); };
366
- var printRemainingExpectations = function (expectations) {
367
- return expectations.length
368
- ? "Remaining unmet expectations:\n - " + expectations.map(function (e) { return e.toJSON(); }).join('\n - ')
369
- : 'There are no remaining unmet expectations.';
883
+ const It = {
884
+ matches,
885
+ deepEquals,
886
+ is,
887
+ isAny,
888
+ isObject,
889
+ isNumber,
890
+ isString,
891
+ isArray,
892
+ willCapture
370
893
  };
371
894
 
372
- var UnfinishedExpectation = /** @class */ (function (_super) {
373
- __extends(UnfinishedExpectation, _super);
374
- function UnfinishedExpectation(pendingExpectation) {
375
- return _super.call(this, "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\nThis may have been caused by using the mock without getting\nan instance from it first. Please use instance(mock) and use\nthat value in the code you're testing.") || this;
376
- }
377
- return UnfinishedExpectation;
378
- }(Error));
379
- var MissingWhen = /** @class */ (function (_super) {
380
- __extends(MissingWhen, _super);
381
- function MissingWhen() {
382
- return _super.call(this, "You tried setting a return value without an expectation.\n\nEvery call to set a return value must be preceded by an expectation.") || this;
383
- }
384
- return MissingWhen;
385
- }(Error));
386
- var UnexpectedAccess = /** @class */ (function (_super) {
387
- __extends(UnexpectedAccess, _super);
388
- function UnexpectedAccess(property, expectations) {
389
- return _super.call(this, "Didn't expect " + jestMatcherUtils.EXPECTED_COLOR("mock" + printProperty(property)) + " to be accessed.\n\nIf you expect this property to be accessed then please\nset an expectation for it.\n\n" + printRemainingExpectations(expectations)) || this;
390
- }
391
- return UnexpectedAccess;
392
- }(Error));
393
- var UnexpectedCall = /** @class */ (function (_super) {
394
- __extends(UnexpectedCall, _super);
395
- function UnexpectedCall(property, args, expectations) {
396
- return _super.call(this, "Didn't expect " + jestMatcherUtils.EXPECTED_COLOR("mock" + printCall(property, args)) + " to be called.\n\n" + printRemainingExpectations(expectations)) || this;
397
- }
398
- return UnexpectedCall;
399
- }(Error));
400
- var NotAMock = /** @class */ (function (_super) {
401
- __extends(NotAMock, _super);
402
- function NotAMock() {
403
- return _super.call(this, "We couldn't find the mock.\n\nMake sure you're passing in an actual mock.") || this;
404
- }
405
- return NotAMock;
406
- }(Error));
407
- var UnmetExpectations = /** @class */ (function (_super) {
408
- __extends(UnmetExpectations, _super);
409
- function UnmetExpectations(expectations) {
410
- return _super.call(this, "There are unmet expectations:\n\n - " + expectations.map(function (e) { return e.toJSON(); }).join('\n - ')) || this;
411
- }
412
- return UnmetExpectations;
413
- }(Error));
895
+ const defaults = {
896
+ matcher: It.deepEquals
897
+ };
898
+ let currentDefaults = defaults;
414
899
  /**
415
- * Merge property accesses and method calls for the same property
416
- * into a single call.
900
+ * Override strong-mock's defaults.
417
901
  *
418
- * @example
419
- * mergeCalls({ foo: [{ arguments: undefined }, { arguments: [1, 2, 3] }] }
420
- * // returns { foo: [{ arguments: [1, 2, 3] } }
421
- */
422
- var mergeCalls = function (callMap) {
423
- return new Map(Array.from(callMap.entries()).map(function (_a) {
424
- var _b = __read(_a, 2), property = _b[0], calls = _b[1];
425
- var hasMethodCalls = calls.some(function (call) { return call.arguments; });
426
- var hasPropertyAccesses = calls.some(function (call) { return !call.arguments; });
427
- if (hasMethodCalls && hasPropertyAccesses) {
428
- return [property, calls.filter(function (call) { return call.arguments; })];
429
- }
430
- return [property, calls];
431
- }));
432
- };
433
- var UnexpectedCalls = /** @class */ (function (_super) {
434
- __extends(UnexpectedCalls, _super);
435
- function UnexpectedCalls(unexpectedCalls, expectations) {
436
- var _this = this;
437
- var printedCalls = Array.from(mergeCalls(unexpectedCalls).entries())
438
- .map(function (_a) {
439
- var _b = __read(_a, 2), property = _b[0], calls = _b[1];
440
- return calls
441
- .map(function (call) {
442
- return call.arguments
443
- ? jestMatcherUtils.EXPECTED_COLOR("mock" + printCall(property, call.arguments))
444
- : jestMatcherUtils.EXPECTED_COLOR("mock" + printProperty(property));
445
- })
446
- .join('\n - ');
447
- })
448
- .join('\n - ');
449
- _this = _super.call(this, "The following calls were unexpected:\n\n - " + printedCalls + "\n\n" + printRemainingExpectations(expectations)) || this;
450
- return _this;
451
- }
452
- return UnexpectedCalls;
453
- }(Error));
454
- var NestedWhen = /** @class */ (function (_super) {
455
- __extends(NestedWhen, _super);
456
- function NestedWhen(parentProp, childProp) {
457
- var _this = this;
458
- var snippet = "\nconst parentMock = mock<T1>();\nconst childMock = mock<T2>();\n\nwhen(childMock" + printProperty(childProp) + ").thenReturn(...);\nwhen(parentMock" + printProperty(parentProp) + ").thenReturn(instance(childMock))\n";
459
- _this = _super.call(this, "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) || this;
460
- return _this;
461
- }
462
- return NestedWhen;
463
- }(Error));
902
+ * @param newDefaults These will be applied to the library defaults. Multiple
903
+ * calls don't stack e.g. calling this with `{}` will clear any previously
904
+ * applied defaults.
905
+ */
906
+
907
+ const setDefaults = newDefaults => {
908
+ currentDefaults = _extends({}, defaults, newDefaults);
909
+ };
464
910
 
911
+ const strongExpectationFactory = (property, args, returnValue) => new StrongExpectation(property, // Wrap every non-matcher in the default matcher.
912
+ args == null ? void 0 : args.map(arg => isMatcher(arg) ? arg : currentDefaults.matcher(arg)), returnValue);
913
+
914
+ let isRecording = false;
915
+ const setRecording = recording => {
916
+ isRecording = recording;
917
+ };
465
918
  /**
466
- * Since `when()` doesn't receive the mock subject (because we can't make it
467
- * consistently return it from `mock()`, `mock.foo` and `mock.bar()`) we need
468
- * to store a global state for the currently active mock.
919
+ * Create a type safe mock.
469
920
  *
470
- * We also want to throw in the following case:
921
+ * @see {@link when} Set expectations on the mock using `when`.
471
922
  *
472
- * ```
473
- * when(mock()) // forgot returns here
474
- * when(mock()) // should throw
475
- * ```
923
+ * @example
924
+ * const fn = mock<() => number>();
476
925
  *
477
- * For that reason we can't just store the currently active mock, but also
478
- * whether we finished the expectation or not.
479
- */
480
- var activeMock;
481
- var setActiveMock = function (mock) {
482
- activeMock = mock;
483
- };
484
- var getActiveMock = function () { return activeMock; };
485
- /**
486
- * Store a global map of all mocks created and their state.
926
+ * when(() => fn()).thenReturn(23);
487
927
  *
488
- * This is needed because we can't reliably pass the state between `when`,
489
- * `thenReturn` and `instance`.
490
- */
491
- var mockMap = new Map();
492
- var getMockState = function (mock) {
493
- if (mockMap.has(mock)) {
494
- return mockMap.get(mock);
495
- }
496
- throw new NotAMock();
497
- };
498
- var setMockState = function (mock, state) {
499
- mockMap.set(mock, state);
500
- };
501
- var getAllMocks = function () {
502
- return Array.from(mockMap.entries());
503
- };
928
+ * fn() === 23;
929
+ */
504
930
 
505
- var createProxy = function (traps) {
506
- // eslint-disable-next-line no-empty-function
507
- return new Proxy(/* istanbul ignore next */ function () { }, {
508
- get: function (target, prop) {
509
- if (prop === 'bind') {
510
- return function (thisArg) {
511
- var args = [];
512
- for (var _i = 1; _i < arguments.length; _i++) {
513
- args[_i - 1] = arguments[_i];
514
- }
515
- return function () {
516
- var moreArgs = [];
517
- for (var _i = 0; _i < arguments.length; _i++) {
518
- moreArgs[_i] = arguments[_i];
519
- }
520
- return traps.apply(__spreadArray(__spreadArray([], __read(args), false), __read(moreArgs)));
521
- };
522
- };
523
- }
524
- if (prop === 'apply') {
525
- return function (thisArg, args) {
526
- return traps.apply(args || []);
527
- };
528
- }
529
- if (prop === 'call') {
530
- return function (thisArg) {
531
- var args = [];
532
- for (var _i = 1; _i < arguments.length; _i++) {
533
- args[_i - 1] = arguments[_i];
534
- }
535
- return traps.apply(args);
536
- };
537
- }
538
- return traps.property(prop);
539
- },
540
- apply: function (target, thisArg, args) { return traps.apply(args); },
541
- ownKeys: function () { return traps.ownKeys(); },
542
- getOwnPropertyDescriptor: function (target, prop) {
543
- var keys = traps.ownKeys();
544
- if (keys.includes(prop)) {
545
- return {
546
- configurable: true,
547
- enumerable: true,
548
- };
549
- }
550
- return undefined;
551
- },
552
- });
931
+ const mock = ({
932
+ repository = new StrongRepository(),
933
+ expectationFactory = strongExpectationFactory
934
+ } = {}) => {
935
+ const pendingExpectation = new RepoSideEffectPendingExpectation(expectationFactory);
936
+ const stub = createStub(repository, pendingExpectation, () => isRecording);
937
+ setMockState(stub, {
938
+ repository,
939
+ pendingExpectation
940
+ });
941
+ return stub;
553
942
  };
554
943
 
944
+ const createInvocationCount = expectation => ({
945
+ between(min, max) {
946
+ expectation.setInvocationCount(min, max);
947
+ },
948
+
949
+ /* istanbul ignore next */
950
+ times(exact) {
951
+ expectation.setInvocationCount(exact, exact);
952
+ },
953
+
954
+ /* istanbul ignore next */
955
+ anyTimes() {
956
+ expectation.setInvocationCount(0, 0);
957
+ },
958
+
959
+ /* istanbul ignore next */
960
+ atLeast(min) {
961
+ expectation.setInvocationCount(min, Infinity);
962
+ },
963
+
964
+ /* istanbul ignore next */
965
+ atMost(max) {
966
+ expectation.setInvocationCount(0, max);
967
+ },
968
+
969
+ /* istanbul ignore next */
970
+ once() {
971
+ expectation.setInvocationCount(1, 1);
972
+ },
973
+
974
+ /* istanbul ignore next */
975
+ twice() {
976
+ expectation.setInvocationCount(2, 2);
977
+ }
978
+ /* eslint-enable no-param-reassign, no-multi-assign */
979
+
980
+
981
+ });
982
+
555
983
  /**
556
- * Return the expectation's return value.
557
- *
558
- * If the value is an error then throw it.
559
- *
560
- * If the value is a promise then resolve/reject it.
561
- */
562
- var returnOrThrow = function (_a) {
563
- var isError = _a.isError, isPromise = _a.isPromise, value = _a.value;
564
- if (isError) {
565
- if (isPromise) {
566
- return Promise.reject(value);
567
- }
568
- if (value instanceof Error) {
569
- throw value;
570
- }
571
- throw new Error(value);
572
- }
573
- if (isPromise) {
574
- return Promise.resolve(value);
575
- }
576
- return value;
577
- };
578
- /**
579
- * Get a real instance from the mock that you can pass to your code under test.
580
- */
581
- var instance = function (mock) {
582
- var repository = getMockState(mock).repository;
583
- return createProxy({
584
- property: function (property) { return returnOrThrow(repository.get(property)); },
585
- apply: function (args) {
586
- var fn = repository.get(ApplyProp);
587
- // This is not using `returnOrThrow` because the repo will use it.
588
- return fn.value.apply(fn, __spreadArray([], __read(args)));
589
- },
590
- ownKeys: function () { return repository.getAllProperties(); },
591
- });
984
+ * Set a return value for the currently pending expectation.
985
+ */
986
+
987
+ const finishPendingExpectation = (returnValue, pendingExpectation) => {
988
+ const finishedExpectation = pendingExpectation.finish(returnValue);
989
+ pendingExpectation.clear();
990
+ return createInvocationCount(finishedExpectation);
592
991
  };
593
992
 
594
- var RepoSideEffectPendingExpectation = /** @class */ (function () {
595
- function RepoSideEffectPendingExpectation(createExpectation) {
596
- this.createExpectation = createExpectation;
597
- this._property = '';
598
- }
599
- RepoSideEffectPendingExpectation.prototype.start = function (repo) {
600
- if (this._repo) {
601
- throw new UnfinishedExpectation(this);
602
- }
603
- this.clear();
604
- this._repo = repo;
605
- };
606
- Object.defineProperty(RepoSideEffectPendingExpectation.prototype, "property", {
607
- set: function (value) {
608
- this._property = value;
609
- },
610
- enumerable: false,
611
- configurable: true
612
- });
613
- Object.defineProperty(RepoSideEffectPendingExpectation.prototype, "args", {
614
- set: function (value) {
615
- this._args = value;
616
- },
617
- enumerable: false,
618
- configurable: true
619
- });
620
- RepoSideEffectPendingExpectation.prototype.finish = function (returnValue) {
621
- if (!this._repo) {
622
- throw new MissingWhen();
623
- }
624
- var expectation = this.createExpectation(this._property, this._args, returnValue);
625
- this._repo.add(expectation);
626
- this.clear();
627
- return expectation;
628
- };
629
- RepoSideEffectPendingExpectation.prototype.clear = function () {
630
- this._repo = undefined;
631
- this._args = undefined;
632
- this._property = '';
633
- };
634
- RepoSideEffectPendingExpectation.prototype.toJSON = function () {
635
- return printWhen(this._property, this._args);
636
- };
637
- return RepoSideEffectPendingExpectation;
638
- }());
993
+ const getError = errorOrMessage => {
994
+ if (typeof errorOrMessage === 'string') {
995
+ return new Error(errorOrMessage);
996
+ }
639
997
 
640
- /**
641
- * Deeply compare actual arguments against expected ones.
642
- *
643
- * Supports argument matchers. Matches a call with more parameters
644
- * than expected because it is assumed the compiler will check that those
645
- * parameters are optional.
646
- *
647
- * @example
648
- * new Expectation('bar', [1, 2, 3], 23).matches('bar', [1, 2, 3]) === true;
649
- * new Expectation('bar', [1, 2, 3], 23).matches('bar', [1, 2]) === false;
650
- * new Expectation('bar', [1, 2], 23).matches('bar', [1, 2, 3]) === true;
651
- */
652
- var StrongExpectation = /** @class */ (function () {
653
- function StrongExpectation(property, args, returnValue) {
654
- this.property = property;
655
- this.args = args;
656
- this.returnValue = returnValue;
657
- this.matched = 0;
658
- this.min = 1;
659
- this.max = 1;
660
- }
661
- StrongExpectation.prototype.setInvocationCount = function (min, max) {
662
- if (max === void 0) { max = 1; }
663
- this.min = min;
664
- this.max = max;
665
- };
666
- StrongExpectation.prototype.matches = function (args) {
667
- if (!this.matchesArgs(args)) {
668
- return false;
669
- }
670
- this.matched++;
671
- return this.max === 0 || this.matched <= this.max;
672
- };
673
- StrongExpectation.prototype.isUnmet = function () {
674
- return this.matched < this.min;
675
- };
676
- StrongExpectation.prototype.matchesArgs = function (received) {
677
- if (this.args === undefined) {
678
- return !received;
679
- }
680
- if (!received) {
681
- return false;
682
- }
683
- return this.args.every(function (arg, i) { return arg.matches(received[i]); });
684
- };
685
- StrongExpectation.prototype.toJSON = function () {
686
- return printExpectation(this.property, this.args, this.returnValue, this.min, this.max);
687
- };
688
- return StrongExpectation;
689
- }());
690
-
691
- var BaseRepository = /** @class */ (function () {
692
- function BaseRepository() {
693
- this.expectations = new Map();
694
- this.expectedCallStats = new Map();
695
- this.unexpectedCallStats = new Map();
696
- }
697
- BaseRepository.prototype.add = function (expectation) {
698
- var property = expectation.property;
699
- var expectations = this.expectations.get(property) || [];
700
- this.expectations.set(property, __spreadArray(__spreadArray([], __read(expectations), false), [
701
- {
702
- expectation: expectation,
703
- matchCount: 0,
704
- },
705
- ]));
706
- };
707
- BaseRepository.prototype.clear = function () {
708
- this.expectations.clear();
709
- this.expectedCallStats.clear();
710
- this.unexpectedCallStats.clear();
711
- };
712
- BaseRepository.prototype.get = function (property) {
713
- var _this = this;
714
- var expectations = this.expectations.get(property);
715
- if (expectations && expectations.length) {
716
- // We record that an expected property access has happened, but an
717
- // unexpected call could still happen later.
718
- this.recordExpected(property, undefined);
719
- var propertyExpectation = expectations.find(function (e) {
720
- return e.expectation.matches(undefined);
721
- });
722
- if (propertyExpectation) {
723
- this.countAndConsume(propertyExpectation);
724
- return propertyExpectation.expectation.returnValue;
725
- }
726
- return {
727
- value: function () {
728
- var args = [];
729
- for (var _i = 0; _i < arguments.length; _i++) {
730
- args[_i] = arguments[_i];
731
- }
732
- var callExpectation = expectations.find(function (e) {
733
- return e.expectation.matches(args);
734
- });
735
- if (callExpectation) {
736
- _this.recordExpected(property, args);
737
- _this.countAndConsume(callExpectation);
738
- // TODO: this is duplicated in instance
739
- return returnOrThrow(callExpectation.expectation.returnValue);
740
- }
741
- _this.recordUnexpected(property, args);
742
- return _this.getValueForUnexpectedCall(property, args);
743
- },
744
- };
745
- }
746
- switch (property) {
747
- case 'toString':
748
- return { value: function () { return 'mock'; } };
749
- case '@@toStringTag':
750
- case Symbol.toStringTag:
751
- case 'name':
752
- return { value: 'mock' };
753
- // pretty-format
754
- case '$$typeof':
755
- case 'constructor':
756
- case '@@__IMMUTABLE_ITERABLE__@@':
757
- case '@@__IMMUTABLE_RECORD__@@':
758
- return { value: null };
759
- case '__isMatcher':
760
- return { value: false };
761
- case ApplyProp:
762
- return {
763
- value: function () {
764
- var args = [];
765
- for (var _i = 0; _i < arguments.length; _i++) {
766
- args[_i] = arguments[_i];
767
- }
768
- _this.recordUnexpected(property, args);
769
- return _this.getValueForUnexpectedCall(property, args);
770
- },
771
- };
772
- default:
773
- this.recordUnexpected(property, undefined);
774
- return this.getValueForUnexpectedAccess(property);
775
- }
776
- };
777
- BaseRepository.prototype.getAllProperties = function () {
778
- return Array.from(this.expectations.keys());
779
- };
780
- BaseRepository.prototype.getCallStats = function () {
781
- return {
782
- expected: this.expectedCallStats,
783
- unexpected: this.unexpectedCallStats,
784
- };
785
- };
786
- BaseRepository.prototype.getUnmet = function () {
787
- var _a;
788
- return (_a = []).concat.apply(_a, __spreadArray([], __read(Array.from(this.expectations.values()).map(function (expectations) {
789
- return expectations
790
- .filter(function (e) { return e.expectation.min > e.matchCount; })
791
- .map(function (e) { return e.expectation; });
792
- }))));
793
- };
794
- /**
795
- * Record an expected property access/method call.
796
- */
797
- BaseRepository.prototype.recordExpected = function (property, args) {
798
- var calls = this.expectedCallStats.get(property) || [];
799
- this.expectedCallStats.set(property, __spreadArray(__spreadArray([], __read(calls), false), [{ arguments: args }]));
800
- };
801
- /**
802
- * Record an unexpected property access/method call.
803
- */
804
- BaseRepository.prototype.recordUnexpected = function (property, args) {
805
- var calls = this.unexpectedCallStats.get(property) || [];
806
- this.unexpectedCallStats.set(property, __spreadArray(__spreadArray([], __read(calls), false), [{ arguments: args }]));
807
- };
808
- BaseRepository.prototype.countAndConsume = function (expectation) {
809
- // eslint-disable-next-line no-param-reassign
810
- expectation.matchCount++;
811
- this.consumeExpectation(expectation);
812
- };
813
- return BaseRepository;
814
- }());
998
+ if (errorOrMessage instanceof Error) {
999
+ return errorOrMessage;
1000
+ }
815
1001
 
816
- /**
817
- * Throw if no expectation matches.
818
- */
819
- var StrongRepository = /** @class */ (function (_super) {
820
- __extends(StrongRepository, _super);
821
- function StrongRepository() {
822
- return _super !== null && _super.apply(this, arguments) || this;
823
- }
824
- StrongRepository.prototype.consumeExpectation = function (expectation) {
825
- var _a = expectation.expectation, property = _a.property, max = _a.max;
826
- var expectations = this.expectations.get(property);
827
- if (expectation.matchCount === max) {
828
- this.expectations.set(property, expectations.filter(function (e) { return e !== expectation; }));
829
- }
830
- };
831
- StrongRepository.prototype.getValueForUnexpectedCall = function (property, args) {
832
- throw new UnexpectedCall(property, args, this.getUnmet());
833
- };
834
- StrongRepository.prototype.getValueForUnexpectedAccess = function (property) {
835
- throw new UnexpectedAccess(property, this.getUnmet());
836
- };
837
- return StrongRepository;
838
- }(BaseRepository));
839
-
840
- var createStub = function (repo, pendingExpectation) {
841
- var stub = createProxy({
842
- property: function (property) {
843
- setActiveMock(stub);
844
- pendingExpectation.start(repo);
845
- // eslint-disable-next-line no-param-reassign
846
- pendingExpectation.property = property;
847
- return createProxy({
848
- property: function (childProp) {
849
- pendingExpectation.clear();
850
- throw new NestedWhen(property, childProp);
851
- },
852
- apply: function (args) {
853
- // eslint-disable-next-line no-param-reassign
854
- pendingExpectation.args = args;
855
- },
856
- ownKeys: function () {
857
- throw new Error('Spreading during an expectation is not supported.');
858
- },
859
- });
860
- },
861
- apply: function (args) {
862
- setActiveMock(stub);
863
- pendingExpectation.start(repo);
864
- // eslint-disable-next-line no-param-reassign
865
- pendingExpectation.property = ApplyProp;
866
- // eslint-disable-next-line no-param-reassign
867
- pendingExpectation.args = args;
868
- },
869
- ownKeys: function () {
870
- throw new Error('Spreading during an expectation is not supported.');
871
- },
872
- });
873
- return stub;
1002
+ return new Error();
1003
+ };
1004
+
1005
+ const createReturns = pendingExpectation => {
1006
+ const nonPromiseStub = {
1007
+ // TODO: merge this with the promise version
1008
+ thenReturn:
1009
+ /* istanbul ignore next: because this is overwritten by the promise version */
1010
+ returnValue => finishPendingExpectation({
1011
+ value: returnValue,
1012
+ isError: false,
1013
+ isPromise: false
1014
+ }, pendingExpectation),
1015
+ thenThrow: errorOrMessage => finishPendingExpectation({
1016
+ value: getError(errorOrMessage),
1017
+ isError: true,
1018
+ isPromise: false
1019
+ }, pendingExpectation)
1020
+ };
1021
+ const promiseStub = {
1022
+ thenReturn: promise => finishPendingExpectation({
1023
+ value: promise,
1024
+ isError: false,
1025
+ // We're setting this to false because we can't distinguish between a
1026
+ // promise thenReturn and a normal thenReturn.
1027
+ isPromise: false
1028
+ }, pendingExpectation),
1029
+ thenResolve: promiseValue => finishPendingExpectation({
1030
+ value: promiseValue,
1031
+ isError: false,
1032
+ isPromise: true
1033
+ }, pendingExpectation),
1034
+ thenReject: errorOrMessage => finishPendingExpectation({
1035
+ value: getError(errorOrMessage),
1036
+ isError: true,
1037
+ isPromise: true
1038
+ }, pendingExpectation)
1039
+ }; // @ts-expect-error because the return type is a conditional, and we're merging
1040
+ // both branches here
1041
+
1042
+ return _extends({}, nonPromiseStub, promiseStub);
874
1043
  };
875
1044
 
876
- var strongExpectationFactory = function (property, args, returnValue) {
877
- return new StrongExpectation(property,
878
- // Wrap every non-matcher in the default matcher.
879
- args === null || args === void 0 ? void 0 : args.map(function (arg) { return (isMatcher(arg) ? arg : deepEquals(arg)); }), returnValue);
880
- };
881
1045
  /**
882
- * Create a type safe mock.
1046
+ * Set an expectation on a mock.
1047
+ *
1048
+ * The expectation must be finished by setting a return value, even if the value
1049
+ * is `undefined`.
1050
+ *
1051
+ * If a call happens that was not expected then the mock will throw an error.
1052
+ * By default, the call is expected to only be made once. Use the invocation
1053
+ * count helpers to expect a call multiple times.
883
1054
  *
884
- * Set expectations on the mock using `when` and `thenReturn` and get an
885
- * instance from the mock using `instance`.
1055
+ * @param expectation A callback to set the expectation on your mock. The
1056
+ * callback must return the value from the mock to properly infer types.
886
1057
  *
887
1058
  * @example
888
- * const fn = mock<() => number>();
1059
+ * const fn = mock<() => void>();
1060
+ * when(() => fn()).thenReturn(undefined);
889
1061
  *
890
- * when(fn()).thenReturn(23);
1062
+ * @example
1063
+ * const fn = mock<() => number>();
1064
+ * when(() => fn()).thenReturn(42).atMost(3);
891
1065
  *
892
- * instance(fn) === 23;
893
- */
894
- var mock = function (_a) {
895
- var _b = _a === void 0 ? {} : _a, _c = _b.repository, repository = _c === void 0 ? new StrongRepository() : _c, _d = _b.expectationFactory, expectationFactory = _d === void 0 ? strongExpectationFactory : _d;
896
- var pendingExpectation = new RepoSideEffectPendingExpectation(expectationFactory);
897
- var stub = createStub(repository, pendingExpectation);
898
- setMockState(stub, { repository: repository, pendingExpectation: pendingExpectation });
899
- return stub;
1066
+ * @example
1067
+ * const fn = mock<(x: number) => Promise<number>();
1068
+ * when(() => fn(23)).thenResolve(42);
1069
+ */
1070
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars
1071
+
1072
+ const when = expectation => {
1073
+ setRecording(true);
1074
+ expectation();
1075
+ setRecording(false);
1076
+ return createReturns(getMockState(getActiveMock()).pendingExpectation);
900
1077
  };
901
1078
 
902
1079
  /**
@@ -905,37 +1082,41 @@ var mock = function (_a) {
905
1082
  * @example
906
1083
  * const fn = mock<() => number>();
907
1084
  *
908
- * when(fn()).thenReturn(23);
1085
+ * when(() => fn()).thenReturn(23);
909
1086
  *
910
1087
  * reset(fn);
911
1088
  *
912
- * instance(fn)(); // throws
913
- */
914
- var reset = function (mock) {
915
- getMockState(mock).repository.clear();
916
- };
1089
+ * fn(); // throws
1090
+ */
1091
+
1092
+ const reset = mock => {
1093
+ getMockState(mock).repository.clear();
1094
+ };
917
1095
  /**
918
1096
  * Reset all existing mocks.
919
1097
  *
920
1098
  * @see reset
921
- */
922
- var resetAll = function () {
923
- getAllMocks().forEach(function (_a) {
924
- var _b = __read(_a, 1), mock = _b[0];
925
- reset(mock);
926
- });
1099
+ */
1100
+
1101
+ const resetAll = () => {
1102
+ getAllMocks().forEach(([mock]) => {
1103
+ reset(mock);
1104
+ });
927
1105
  };
928
1106
 
929
- var verifyRepo = function (repository) {
930
- var unmetExpectations = repository.getUnmet();
931
- if (unmetExpectations.length) {
932
- throw new UnmetExpectations(unmetExpectations);
933
- }
934
- var callStats = repository.getCallStats();
935
- if (callStats.unexpected.size) {
936
- throw new UnexpectedCalls(callStats.unexpected, unmetExpectations);
937
- }
938
- };
1107
+ const verifyRepo = repository => {
1108
+ const unmetExpectations = repository.getUnmet();
1109
+
1110
+ if (unmetExpectations.length) {
1111
+ throw new UnmetExpectations(unmetExpectations);
1112
+ }
1113
+
1114
+ const callStats = repository.getCallStats();
1115
+
1116
+ if (callStats.unexpected.size) {
1117
+ throw new UnexpectedCalls(callStats.unexpected, unmetExpectations);
1118
+ }
1119
+ };
939
1120
  /**
940
1121
  * Verify that all expectations on the given mock have been met.
941
1122
  *
@@ -949,146 +1130,35 @@ var verifyRepo = function (repository) {
949
1130
  * @example
950
1131
  * const fn = mock<() => number>();
951
1132
  *
952
- * when(fn()).thenReturn(23);
1133
+ * when(() => fn()).thenReturn(23);
953
1134
  *
954
1135
  * verify(fn); // throws
955
- */
956
- var verify = function (mock) {
957
- var repository = getMockState(mock).repository;
958
- verifyRepo(repository);
959
- };
1136
+ */
1137
+
1138
+ const verify = mock => {
1139
+ const {
1140
+ repository
1141
+ } = getMockState(mock);
1142
+ verifyRepo(repository);
1143
+ };
960
1144
  /**
961
1145
  * Verify all existing mocks.
962
1146
  *
963
1147
  * @see verify
964
- */
965
- var verifyAll = function () {
966
- getAllMocks().forEach(function (_a) {
967
- var _b = __read(_a, 1), mock = _b[0];
968
- verify(mock);
969
- });
970
- };
971
-
972
- var createInvocationCount = function (expectation) { return ({
973
- between: function (min, max) {
974
- expectation.setInvocationCount(min, max);
975
- },
976
- /* istanbul ignore next */
977
- times: function (exact) {
978
- expectation.setInvocationCount(exact, exact);
979
- },
980
- /* istanbul ignore next */
981
- anyTimes: function () {
982
- expectation.setInvocationCount(0, 0);
983
- },
984
- /* istanbul ignore next */
985
- atLeast: function (min) {
986
- expectation.setInvocationCount(min, Infinity);
987
- },
988
- /* istanbul ignore next */
989
- atMost: function (max) {
990
- expectation.setInvocationCount(0, max);
991
- },
992
- /* istanbul ignore next */
993
- once: function () {
994
- expectation.setInvocationCount(1, 1);
995
- },
996
- /* istanbul ignore next */
997
- twice: function () {
998
- expectation.setInvocationCount(2, 2);
999
- },
1000
- /* eslint-enable no-param-reassign, no-multi-assign */
1001
- }); };
1002
-
1003
- /**
1004
- * Set a return value for the currently pending expectation.
1005
- */
1006
- var finishPendingExpectation = function (returnValue, pendingExpectation) {
1007
- var finishedExpectation = pendingExpectation.finish(returnValue);
1008
- pendingExpectation.clear();
1009
- return createInvocationCount(finishedExpectation);
1010
- };
1011
- var getError = function (errorOrMessage) {
1012
- if (typeof errorOrMessage === 'string') {
1013
- return new Error(errorOrMessage);
1014
- }
1015
- if (errorOrMessage instanceof Error) {
1016
- return errorOrMessage;
1017
- }
1018
- return new Error();
1019
- };
1020
- var createReturns = function (pendingExpectation) {
1021
- var nonPromiseStub = {
1022
- // TODO: merge this with the promise version
1023
- thenReturn: /* istanbul ignore next: because this is overwritten by the promise version */ function (returnValue) {
1024
- return finishPendingExpectation({ value: returnValue, isError: false, isPromise: false }, pendingExpectation);
1025
- },
1026
- thenThrow: function (errorOrMessage) {
1027
- return finishPendingExpectation({ value: getError(errorOrMessage), isError: true, isPromise: false }, pendingExpectation);
1028
- },
1029
- };
1030
- var promiseStub = {
1031
- thenReturn: function (promise) {
1032
- return finishPendingExpectation({
1033
- value: promise,
1034
- isError: false,
1035
- // We're setting this to false because we can't distinguish between a
1036
- // promise thenReturn and a normal thenReturn.
1037
- isPromise: false,
1038
- }, pendingExpectation);
1039
- },
1040
- thenResolve: function (promiseValue) {
1041
- return finishPendingExpectation({
1042
- value: promiseValue,
1043
- isError: false,
1044
- isPromise: true,
1045
- }, pendingExpectation);
1046
- },
1047
- thenReject: function (errorOrMessage) {
1048
- return finishPendingExpectation({
1049
- value: getError(errorOrMessage),
1050
- isError: true,
1051
- isPromise: true,
1052
- }, pendingExpectation);
1053
- },
1054
- };
1055
- return __assign(__assign({}, nonPromiseStub), promiseStub);
1056
- };
1148
+ */
1057
1149
 
1058
- /**
1059
- * Set an expectation on a mock.
1060
- *
1061
- * The expectation must be finished by setting a return value, even if the value
1062
- * is `undefined`.
1063
- *
1064
- * If a call happens that was not expected then the mock will throw an error.
1065
- * By default, the call is expected to only be made once. Use the invocation
1066
- * count helpers to expect a call multiple times.
1067
- *
1068
- * @param expectedCall Make a "real" call using the value returned by `mock()`.
1069
- *
1070
- * @example
1071
- * const fn = mock<() => void>();
1072
- * when(fn()).thenReturn(undefined);
1073
- *
1074
- * @example
1075
- * const fn = mock<() => number>();
1076
- * when(fn()).thenReturn(42).atMost(3);
1077
- *
1078
- * @example
1079
- * const fn = mock<(x: number) => Promise<number>();
1080
- * when(fn(23)).thenResolve(42);
1081
- */
1082
- // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars
1083
- var when = function (expectedCall) {
1084
- return createReturns(getMockState(getActiveMock()).pendingExpectation);
1150
+ const verifyAll = () => {
1151
+ getAllMocks().forEach(([mock]) => {
1152
+ verify(mock);
1153
+ });
1085
1154
  };
1086
1155
 
1087
1156
  exports.It = It;
1088
- exports.instance = instance;
1089
1157
  exports.mock = mock;
1090
1158
  exports.reset = reset;
1091
1159
  exports.resetAll = resetAll;
1160
+ exports.setDefaults = setDefaults;
1092
1161
  exports.verify = verify;
1093
1162
  exports.verifyAll = verifyAll;
1094
1163
  exports.when = when;
1164
+ //# sourceMappingURL=index.js.map