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/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  </div>
7
7
 
8
8
  ```typescript
9
- import { mock, when, instance } from 'strong-mock';
9
+ import { mock, when } from 'strong-mock';
10
10
 
11
11
  interface Foo {
12
12
  bar: (x: number) => string;
@@ -14,9 +14,9 @@ interface Foo {
14
14
 
15
15
  const foo = mock<Foo>();
16
16
 
17
- when(foo.bar(23)).thenReturn('I am strong!');
17
+ when(() => foo.bar(23)).thenReturn('I am strong!');
18
18
 
19
- console.log(instance(foo).bar(23)); // 'I am strong!'
19
+ console.log(foo.bar(23)); // 'I am strong!'
20
20
  ```
21
21
 
22
22
  ----
@@ -27,12 +27,12 @@ console.log(instance(foo).bar(23)); // 'I am strong!'
27
27
  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
28
28
  **Table of Contents**
29
29
 
30
- - [Installation](#installation)
31
- - [Requirements](#requirements)
32
30
  - [Features](#features)
33
31
  - [Type safety](#type-safety)
34
32
  - [Useful error messages](#useful-error-messages)
35
33
  - [Type safe argument matchers](#type-safe-argument-matchers)
34
+ - [Installation](#installation)
35
+ - [Requirements](#requirements)
36
36
  - [API](#api)
37
37
  - [Setting expectations](#setting-expectations)
38
38
  - [Setting multiple expectations](#setting-multiple-expectations)
@@ -44,6 +44,7 @@ console.log(instance(foo).bar(23)); // 'I am strong!'
44
44
  - [Verifying expectations](#verifying-expectations)
45
45
  - [Resetting expectations](#resetting-expectations)
46
46
  - [Argument matchers](#argument-matchers)
47
+ - [Overriding default matcher](#overriding-default-matcher)
47
48
  - [FAQ](#faq)
48
49
  - [Why do I have to set all expectations first?](#why-do-i-have-to-set-all-expectations-first)
49
50
  - [Can I mock an existing object/function?](#can-i-mock-an-existing-objectfunction)
@@ -51,24 +52,11 @@ console.log(instance(foo).bar(23)); // 'I am strong!'
51
52
  - [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)
52
53
  - [How do I provide a function for the mock to call?](#how-do-i-provide-a-function-for-the-mock-to-call)
53
54
  - [Why does accessing an unused method throw?](#why-does-accessing-an-unused-method-throw)
54
- - [Can I spread/enumerate a mock instance?](#can-i-spreadenumerate-a-mock-instance)
55
+ - [Can I spread/enumerate a mock?](#can-i-spreadenumerate-a-mock)
56
+ - [How can I ignore `undefined` keys when setting expectations on objects?](#how-can-i-ignore-undefined-keys-when-setting-expectations-on-objects)
55
57
 
56
58
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
57
59
 
58
- ## Installation
59
-
60
- ```
61
- npm i -D strong-mock
62
- ```
63
-
64
- ```
65
- yarn add -D strong-mock
66
- ```
67
-
68
- ## Requirements
69
-
70
- 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.
71
-
72
60
  ## Features
73
61
 
74
62
  ### Type safety
@@ -85,34 +73,44 @@ Error messages include the property that has been accessed, any arguments passed
85
73
 
86
74
  ### Type safe argument matchers
87
75
 
88
- ![type safe matchers](./media/type-safe-matchers.png)
76
+ Optional argument matchers allow you to create complex expectations, while still maintaining type safety.
89
77
 
90
- ## API
78
+ ![type safe matchers](./media/type-safe-matchers.png)
91
79
 
92
- ### Setting expectations
80
+ ## Installation
93
81
 
94
- Expectations are set by calling the mock inside a `when()` call and finishing it by setting a return value.
82
+ ```
83
+ npm i -D strong-mock
84
+ ```
95
85
 
96
- ```typescript
97
- when(foo.bar(23)).thenReturn('awesome');
86
+ ```
87
+ yarn add -D strong-mock
98
88
  ```
99
89
 
100
- After expectations have been set you need to get an instance of the mock by calling `instance()`.
90
+ ## Requirements
91
+
92
+ 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.
93
+
94
+ ## API
95
+
96
+ ### Setting expectations
97
+
98
+ Expectations are set by calling the mock inside a `when` callback and finishing it by setting a return value.
101
99
 
102
100
  ```typescript
103
- instance(foo)
101
+ when(() => foo.bar(23)).thenReturn('awesome');
104
102
  ```
105
103
 
106
104
  ### Setting multiple expectations
107
105
 
108
- You can set as many expectations as you want by calling `when()` multiple times. If you have multiple expectations with the same arguments they will be consumed in the order they were created.
106
+ You can set as many expectations as you want by calling `when` multiple times. If you have multiple expectations with the same arguments they will be consumed in the order they were created.
109
107
 
110
108
  ```typescript
111
- when(foo.bar(23)).thenReturn('awesome');
112
- when(foo.bar(23)).thenReturn('even more awesome');
109
+ when(() => foo.bar(23)).thenReturn('awesome');
110
+ when(() => foo.bar(23)).thenReturn('even more awesome');
113
111
 
114
- console.log(instance(foo).bar(23)); // awesome
115
- console.log(instance(foo).bar(23)); // even more awesome
112
+ console.log(foo.bar(23)); // awesome
113
+ console.log(foo.bar(23)); // even more awesome
116
114
  ```
117
115
 
118
116
  By default, each call is expected to be called only once. You can expect a call to be made multiple times using the [invocation count](#setting-invocation-count-expectations) helpers.
@@ -124,12 +122,12 @@ You can expect a call to be made multiple times by using the invocation count he
124
122
  ```typescript
125
123
  const fn = mock<(x: number) => number>();
126
124
 
127
- when(fn(1)).thenReturn(1).between(2, 3);
125
+ when(() => fn(1)).thenReturn(1).between(2, 3);
128
126
 
129
- console.log(instance(fn)(1)); // 1
130
- console.log(instance(fn)(1)); // 1
131
- console.log(instance(fn)(1)); // 1
132
- console.log(instance(fn)(1)); // throws because the expectation is finished
127
+ console.log(fn(1)); // 1
128
+ console.log(fn(1)); // 1
129
+ console.log(fn(1)); // 1
130
+ console.log(fn(1)); // throws because the expectation is finished
133
131
  ```
134
132
 
135
133
  ### Mocking interfaces
@@ -144,11 +142,11 @@ interface Foo {
144
142
 
145
143
  const foo = mock<Foo>();
146
144
 
147
- when(foo.bar(23)).thenReturn('awesome');
148
- when(foo.baz).thenReturn(100);
145
+ when(() => foo.bar(23)).thenReturn('awesome');
146
+ when(() => foo.baz).thenReturn(100);
149
147
 
150
- console.log(instance(foo).bar(23)); // 'awesome'
151
- console.log(instance(foo).baz); // 100
148
+ console.log(foo.bar(23)); // 'awesome'
149
+ console.log(foo.baz); // 100
152
150
  ```
153
151
 
154
152
  Since the mock is type safe the compiler will guarantee that you're only mocking things that actually exist on the interface.
@@ -162,9 +160,9 @@ type Fn = (x: number) => number;
162
160
 
163
161
  const fn = mock<Fn>();
164
162
 
165
- when(fn(1)).thenReturn(2);
163
+ when(() => fn(1)).thenReturn(2);
166
164
 
167
- console.log(instance(fn)(1)); // 2
165
+ console.log(fn(1)); // 2
168
166
  ```
169
167
 
170
168
  ### Mocking promises
@@ -176,9 +174,9 @@ type Fn = (x: number) => Promise<number>;
176
174
 
177
175
  const fn = mock<Fn>();
178
176
 
179
- when(fn(1)).thenResolve(2);
177
+ when(() => fn(1)).thenResolve(2);
180
178
 
181
- console.log(await instance(fn)()); // 2
179
+ console.log(await fn()); // 2
182
180
  ```
183
181
 
184
182
  ### Throwing errors
@@ -190,8 +188,8 @@ type FnWithPromise = (x: number) => Promise<void>;
190
188
  const fn = mock<Fn>();
191
189
  const fnWithPromise = mock<FnWithPromise>();
192
190
 
193
- when(fn(1)).thenThrow();
194
- when(fnWithPromise(1)).thenReject();
191
+ when(() => fn(1)).thenThrow();
192
+ when(() => fnWithPromise(1)).thenReject();
195
193
  ```
196
194
 
197
195
  You'll notice there is no `never()` helper - if you expect a call to not be made simply don't set an expectation on it and the mock will throw if the call happens.
@@ -203,7 +201,7 @@ Calling `verify(mock)` will make sure that all expectations set on `mock` have b
203
201
  ```typescript
204
202
  const fn = mock<(x: number) => number>();
205
203
 
206
- when(fn(1)).thenReturn(1).between(2, 10);
204
+ when(() => fn(1)).thenReturn(1).between(2, 10);
207
205
 
208
206
  verify(fn); // throws
209
207
  ```
@@ -214,7 +212,7 @@ It will also throw if any unexpected calls happened that were maybe caught in th
214
212
  const fn = mock<() => void>();
215
213
 
216
214
  try {
217
- instance(fn)(); // throws because the call is unexpected
215
+ fn(); // throws because the call is unexpected
218
216
  } catch(e) {
219
217
  // your code might transition to an error state here
220
218
  }
@@ -222,7 +220,7 @@ try {
222
220
  verify(fn); // throws
223
221
  ```
224
222
 
225
- It is recommended that that you call `verify()` on your mocks at the end of every test. This will make sure you don't have any unused expectations in your tests and that your code hasn't silently caught any of the errors that are thrown when an unexpected call happens. You can use `verifyAll()` to check all existing mocks e.g. in an `afterEach` hook.
223
+ It is recommended that you call `verify()` on your mocks at the end of every test. This will make sure you don't have any unused expectations in your tests and that your code did not silently catch any of the errors that are thrown when an unexpected call happens. You can use `verifyAll()` to check all existing mocks e.g. in an `afterEach` hook.
226
224
 
227
225
  ![verify error](./media/verify.png)
228
226
 
@@ -233,11 +231,11 @@ You can remove all expectations from a mock by using the `reset()` method:
233
231
  ```typescript
234
232
  const fn = mock<(x: number) => number>();
235
233
 
236
- when(fn(1)).thenReturn(1);
234
+ when(() => fn(1)).thenReturn(1);
237
235
 
238
236
  reset(fn);
239
237
 
240
- instance(fn)(1); // throws
238
+ fn(1); // throws
241
239
  ```
242
240
 
243
241
  If you create common mocks that are shared by multiple tests you should reset them before using them e.g. in a `beforeEach` hook. You can use `resetAll()` to reset all existing mocks.
@@ -251,18 +249,20 @@ const fn = mock<
251
249
  (x: number, data: { values: number[]; labels: string[] }) => string
252
250
  >();
253
251
 
254
- when(fn(
252
+ when(() => fn(
255
253
  It.isAny(),
256
254
  It.isObject({ values: [1, 2, 3] })
257
255
  )).thenReturn('matched!');
258
256
 
259
- console.log(instance(fn)(
257
+ console.log(fn(
260
258
  123,
261
259
  { values: [1, 2, 3], labels: ['a', 'b', 'c'] })
262
260
  ); // 'matched!'
263
261
  ```
264
262
 
265
263
  Available matchers:
264
+ - `deepEquals` - the default, uses deep equality,
265
+ - `is` - uses `Object.is` for comparison,
266
266
  - `isAny` - matches anything,
267
267
  - `isNumber` - matches any number,
268
268
  - `isString` - matches any string, can search for substrings and patterns,
@@ -271,6 +271,15 @@ Available matchers:
271
271
  - `matches` - build your own matcher,
272
272
  - `willCapture` - matches anything and stores the received value.
273
273
 
274
+ The following table illustrates the differences between the equality matchers:
275
+
276
+ | expected | actual | `It.is` | `It.deepEquals` | `It.deepEquals({ strict: false })` |
277
+ |--------------------|----------------------|-----------|-----------------|------------------------------------|
278
+ | `"foo"` | `"bar"` | equal | equal | equal |
279
+ | `{ foo: "bar" }` | `{ foo: "bar" }` | not equal | equal | equal |
280
+ | `{ }` | `{ foo: undefined }` | not equal | not equal | equal |
281
+ | `new (class {})()` | `new (class {})()` | not equal | not equal | equal |
282
+
274
283
  Some matchers, like `isObject` and `isArray` support nesting matchers:
275
284
 
276
285
  ```typescript
@@ -286,9 +295,9 @@ You can create arbitrarily complex and type safe matchers with `It.matches(cb)`:
286
295
  ```typescript
287
296
  const fn = mock<(x: number, y: number[]) => string>();
288
297
 
289
- when(fn(
298
+ when(() => fn(
290
299
  It.matches(x => x > 0),
291
- It.matches(y => y.values.includes(42))
300
+ It.matches(y => y.includes(42))
292
301
  )).thenReturn('matched');
293
302
  ```
294
303
 
@@ -300,19 +309,37 @@ type Cb = (value: number) => number;
300
309
  const fn = mock<(cb: Cb) => number>();
301
310
 
302
311
  const matcher = It.willCapture<Cb>();
303
- when(fn(matcher)).thenReturn(42);
312
+ when(() => fn(matcher)).thenReturn(42);
304
313
 
305
- console.log(instance(fn)(23, (x) => x + 1)); // 42
314
+ console.log(fn(23, (x) => x + 1)); // 42
306
315
  console.log(matcher.value?.(3)); // 4
307
316
  ```
308
317
 
318
+ ### Overriding default matcher
319
+
320
+ You can override the default matcher that will be used when setting expectations with non-matcher values e.g. `42` or `{ foo: "bar" }`.
321
+
322
+ ```ts
323
+ import { mock, when, It, setDefaults } from 'strong-mock';
324
+
325
+ // Use strict equality instead of deep equality.
326
+ setDefaults({
327
+ matcher: It.is
328
+ })
329
+
330
+ const fn = mock<(x: number[]) => boolean>();
331
+ when(() => fn([1, 2, 3])).thenReturn(true);
332
+
333
+ fn([1, 2, 3]); // throws because different arrays
334
+ ```
335
+
309
336
  ## FAQ
310
337
 
311
338
  ### Why do I have to set all expectations first?
312
339
 
313
340
  This library is different from other mocking/spying libraries you might have used before such as [sinon](https://sinonjs.org) or [jest](https://jestjs.io/docs/en/mock-functions). Whereas those libraries are focused on recording calls to the mocks and always returning something, strong-mock requires you to set your expectations upfront. If a call happens that is not expected the mock will throw an error.
314
341
 
315
- This design decision has a few reasons behind it. First of all, it forces you to be aware of what your code needs from its dependencies. Spying libraries encourage checking those needs at the end of the test after the code has already called the mocks. This can lead to tests missing dependency calls that just happen to not throw any error at runtime with the dummy values that the spies return.
342
+ This design decision has a few reasons behind it. First, it forces you to be aware of what your code needs from its dependencies. Spying libraries encourage checking those needs at the end of the test after the code has already called the mocks. This can lead to tests missing dependency calls that just happen to not throw any error at runtime with the dummy values that the spies return.
316
343
 
317
344
  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.
318
345
 
@@ -326,11 +353,11 @@ You currently can't do that. Please use a normal method instead e.g. `setFoo()`
326
353
 
327
354
  ### Why do I have to set a return value even if it's `undefined`?
328
355
 
329
- To make side effects explicit and to prevent future refactoring headaches. If you would have 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.
356
+ 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.
330
357
 
331
358
  ### How do I provide a function for the mock to call?
332
359
 
333
- 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:
360
+ 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:
334
361
 
335
362
  ```typescript
336
363
  interface Foo {
@@ -339,12 +366,12 @@ interface Foo {
339
366
 
340
367
  const foo = mock<Foo>();
341
368
 
342
- when(foo.bar).thenReturn(x => `called ${x}`);
369
+ when(() => foo.bar).thenReturn(x => `called ${x}`);
343
370
 
344
- console.log(instance(foo).bar(23)); // 'called 23'
371
+ console.log(foo.bar(23)); // 'called 23'
345
372
  ```
346
373
 
347
- 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).
374
+ 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).
348
375
 
349
376
  ![call-rename](media/rename-args.gif)
350
377
 
@@ -370,10 +397,10 @@ function doFoo(foo: Foo, { callBaz }: { callBaz: boolean }) {
370
397
  }
371
398
 
372
399
  const foo = mock<Foo>();
373
- when(foo.bar()).thenReturn(42);
400
+ when(() => foo.bar()).thenReturn(42);
374
401
 
375
402
  // Throws with unexpected access on `baz`.
376
- doFoo(instance(foo), { callBaz: false });
403
+ doFoo(foo, { callBaz: false });
377
404
  ```
378
405
 
379
406
  To work around this, either change your code to avoid destructuring
@@ -391,21 +418,42 @@ function doFoo(foo: Foo, callBaz: boolean) {
391
418
  or set a dummy expectation on the methods you're not interested in during the test.
392
419
 
393
420
  ```typescript
394
- when(foo.baz()).thenThrow('should not be called').anyTimes();
421
+ when(() => foo.baz()).thenThrow('should not be called').anyTimes();
395
422
  ```
396
423
 
397
- ### Can I spread/enumerate a mock instance?
424
+ ### Can I spread/enumerate a mock?
398
425
 
399
426
  Yes, and you will only get the properties that have expectations on them.
400
427
 
401
428
  ```typescript
402
429
  const foo = mock<{ bar: number; baz: number }>();
403
- when(foo.bar).thenReturn(42);
430
+ when(() => foo.bar).thenReturn(42);
404
431
 
405
- console.log(Object.keys(instance(foo))); // ['bar']
432
+ console.log(Object.keys(foo)); // ['bar']
406
433
 
407
- const foo2 = { ...instance(foo) };
434
+ const foo2 = { ...foo };
408
435
 
409
436
  console.log(foo2.bar); // 42
410
437
  console.log(foo2.baz); // undefined
411
438
  ```
439
+
440
+
441
+ ### How can I ignore `undefined` keys when setting expectations on objects?
442
+
443
+ Use the `It.deepEquals` matcher explicitly inside `when` and pass `{ strict: false }`:
444
+
445
+ ```ts
446
+ const fn = mock<(x: { foo: string }) => boolean>();
447
+
448
+ when(() => fn(It.deepEquals({ foo: "bar" }, { strict: false }))).thenReturn(true);
449
+
450
+ fn({ foo: "bar", baz: undefined }) === true
451
+ ```
452
+
453
+ You can also set this behavior to be the default by using [`setDefaults`](#overriding-default-matcher):
454
+
455
+ ```ts
456
+ setDefaults({
457
+ matcher: (expected) => It.deepEquals(expected, { strict: false })
458
+ });
459
+ ```
package/dist/errors.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Expectation } from './expectation/expectation';
2
2
  import { CallMap } from './expectation/repository/expectation-repository';
3
- import { PendingExpectation } from './when/pending-expectation';
4
3
  import { Property } from './proxy';
4
+ import { PendingExpectation } from './when/pending-expectation';
5
5
  export declare class UnfinishedExpectation extends Error {
6
6
  constructor(pendingExpectation: PendingExpectation);
7
7
  }
@@ -1,16 +1,20 @@
1
1
  import { Property } from '../proxy';
2
+ import { Matcher } from './matcher';
2
3
  export declare type ReturnValue = {
3
4
  value: any;
4
5
  isPromise?: boolean;
5
6
  isError?: boolean;
6
7
  };
8
+ /**
9
+ * Compare received arguments against matchers.
10
+ */
7
11
  export interface Expectation {
8
12
  property: Property;
9
13
  /**
10
14
  * `undefined` means this is a property expectation.
11
15
  * `[]` means this is a function call with no arguments.
12
16
  */
13
- args: any[] | undefined;
17
+ args: Matcher[] | undefined;
14
18
  returnValue: ReturnValue;
15
19
  min: number;
16
20
  max: number;
@@ -0,0 +1,29 @@
1
+ import { Matcher, TypeMatcher } from './matcher';
2
+ declare type DeepPartial<T> = T extends object ? {
3
+ [K in keyof T]?: DeepPartial<T[K]>;
4
+ } : T;
5
+ /**
6
+ * Contains argument matchers that can be used to ignore arguments in an
7
+ * expectation or to match complex arguments.
8
+ */
9
+ export declare const It: {
10
+ matches: <T>(cb: (actual: T) => boolean, { toJSON }?: {
11
+ toJSON?: (() => string) | undefined;
12
+ }) => TypeMatcher<T>;
13
+ deepEquals: <T_1>(expected: T_1, { strict }?: {
14
+ strict?: boolean | undefined;
15
+ }) => TypeMatcher<T_1>;
16
+ is: <T_2 = unknown>(expected: T_2) => TypeMatcher<T_2>;
17
+ isAny: () => TypeMatcher<any>;
18
+ isObject: <T_3 extends object, K extends DeepPartial<T_3>>(partial?: K | undefined) => TypeMatcher<T_3>;
19
+ isNumber: () => TypeMatcher<number>;
20
+ isString: ({ matching, containing, }?: {
21
+ matching?: RegExp | undefined;
22
+ containing?: string | undefined;
23
+ }) => TypeMatcher<string>;
24
+ isArray: <T_4 extends any[]>(containing?: T_4 | undefined) => TypeMatcher<T_4>;
25
+ willCapture: <T_5 = unknown>(name?: string) => T_5 & Matcher & {
26
+ value: T_5 | undefined;
27
+ };
28
+ };
29
+ export {};
@@ -1,57 +1,21 @@
1
- export declare type Matcher<T> = T & {
1
+ export declare const MATCHER_SYMBOL: unique symbol;
2
+ export declare type Matcher = {
2
3
  /**
3
4
  * Will be called with a value to match against.
4
5
  */
5
- matches: (arg: unknown) => boolean;
6
- /**
7
- * TODO: turn into a symbol
8
- */
9
- __isMatcher: boolean;
6
+ matches: (arg: any) => boolean;
7
+ [MATCHER_SYMBOL]: boolean;
10
8
  /**
11
9
  * Used by `pretty-format`.
12
10
  */
13
11
  toJSON(): string;
14
12
  };
15
13
  /**
16
- * Use to test if an expectation on an argument is a custom matcher.
14
+ * This takes the shape of T to satisfy call sites, but strong-mock will only
15
+ * care about the matcher type.
17
16
  */
18
- export declare function isMatcher(f: unknown): f is Matcher<unknown>;
17
+ export declare type TypeMatcher<T> = T & Matcher;
19
18
  /**
20
- * The default matcher that checks for deep equality.
19
+ * Used to test if an expectation on an argument is a custom matcher.
21
20
  */
22
- export declare const deepEquals: <T>(expected: T) => Matcher<T>;
23
- declare type DeepPartial<T> = T extends object ? {
24
- [K in keyof T]?: DeepPartial<T[K]>;
25
- } : T;
26
- /**
27
- * Contains argument matchers that can be used to ignore arguments in an
28
- * expectation or to match complex arguments.
29
- */
30
- export declare const It: {
31
- isAny: () => Matcher<any>;
32
- matches: <T>(cb: (arg: T) => boolean) => Matcher<T>;
33
- isObject: <T_1 extends object, K extends DeepPartial<T_1>>(partial?: K | undefined) => Matcher<T_1>;
34
- isNumber: () => Matcher<number>;
35
- isString: ({ matching, containing, }?: {
36
- matching?: RegExp | undefined;
37
- containing?: string | undefined;
38
- }) => Matcher<string>;
39
- isArray: <T_2 extends any[]>(containing?: T_2 | undefined) => Matcher<T_2>;
40
- willCapture: <T_3 = unknown>(name?: string | undefined) => T_3 & {
41
- /**
42
- * Will be called with a value to match against.
43
- */
44
- matches: (arg: unknown) => boolean;
45
- /**
46
- * TODO: turn into a symbol
47
- */
48
- __isMatcher: boolean;
49
- /**
50
- * Used by `pretty-format`.
51
- */
52
- toJSON(): string;
53
- } & {
54
- value: T_3 | undefined;
55
- };
56
- };
57
- export {};
21
+ export declare function isMatcher(f: unknown): f is Matcher;
@@ -1,6 +1,6 @@
1
+ import { Property } from '../../proxy';
1
2
  import { Expectation, ReturnValue } from '../expectation';
2
3
  import { CallMap, ExpectationRepository } from './expectation-repository';
3
- import { Property } from '../../proxy';
4
4
  export declare type CountableExpectation = {
5
5
  expectation: Expectation;
6
6
  matchCount: number;
@@ -2,25 +2,24 @@ import { Property } from '../proxy';
2
2
  import { Expectation, ReturnValue } from './expectation';
3
3
  import { Matcher } from './matcher';
4
4
  /**
5
- * Deeply compare actual arguments against expected ones.
6
- *
7
- * Supports argument matchers. Matches a call with more parameters
8
- * than expected because it is assumed the compiler will check that those
9
- * parameters are optional.
5
+ * Matches a call with more parameters than expected because it is assumed the
6
+ * compiler will check that those parameters are optional.
10
7
  *
11
8
  * @example
12
- * new Expectation('bar', [1, 2, 3], 23).matches('bar', [1, 2, 3]) === true;
13
- * new Expectation('bar', [1, 2, 3], 23).matches('bar', [1, 2]) === false;
14
- * new Expectation('bar', [1, 2], 23).matches('bar', [1, 2, 3]) === true;
9
+ * new StrongExpectation(
10
+ * 'bar',
11
+ * deepEquals([1, 2, 3]),
12
+ * 23
13
+ * ).matches('bar', [1, 2, 3]) === true;
15
14
  */
16
15
  export declare class StrongExpectation implements Expectation {
17
16
  property: Property;
18
- args: Matcher<any>[] | undefined;
17
+ args: Matcher[] | undefined;
19
18
  returnValue: ReturnValue;
20
19
  private matched;
21
20
  min: number;
22
21
  max: number;
23
- constructor(property: Property, args: Matcher<any>[] | undefined, returnValue: ReturnValue);
22
+ constructor(property: Property, args: Matcher[] | undefined, returnValue: ReturnValue);
24
23
  setInvocationCount(min: number, max?: number): void;
25
24
  matches(args: any[] | undefined): boolean;
26
25
  isUnmet(): boolean;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { instance } from './instance/instance';
2
- import { It } from './expectation/matcher';
3
- import { mock } from './mock/mock';
4
- import { reset, resetAll } from './verify/reset';
5
- import { verify, verifyAll } from './verify/verify';
6
- import { when } from './when/when';
7
- export { mock, when, instance, verify, verifyAll, reset, resetAll, It };
1
+ export { mock } from './mock/mock';
2
+ export { when } from './when/when';
3
+ export { reset, resetAll } from './verify/reset';
4
+ export { verify, verifyAll } from './verify/verify';
5
+ export { It } from './expectation/it';
6
+ export { setDefaults } from './mock/defaults';
7
+ export type { Matcher } from './expectation/matcher';
8
+ export type { StrongMockDefaults } from './mock/defaults';