strong-mock 8.0.1 → 9.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.
Files changed (40) hide show
  1. package/README.md +52 -30
  2. package/dist/errors/api.d.ts +13 -0
  3. package/dist/errors/unexpected-access.d.ts +5 -0
  4. package/dist/errors/unexpected-call.d.ts +17 -0
  5. package/dist/errors/verify.d.ts +8 -0
  6. package/dist/expectation/expectation.d.ts +27 -30
  7. package/dist/expectation/repository/expectation-repository.d.ts +90 -90
  8. package/dist/expectation/repository/flexible-repository.d.ts +38 -38
  9. package/dist/expectation/repository/return-value.d.ts +13 -13
  10. package/dist/expectation/strong-expectation.d.ts +30 -30
  11. package/dist/index.d.ts +14 -9
  12. package/dist/index.js +810 -512
  13. package/dist/index.js.map +1 -1
  14. package/dist/matchers/deep-equals.d.ts +16 -0
  15. package/dist/matchers/is-any.d.ts +11 -0
  16. package/dist/matchers/is-array.d.ts +22 -0
  17. package/dist/matchers/is-number.d.ts +12 -0
  18. package/dist/matchers/is-object.d.ts +27 -0
  19. package/dist/matchers/is-string.d.ts +15 -0
  20. package/dist/matchers/is.d.ts +9 -0
  21. package/dist/matchers/it.d.ts +9 -0
  22. package/dist/matchers/matcher.d.ts +92 -0
  23. package/dist/matchers/will-capture.d.ts +21 -0
  24. package/dist/mock/defaults.d.ts +11 -11
  25. package/dist/mock/map.d.ts +16 -16
  26. package/dist/mock/mock.d.ts +29 -29
  27. package/dist/mock/options.d.ts +99 -99
  28. package/dist/mock/stub.d.ts +5 -5
  29. package/dist/print.d.ts +10 -10
  30. package/dist/proxy.d.ts +48 -48
  31. package/dist/return/invocation-count.d.ts +44 -44
  32. package/dist/return/returns.d.ts +61 -87
  33. package/dist/verify/reset.d.ts +20 -20
  34. package/dist/verify/verify.d.ts +27 -27
  35. package/dist/when/{pending-expectation.d.ts → expectation-builder.d.ts} +26 -31
  36. package/dist/when/when.d.ts +32 -32
  37. package/package.json +20 -16
  38. package/dist/errors.d.ts +0 -28
  39. package/dist/expectation/it.d.ts +0 -29
  40. package/dist/expectation/matcher.d.ts +0 -21
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  <div align="center">
3
3
  <h1>💪 strong-mock</h1>
4
4
 
5
- <p>Simple type safe mocking library</p>
5
+ <p>Type safe mocking library for TypeScript</p>
6
6
  </div>
7
7
 
8
8
  ```typescript
@@ -29,8 +29,8 @@ console.log(foo.bar(23)); // 'I am strong!'
29
29
 
30
30
  - [Features](#features)
31
31
  - [Type safety](#type-safety)
32
- - [Useful error messages](#useful-error-messages)
33
- - [Type safe argument matchers](#type-safe-argument-matchers)
32
+ - [Matchers](#matchers)
33
+ - [Awesome error messages](#awesome-error-messages)
34
34
  - [Installation](#installation)
35
35
  - [Requirements](#requirements)
36
36
  - [API](#api)
@@ -43,18 +43,19 @@ console.log(foo.bar(23)); // 'I am strong!'
43
43
  - [Throwing errors](#throwing-errors)
44
44
  - [Verifying expectations](#verifying-expectations)
45
45
  - [Resetting expectations](#resetting-expectations)
46
- - [Argument matchers](#argument-matchers)
46
+ - [Matchers](#matchers-1)
47
47
  - [Mock options](#mock-options)
48
48
  - [Unexpected property return value](#unexpected-property-return-value)
49
49
  - [Exact params](#exact-params)
50
50
  - [Concrete matcher](#concrete-matcher)
51
51
  - [FAQ](#faq)
52
52
  - [Why do I have to set all expectations first?](#why-do-i-have-to-set-all-expectations-first)
53
- - [Can I partially mock an existing object/function?](#can-i-partially-mock-an-existing-objectfunction)
54
- - [How do I set expectations on setters?](#how-do-i-set-expectations-on-setters)
53
+ - [Why do I get a `Didn't expect mock to be called` error?](#why-do-i-get-a-didnt-expect-mock-to-be-called-error)
55
54
  - [Why do I have to set a return value even if it's `undefined`?](#why-do-i-have-to-set-a-return-value-even-if-its-undefined)
55
+ - [Can I partially mock a concrete implementation?](#can-i-partially-mock-a-concrete-implementation)
56
+ - [How do I set expectations on setters?](#how-do-i-set-expectations-on-setters)
56
57
  - [How do I provide a function for the mock to call?](#how-do-i-provide-a-function-for-the-mock-to-call)
57
- - [Can I spread/enumerate a mock?](#can-i-spreadenumerate-a-mock)
58
+ - [Can I spread or enumerate a mock?](#can-i-spread-or-enumerate-a-mock)
58
59
  - [How can I ignore `undefined` keys when setting expectations on objects?](#how-can-i-ignore-undefined-keys-when-setting-expectations-on-objects)
59
60
 
60
61
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -67,27 +68,34 @@ The mock expectations will share the same type guarantees as your production cod
67
68
 
68
69
  ![Renaming production code and test code](media/rename-refactor.gif)
69
70
 
70
- ### Useful error messages
71
+ ### Matchers
71
72
 
72
- Error messages include the property that has been accessed, any arguments passed to it and any remaining unmet expectations.
73
+ You can use matchers to partially match values, or create complex expectations, while still maintaining type safety.
73
74
 
74
- ```typescript
75
- import { mock, when } from 'strong-mock';
75
+ ![Type safe matcher showing a type error](media/type-safe-matchers.png)
76
76
 
77
- const fn = mock<(a: number, b: number, c: number) => number>();
77
+ ### Awesome error messages
78
78
 
79
- when(() => fn(1, 2, 3)).thenReturn(42);
79
+ Failed expectations will print a visual diff, and even integrate with the IDE.
80
80
 
81
- fn(4, 5, 6);
82
- ```
81
+ ```typescript
82
+ import { mock, when } from 'strong-mock';
83
83
 
84
- ![Test output showing details about mock expectations](media/error-messages.png)
84
+ const fn = mock<(pos: { x: number; y: number }) => boolean>();
85
85
 
86
- ### Type safe argument matchers
86
+ when(() =>
87
+ fn(
88
+ It.isObject({
89
+ x: It.isNumber(),
90
+ y: It.matches<number>((y) => y > 0)
91
+ })
92
+ )
93
+ ).thenReturn(true);
87
94
 
88
- You can use argument matchers to partially match values, or create complex expectations, while still maintaining type safety.
95
+ fn({ x: 1, y: -1 });
96
+ ```
89
97
 
90
- ![Type safe matcher showing a type error](media/type-safe-matchers.png)
98
+ ![Test output from the IDE showing details about a failed mock expectation](media/error-messages.png)
91
99
 
92
100
  ## Installation
93
101
 
@@ -99,6 +107,10 @@ npm i -D strong-mock
99
107
  yarn add -D strong-mock
100
108
  ```
101
109
 
110
+ ```shell
111
+ pnpm add -D strong-mock
112
+ ```
113
+
102
114
  ## Requirements
103
115
 
104
116
  strong-mock requires an environment that supports the [ES6 Proxy object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). This is necessary to create dynamic mocks from types because TypeScript does not support reflection i.e. exposing the type info at runtime.
@@ -107,7 +119,7 @@ strong-mock requires an environment that supports the [ES6 Proxy object](https:/
107
119
 
108
120
  ### Setting expectations
109
121
 
110
- Expectations are set by calling the mock inside a `when` callback and finishing it by setting a return value.
122
+ Expectations are set by calling the mock inside a `when` callback and setting a return value.
111
123
 
112
124
  ```typescript
113
125
  when(() => foo.bar(23)).thenReturn('awesome');
@@ -186,7 +198,7 @@ const fn = mock<Fn>();
186
198
 
187
199
  when(() => fn(1)).thenResolve(2);
188
200
 
189
- console.log(await fn()); // 2
201
+ console.log(await fn(1)); // 2
190
202
  ```
191
203
 
192
204
  ### Throwing errors
@@ -266,7 +278,7 @@ beforeEach(() => {
266
278
  })
267
279
  ```
268
280
 
269
- ### Argument matchers
281
+ ### Matchers
270
282
 
271
283
  Sometimes you're not interested in specifying all the arguments in an expectation. Maybe they've been covered in another test, maybe they're hard to specify e.g. callbacks, or maybe you want to match just a property from an argument.
272
284
 
@@ -286,7 +298,7 @@ console.log(fn(
286
298
  ); // 'matched!'
287
299
  ```
288
300
 
289
- You can mix argument matchers with concrete arguments:
301
+ You can mix matchers with concrete arguments:
290
302
 
291
303
  ```typescript
292
304
  when(() => fn(42, It.isObject())).thenReturn('matched');
@@ -397,7 +409,7 @@ propertiesThrow.bar(42);
397
409
 
398
410
  ### Exact params
399
411
 
400
- By default, function/method expectations will allow more arguments to be received than expected. Since the expectations are type safe, the TypeScript compiler will never allow expecting less arguments than required. Unspecified optional arguments will be considered ignored, as if they've been replaced with [argument matchers](#argument-matchers).
412
+ By default, function/method expectations will allow more arguments to be received than expected. Since the expectations are type safe, the TypeScript compiler will never allow expecting less arguments than required. Unspecified optional arguments will be considered ignored, as if they've been replaced with [matchers](#matchers-1).
401
413
 
402
414
  ```typescript
403
415
  import { mock } from 'strong-mock';
@@ -429,7 +441,7 @@ console.log(fn(1)); // throws
429
441
 
430
442
  ### Concrete matcher
431
443
 
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.
444
+ You can configure the [matcher](#matchers-1) 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.
433
445
 
434
446
  ```typescript
435
447
  import { mock, when, It } from 'strong-mock';
@@ -458,18 +470,28 @@ This design decision has a few reasons behind it. First, it forces you to be awa
458
470
 
459
471
  Secondly, it will highlight potential design problems such as violations of the SOLID principles. If you find yourself duplicating expectations between tests and passing dummy values to them because your test is not concerned with them, then you might want to look into splitting the code to only depend on things it really needs.
460
472
 
461
- ### Can I partially mock an existing object/function?
473
+ ### Why do I get a `Didn't expect mock to be called` error?
462
474
 
463
- No, passing a concrete implementation to `mock()` will be the same as passing a type: all properties will be mocked, and you have to set expectations on the ones that will be accessed.
475
+ This error happens when your code under test calls a method from the mock, or the mock itself if it's a function, that didn't have a matching expectation. It could be that the arguments received didn't match the ones set in the expectation (see [matchers](#matchers-1)), or the call was made more than the allowed number of times (see [invocation count expectations](#setting-invocation-count-expectations)).
464
476
 
465
- ### How do I set expectations on setters?
477
+ In rare cases, the code under test may try to inspect the mock by accessing special properties on it. For instance, React's `setState(state)` accepts 2 types of values: functions and everything else. To differentiate between the 2 types, React will internally do a `typeof` check. All mocks created by strong-mock return `'function'` for this check, so React will try to call them in case you pass them directly to `setState`. This might lead to the `Didn't expect mock(...) to be called` error, as the mock receives the previous state and doesn't find an expectation for it.
466
478
 
467
- You currently can't do that. Please use a normal method instead e.g. `setFoo()` vs `set foo()`.
479
+ If you run into any of these cases, feel free to [open an issue](https://github.com/NiGhTTraX/strong-mock/issues) with a minimal reproduction. Most of the time the issue can be fixed by returning stubbed values for these special properties.
480
+
481
+ Unfortunately, this is not always possible, such as with the React example above. You might have to adjust your code slightly to work around the checks your code, or some library, is doing. With React, simply putting the mock inside an object e.g. `setState({ foo: theMock })` will avoid the `typeof` check and work as expected.
468
482
 
469
483
  ### Why do I have to set a return value even if it's `undefined`?
470
484
 
471
485
  To make side effects explicit and to prevent future refactoring headaches. If you had just `when(() => fn())`, and you later changed `fn()` to return a `number`, then your expectation would become incorrect and the compiler couldn't check that for you.
472
486
 
487
+ ### Can I partially mock a concrete implementation?
488
+
489
+ No, passing a concrete implementation to `mock()` will be the same as passing a type: all properties will be mocked, and you have to set expectations on the ones that will be accessed.
490
+
491
+ ### How do I set expectations on setters?
492
+
493
+ You currently can't do that. Please use a normal method instead e.g. `setFoo()` vs `set foo()`.
494
+
473
495
  ### How do I provide a function for the mock to call?
474
496
 
475
497
  There is no `thenCall()` method because it can't be safely typed - the type for `thenReturn()` is inferred from the return type in `when`, meaning that the required type would be the return value for the function, not the function itself. However, we can leverage this by setting an expectation on the function property instead:
@@ -488,7 +510,7 @@ console.log(foo.bar(23)); // 'called 23'
488
510
 
489
511
  The function in `thenReturn()` will be type checked against the actual interface, so you can make sure you're passing in an implementation that makes sense. Moreover, refactoring the interface will also refactor the expectation (in a capable IDE).
490
512
 
491
- ### Can I spread/enumerate a mock?
513
+ ### Can I spread or enumerate a mock?
492
514
 
493
515
  Yes, and you will only get the properties that have expectations on them.
494
516
 
@@ -0,0 +1,13 @@
1
+ import type { Property } from '../proxy';
2
+ export declare class UnfinishedExpectation extends Error {
3
+ constructor(property: Property, args: any[] | undefined);
4
+ }
5
+ export declare class MissingWhen extends Error {
6
+ constructor();
7
+ }
8
+ export declare class NotAMock extends Error {
9
+ constructor();
10
+ }
11
+ export declare class NestedWhen extends Error {
12
+ constructor(parentProp: Property, childProp: Property);
13
+ }
@@ -0,0 +1,5 @@
1
+ import type { Expectation } from '../expectation/expectation';
2
+ import type { Property } from '../proxy';
3
+ export declare class UnexpectedAccess extends Error {
4
+ constructor(property: Property, expectations: Expectation[]);
5
+ }
@@ -0,0 +1,17 @@
1
+ import type { Expectation } from '../expectation/expectation';
2
+ import type { Property } from '../proxy';
3
+ type MatcherResult = {
4
+ expected: unknown;
5
+ actual: unknown;
6
+ };
7
+ interface MatcherError {
8
+ matcherResult?: MatcherResult;
9
+ }
10
+ export declare const printArgsDiff: (expected: unknown[], actual: unknown[]) => string;
11
+ export declare const printExpectationDiff: (e: Expectation, args: unknown[]) => string;
12
+ export declare const printDiffForAllExpectations: (expectations: Expectation[], actual: unknown[]) => string;
13
+ export declare class UnexpectedCall extends Error implements MatcherError {
14
+ matcherResult?: MatcherResult;
15
+ constructor(property: Property, args: unknown[], expectations: Expectation[]);
16
+ }
17
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { Expectation } from '../expectation/expectation';
2
+ import type { CallMap } from '../expectation/repository/expectation-repository';
3
+ export declare class UnmetExpectations extends Error {
4
+ constructor(expectations: Expectation[]);
5
+ }
6
+ export declare class UnexpectedCalls extends Error {
7
+ constructor(unexpectedCalls: CallMap, expectations: Expectation[]);
8
+ }
@@ -1,30 +1,27 @@
1
- import type { Property } from '../proxy';
2
- import type { Matcher } from './matcher';
3
- import type { ReturnValue } from './repository/return-value';
4
- /**
5
- * Compare received arguments against matchers.
6
- */
7
- export interface Expectation {
8
- property: Property;
9
- /**
10
- * `undefined` means this is a property expectation.
11
- * `[]` means this is a function call with no arguments.
12
- */
13
- args: Matcher[] | undefined;
14
- returnValue: ReturnValue;
15
- min: number;
16
- max: number;
17
- /**
18
- * How many times should this expectation match?
19
- */
20
- setInvocationCount(min: number, max: number): void;
21
- matches(args: any[] | undefined): boolean;
22
- /**
23
- * Used by `pretty-format`.
24
- */
25
- toJSON(): string;
26
- }
27
- /**
28
- * Special symbol denoting the call of a function.
29
- */
30
- export declare const ApplyProp: unique symbol;
1
+ import type { Matcher } from '../matchers/matcher';
2
+ import type { Property } from '../proxy';
3
+ import type { ReturnValue } from './repository/return-value';
4
+ /**
5
+ * Compare received arguments against matchers.
6
+ */
7
+ export interface Expectation {
8
+ property: Property;
9
+ /**
10
+ * `undefined` means this is a property expectation.
11
+ * `[]` means this is a function call with no arguments.
12
+ */
13
+ args: Matcher[] | undefined;
14
+ returnValue: ReturnValue;
15
+ min: number;
16
+ max: number;
17
+ /**
18
+ * How many times should this expectation match?
19
+ */
20
+ setInvocationCount: (min: number, max: number) => void;
21
+ matches: (args: unknown[] | undefined) => boolean;
22
+ toString: () => string;
23
+ }
24
+ /**
25
+ * Special symbol denoting the call of a function.
26
+ */
27
+ export declare const ApplyProp: unique symbol;
@@ -1,90 +1,90 @@
1
- import type { Property } from '../../proxy';
2
- import type { Expectation } from '../expectation';
3
- export type Call = {
4
- arguments: any[] | undefined;
5
- };
6
- /**
7
- * Method calls should be recorded both as a property access and a method call.
8
- *
9
- * @example
10
- * // foo.bar(1, 2, 3) should generate
11
- * {
12
- * foo: [
13
- * { arguments: undefined },
14
- * { arguments: [1, 2, 3] }
15
- * ]
16
- * }
17
- */
18
- export type CallMap = Map<Property, Call[]>;
19
- export type CallStats = {
20
- /**
21
- * Calls that matched existing expectations.
22
- */
23
- expected: CallMap;
24
- /**
25
- * Calls that didn't match any existing expectation.
26
- */
27
- unexpected: CallMap;
28
- };
29
- export interface ExpectationRepository {
30
- add(expectation: Expectation): void;
31
- /**
32
- * Get a return value for the given property.
33
- *
34
- * The value might be a non-callable e.g. a number or a string, or it might
35
- * be a function that, upon receiving arguments, will start a new search and
36
- * return a value again.
37
- *
38
- * The list of expectations should be consulted from first to last when
39
- * getting a return value. If none of them match it is up to the
40
- * implementation to decide what to do.
41
- *
42
- * @example
43
- * add(new Expectation('getData', [1, 2], 23);
44
- * get('getData')(1, 2) === 23
45
- *
46
- * @example
47
- * add(new Expectation('hasData', undefined, true);
48
- * get('hasData') === true
49
- *
50
- * @example
51
- * add(new Expectation('getData', undefined, () => 42);
52
- * get('getData')(1, 2, '3', false, NaN) === 42
53
- */
54
- get(property: Property): unknown;
55
- /**
56
- * Get a return value for a function call.
57
- *
58
- * Note: this will only be invoked if the mocked type is a function. For
59
- * method property calls {@link get} will be called instead.
60
- *
61
- * The list of expectations should be consulted from first to last when
62
- * getting a return value. If none of them match it is up to the
63
- * implementation to decide what to do.
64
- *
65
- * @example
66
- * add(new Expectation(ApplyProp, [1, 2], 23);
67
- * apply(1, 2) === 23
68
- */
69
- apply(args: unknown[]): unknown;
70
- /**
71
- * Get all the properties that have expectations.
72
- *
73
- * @example
74
- * add(new Expectation('foo', undefined, 23));
75
- * getAllProperties() === ['foo']
76
- */
77
- getAllProperties(): Property[];
78
- /**
79
- * Remove any expectations and clear the call stats.
80
- */
81
- clear(): void;
82
- /**
83
- * Return all unmet expectations.
84
- */
85
- getUnmet(): Expectation[];
86
- /**
87
- * Return all the calls that have been made so far.
88
- */
89
- getCallStats(): CallStats;
90
- }
1
+ import type { Property } from '../../proxy';
2
+ import type { Expectation } from '../expectation';
3
+ export type Call = {
4
+ arguments: any[] | undefined;
5
+ };
6
+ /**
7
+ * Method calls should be recorded both as a property access and a method call.
8
+ *
9
+ * @example
10
+ * // foo.bar(1, 2, 3) should generate
11
+ * {
12
+ * foo: [
13
+ * { arguments: undefined },
14
+ * { arguments: [1, 2, 3] }
15
+ * ]
16
+ * }
17
+ */
18
+ export type CallMap = Map<Property, Call[]>;
19
+ export type CallStats = {
20
+ /**
21
+ * Calls that matched existing expectations.
22
+ */
23
+ expected: CallMap;
24
+ /**
25
+ * Calls that didn't match any existing expectation.
26
+ */
27
+ unexpected: CallMap;
28
+ };
29
+ export interface ExpectationRepository {
30
+ add: (expectation: Expectation) => void;
31
+ /**
32
+ * Get a return value for the given property.
33
+ *
34
+ * The value might be a non-callable e.g. a number or a string, or it might
35
+ * be a function that, upon receiving arguments, will start a new search and
36
+ * return a value again.
37
+ *
38
+ * The list of expectations should be consulted from first to last when
39
+ * getting a return value. If none of them match it is up to the
40
+ * implementation to decide what to do.
41
+ *
42
+ * @example
43
+ * add(new Expectation('getData', [1, 2], 23);
44
+ * get('getData')(1, 2) === 23
45
+ *
46
+ * @example
47
+ * add(new Expectation('hasData', undefined, true);
48
+ * get('hasData') === true
49
+ *
50
+ * @example
51
+ * add(new Expectation('getData', undefined, () => 42);
52
+ * get('getData')(1, 2, '3', false, NaN) === 42
53
+ */
54
+ get: (property: Property) => unknown;
55
+ /**
56
+ * Get a return value for a function call.
57
+ *
58
+ * Note: this will only be invoked if the mocked type is a function. For
59
+ * method property calls {@link get} will be called instead.
60
+ *
61
+ * The list of expectations should be consulted from first to last when
62
+ * getting a return value. If none of them match it is up to the
63
+ * implementation to decide what to do.
64
+ *
65
+ * @example
66
+ * add(new Expectation(ApplyProp, [1, 2], 23);
67
+ * apply(1, 2) === 23
68
+ */
69
+ apply: (args: unknown[]) => unknown;
70
+ /**
71
+ * Get all the properties that have expectations.
72
+ *
73
+ * @example
74
+ * add(new Expectation('foo', undefined, 23));
75
+ * getAllProperties() === ['foo']
76
+ */
77
+ getAllProperties: () => Property[];
78
+ /**
79
+ * Remove any expectations and clear the call stats.
80
+ */
81
+ clear: () => void;
82
+ /**
83
+ * Return all unmet expectations.
84
+ */
85
+ getUnmet: () => Expectation[];
86
+ /**
87
+ * Return all the calls that have been made so far.
88
+ */
89
+ getCallStats: () => CallStats;
90
+ }
@@ -1,38 +1,38 @@
1
- import { UnexpectedProperty } from '../../mock/options';
2
- import type { Property } from '../../proxy';
3
- import type { Expectation } from '../expectation';
4
- import type { CallMap, ExpectationRepository } from './expectation-repository';
5
- type CountableExpectation = {
6
- expectation: Expectation;
7
- matchCount: number;
8
- };
9
- /**
10
- * An expectation repository with a configurable behavior for
11
- * unexpected property access.
12
- */
13
- export declare class FlexibleRepository implements ExpectationRepository {
14
- private unexpectedProperty;
15
- constructor(unexpectedProperty?: UnexpectedProperty);
16
- protected readonly expectations: Map<Property, CountableExpectation[]>;
17
- private readonly expectedCallStats;
18
- private readonly unexpectedCallStats;
19
- add(expectation: Expectation): void;
20
- clear(): void;
21
- apply: (args: unknown[]) => unknown;
22
- get(property: Property): any;
23
- private handlePropertyWithMatchingExpectations;
24
- private handlePropertyWithNoExpectations;
25
- getAllProperties(): Property[];
26
- getCallStats(): {
27
- expected: CallMap;
28
- unexpected: CallMap;
29
- };
30
- getUnmet(): Expectation[];
31
- private recordExpected;
32
- private recordUnexpected;
33
- private countAndConsume;
34
- private consumeExpectation;
35
- private getValueForUnexpectedCall;
36
- private getValueForUnexpectedAccess;
37
- }
38
- export {};
1
+ import { UnexpectedProperty } from '../../mock/options';
2
+ import type { Property } from '../../proxy';
3
+ import type { Expectation } from '../expectation';
4
+ import type { CallMap, ExpectationRepository } from './expectation-repository';
5
+ type CountableExpectation = {
6
+ expectation: Expectation;
7
+ matchCount: number;
8
+ };
9
+ /**
10
+ * An expectation repository with a configurable behavior for
11
+ * unexpected property access.
12
+ */
13
+ export declare class FlexibleRepository implements ExpectationRepository {
14
+ private unexpectedProperty;
15
+ constructor(unexpectedProperty?: UnexpectedProperty);
16
+ protected readonly expectations: Map<Property, CountableExpectation[]>;
17
+ private readonly expectedCallStats;
18
+ private readonly unexpectedCallStats;
19
+ add(expectation: Expectation): void;
20
+ clear(): void;
21
+ apply: (args: unknown[]) => unknown;
22
+ get(property: Property): any;
23
+ private handlePropertyWithMatchingExpectations;
24
+ private handlePropertyWithNoExpectations;
25
+ getAllProperties(): Property[];
26
+ getCallStats(): {
27
+ expected: CallMap;
28
+ unexpected: CallMap;
29
+ };
30
+ getUnmet(): Expectation[];
31
+ private recordExpected;
32
+ private recordUnexpected;
33
+ private countAndConsume;
34
+ private consumeExpectation;
35
+ private getValueForUnexpectedCall;
36
+ private getValueForUnexpectedAccess;
37
+ }
38
+ export {};
@@ -1,13 +1,13 @@
1
- export type ReturnValue = {
2
- value: any;
3
- isPromise?: boolean;
4
- isError?: boolean;
5
- };
6
- /**
7
- * Unbox the expectation's return value.
8
- *
9
- * If the value is an error then throw it.
10
- *
11
- * If the value is a promise then resolve/reject it.
12
- */
13
- export declare const unboxReturnValue: ({ isError, isPromise, value, }: ReturnValue) => any;
1
+ export type ReturnValue = {
2
+ value: any;
3
+ isPromise?: boolean;
4
+ isError?: boolean;
5
+ };
6
+ /**
7
+ * Unbox the expectation's return value.
8
+ *
9
+ * If the value is an error then throw it.
10
+ *
11
+ * If the value is a promise then resolve/reject it.
12
+ */
13
+ export declare const unboxReturnValue: ({ isError, isPromise, value, }: ReturnValue) => any;
@@ -1,30 +1,30 @@
1
- import type { Property } from '../proxy';
2
- import type { Expectation } from './expectation';
3
- import type { Matcher } from './matcher';
4
- import type { ReturnValue } from './repository/return-value';
5
- /**
6
- * Matches a call with more parameters than expected because it is assumed the
7
- * compiler will check that those parameters are optional.
8
- *
9
- * @example
10
- * new StrongExpectation(
11
- * 'bar',
12
- * deepEquals([1, 2, 3]),
13
- * 23
14
- * ).matches('bar', [1, 2, 3]) === true;
15
- */
16
- export declare class StrongExpectation implements Expectation {
17
- property: Property;
18
- args: Matcher[] | undefined;
19
- returnValue: ReturnValue;
20
- private exactParams;
21
- private matched;
22
- min: number;
23
- max: number;
24
- constructor(property: Property, args: Matcher[] | undefined, returnValue: ReturnValue, exactParams?: boolean);
25
- setInvocationCount(min: number, max?: number): void;
26
- matches(args: any[] | undefined): boolean;
27
- isUnmet(): boolean;
28
- private matchesArgs;
29
- toJSON(): string;
30
- }
1
+ import type { Matcher } from '../matchers/matcher';
2
+ import type { Property } from '../proxy';
3
+ import type { Expectation } from './expectation';
4
+ import type { ReturnValue } from './repository/return-value';
5
+ /**
6
+ * Matches a call with more parameters than expected because it is assumed the
7
+ * compiler will check that those parameters are optional.
8
+ *
9
+ * @example
10
+ * new StrongExpectation(
11
+ * 'bar',
12
+ * deepEquals([1, 2, 3]),
13
+ * 23
14
+ * ).matches('bar', [1, 2, 3]) === true;
15
+ */
16
+ export declare class StrongExpectation implements Expectation {
17
+ property: Property;
18
+ args: Matcher[] | undefined;
19
+ returnValue: ReturnValue;
20
+ private exactParams;
21
+ private matched;
22
+ min: number;
23
+ max: number;
24
+ constructor(property: Property, args: Matcher[] | undefined, returnValue: ReturnValue, exactParams?: boolean);
25
+ setInvocationCount(min: number, max?: number): void;
26
+ matches(args: any[] | undefined): boolean;
27
+ isUnmet(): boolean;
28
+ private matchesArgs;
29
+ toString(): string;
30
+ }