@vitest/expect 2.1.3 → 2.1.5
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 +1 -1
- package/dist/index.d.ts +453 -11
- package/dist/index.js +93 -39
- package/package.json +5 -5
package/README.md
CHANGED
@@ -5,12 +5,12 @@ Jest's expect matchers as a Chai plugin.
|
|
5
5
|
## Usage
|
6
6
|
|
7
7
|
```js
|
8
|
-
import * as chai from 'chai'
|
9
8
|
import {
|
10
9
|
JestAsymmetricMatchers,
|
11
10
|
JestChaiExpect,
|
12
11
|
JestExtend,
|
13
12
|
} from '@vitest/expect'
|
13
|
+
import * as chai from 'chai'
|
14
14
|
|
15
15
|
// allows using expect.extend instead of chai.use to extend plugins
|
16
16
|
chai.use(JestExtend)
|
package/dist/index.d.ts
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
+
import { stringify, Constructable } from '@vitest/utils';
|
1
2
|
import * as tinyrainbow from 'tinyrainbow';
|
2
3
|
import { Formatter } from 'tinyrainbow';
|
3
|
-
import { stringify, Constructable } from '@vitest/utils';
|
4
4
|
import { diff, printDiffOrStringify } from '@vitest/utils/diff';
|
5
5
|
export { DiffOptions } from '@vitest/utils/diff';
|
6
6
|
|
7
|
+
declare const MATCHERS_OBJECT: unique symbol;
|
8
|
+
declare const JEST_MATCHERS_OBJECT: unique symbol;
|
9
|
+
declare const GLOBAL_EXPECT: unique symbol;
|
10
|
+
declare const ASYMMETRIC_MATCHERS_OBJECT: unique symbol;
|
11
|
+
|
7
12
|
declare function matcherHint(matcherName: string, received?: string, expected?: string, options?: MatcherHintOptions): string;
|
8
13
|
declare function printReceived(object: unknown): string;
|
9
14
|
declare function printExpected(value: unknown): string;
|
@@ -92,55 +97,433 @@ interface ExpectStatic extends Chai.ExpectStatic, AsymmetricMatchersContaining {
|
|
92
97
|
not: AsymmetricMatchersContaining;
|
93
98
|
}
|
94
99
|
interface AsymmetricMatchersContaining {
|
100
|
+
/**
|
101
|
+
* Matches if the received string contains the expected substring.
|
102
|
+
*
|
103
|
+
* @example
|
104
|
+
* expect('I have an apple').toEqual(expect.stringContaining('apple'));
|
105
|
+
* expect({ a: 'test string' }).toEqual({ a: expect.stringContaining('test') });
|
106
|
+
*/
|
95
107
|
stringContaining: (expected: string) => any;
|
108
|
+
/**
|
109
|
+
* Matches if the received object contains all properties of the expected object.
|
110
|
+
*
|
111
|
+
* @example
|
112
|
+
* expect({ a: '1', b: 2 }).toEqual(expect.objectContaining({ a: '1' }))
|
113
|
+
*/
|
96
114
|
objectContaining: <T = any>(expected: T) => any;
|
115
|
+
/**
|
116
|
+
* Matches if the received array contains all elements in the expected array.
|
117
|
+
*
|
118
|
+
* @example
|
119
|
+
* expect(['a', 'b', 'c']).toEqual(expect.arrayContaining(['b', 'a']));
|
120
|
+
*/
|
97
121
|
arrayContaining: <T = unknown>(expected: Array<T>) => any;
|
122
|
+
/**
|
123
|
+
* Matches if the received string or regex matches the expected pattern.
|
124
|
+
*
|
125
|
+
* @example
|
126
|
+
* expect('hello world').toEqual(expect.stringMatching(/^hello/));
|
127
|
+
* expect('hello world').toEqual(expect.stringMatching('hello'));
|
128
|
+
*/
|
98
129
|
stringMatching: (expected: string | RegExp) => any;
|
130
|
+
/**
|
131
|
+
* Matches if the received number is within a certain precision of the expected number.
|
132
|
+
*
|
133
|
+
* @param precision - Optional decimal precision for comparison. Default is 2.
|
134
|
+
*
|
135
|
+
* @example
|
136
|
+
* expect(10.45).toEqual(expect.closeTo(10.5, 1));
|
137
|
+
* expect(5.11).toEqual(expect.closeTo(5.12)); // with default precision
|
138
|
+
*/
|
99
139
|
closeTo: (expected: number, precision?: number) => any;
|
100
140
|
}
|
101
141
|
interface JestAssertion<T = any> extends jest.Matchers<void, T> {
|
142
|
+
/**
|
143
|
+
* Used when you want to check that two objects have the same value.
|
144
|
+
* This matcher recursively checks the equality of all fields, rather than checking for object identity.
|
145
|
+
*
|
146
|
+
* @example
|
147
|
+
* expect(user).toEqual({ name: 'Alice', age: 30 });
|
148
|
+
*/
|
102
149
|
toEqual: <E>(expected: E) => void;
|
150
|
+
/**
|
151
|
+
* Use to test that objects have the same types as well as structure.
|
152
|
+
*
|
153
|
+
* @example
|
154
|
+
* expect(user).toStrictEqual({ name: 'Alice', age: 30 });
|
155
|
+
*/
|
103
156
|
toStrictEqual: <E>(expected: E) => void;
|
157
|
+
/**
|
158
|
+
* Checks that a value is what you expect. It calls `Object.is` to compare values.
|
159
|
+
* Don't use `toBe` with floating-point numbers.
|
160
|
+
*
|
161
|
+
* @example
|
162
|
+
* expect(result).toBe(42);
|
163
|
+
* expect(status).toBe(true);
|
164
|
+
*/
|
104
165
|
toBe: <E>(expected: E) => void;
|
166
|
+
/**
|
167
|
+
* Check that a string matches a regular expression.
|
168
|
+
*
|
169
|
+
* @example
|
170
|
+
* expect(message).toMatch(/hello/);
|
171
|
+
* expect(greeting).toMatch('world');
|
172
|
+
*/
|
105
173
|
toMatch: (expected: string | RegExp) => void;
|
174
|
+
/**
|
175
|
+
* Used to check that a JavaScript object matches a subset of the properties of an object
|
176
|
+
*
|
177
|
+
* @example
|
178
|
+
* expect(user).toMatchObject({
|
179
|
+
* name: 'Alice',
|
180
|
+
* address: { city: 'Wonderland' }
|
181
|
+
* });
|
182
|
+
*/
|
106
183
|
toMatchObject: <E extends object | any[]>(expected: E) => void;
|
184
|
+
/**
|
185
|
+
* Used when you want to check that an item is in a list.
|
186
|
+
* For testing the items in the list, this uses `===`, a strict equality check.
|
187
|
+
*
|
188
|
+
* @example
|
189
|
+
* expect(items).toContain('apple');
|
190
|
+
* expect(numbers).toContain(5);
|
191
|
+
*/
|
107
192
|
toContain: <E>(item: E) => void;
|
193
|
+
/**
|
194
|
+
* Used when you want to check that an item is in a list.
|
195
|
+
* For testing the items in the list, this matcher recursively checks the
|
196
|
+
* equality of all fields, rather than checking for object identity.
|
197
|
+
*
|
198
|
+
* @example
|
199
|
+
* expect(items).toContainEqual({ name: 'apple', quantity: 1 });
|
200
|
+
*/
|
108
201
|
toContainEqual: <E>(item: E) => void;
|
202
|
+
/**
|
203
|
+
* Use when you don't care what a value is, you just want to ensure a value
|
204
|
+
* is true in a boolean context. In JavaScript, there are six falsy values:
|
205
|
+
* `false`, `0`, `''`, `null`, `undefined`, and `NaN`. Everything else is truthy.
|
206
|
+
*
|
207
|
+
* @example
|
208
|
+
* expect(user.isActive).toBeTruthy();
|
209
|
+
*/
|
109
210
|
toBeTruthy: () => void;
|
211
|
+
/**
|
212
|
+
* When you don't care what a value is, you just want to
|
213
|
+
* ensure a value is false in a boolean context.
|
214
|
+
*
|
215
|
+
* @example
|
216
|
+
* expect(user.isActive).toBeFalsy();
|
217
|
+
*/
|
110
218
|
toBeFalsy: () => void;
|
219
|
+
/**
|
220
|
+
* For comparing floating point numbers.
|
221
|
+
*
|
222
|
+
* @example
|
223
|
+
* expect(score).toBeGreaterThan(10);
|
224
|
+
*/
|
111
225
|
toBeGreaterThan: (num: number | bigint) => void;
|
226
|
+
/**
|
227
|
+
* For comparing floating point numbers.
|
228
|
+
*
|
229
|
+
* @example
|
230
|
+
* expect(score).toBeGreaterThanOrEqual(10);
|
231
|
+
*/
|
112
232
|
toBeGreaterThanOrEqual: (num: number | bigint) => void;
|
233
|
+
/**
|
234
|
+
* For comparing floating point numbers.
|
235
|
+
*
|
236
|
+
* @example
|
237
|
+
* expect(score).toBeLessThan(10);
|
238
|
+
*/
|
113
239
|
toBeLessThan: (num: number | bigint) => void;
|
240
|
+
/**
|
241
|
+
* For comparing floating point numbers.
|
242
|
+
*
|
243
|
+
* @example
|
244
|
+
* expect(score).toBeLessThanOrEqual(10);
|
245
|
+
*/
|
114
246
|
toBeLessThanOrEqual: (num: number | bigint) => void;
|
247
|
+
/**
|
248
|
+
* Used to check that a variable is NaN.
|
249
|
+
*
|
250
|
+
* @example
|
251
|
+
* expect(value).toBeNaN();
|
252
|
+
*/
|
115
253
|
toBeNaN: () => void;
|
254
|
+
/**
|
255
|
+
* Used to check that a variable is undefined.
|
256
|
+
*
|
257
|
+
* @example
|
258
|
+
* expect(value).toBeUndefined();
|
259
|
+
*/
|
116
260
|
toBeUndefined: () => void;
|
261
|
+
/**
|
262
|
+
* This is the same as `.toBe(null)` but the error messages are a bit nicer.
|
263
|
+
* So use `.toBeNull()` when you want to check that something is null.
|
264
|
+
*
|
265
|
+
* @example
|
266
|
+
* expect(value).toBeNull();
|
267
|
+
*/
|
117
268
|
toBeNull: () => void;
|
269
|
+
/**
|
270
|
+
* Ensure that a variable is not undefined.
|
271
|
+
*
|
272
|
+
* @example
|
273
|
+
* expect(value).toBeDefined();
|
274
|
+
*/
|
118
275
|
toBeDefined: () => void;
|
276
|
+
/**
|
277
|
+
* Ensure that an object is an instance of a class.
|
278
|
+
* This matcher uses `instanceof` underneath.
|
279
|
+
*
|
280
|
+
* @example
|
281
|
+
* expect(new Date()).toBeInstanceOf(Date);
|
282
|
+
*/
|
119
283
|
toBeInstanceOf: <E>(expected: E) => void;
|
120
|
-
|
284
|
+
/**
|
285
|
+
* Used to check that an object has a `.length` property
|
286
|
+
* and it is set to a certain numeric value.
|
287
|
+
*
|
288
|
+
* @example
|
289
|
+
* expect([1, 2, 3]).toHaveLength(3);
|
290
|
+
* expect('hello').toHaveLength(5);
|
291
|
+
*/
|
121
292
|
toHaveLength: (length: number) => void;
|
293
|
+
/**
|
294
|
+
* Use to check if a property at the specified path exists on an object.
|
295
|
+
* For checking deeply nested properties, you may use dot notation or an array containing
|
296
|
+
* the path segments for deep references.
|
297
|
+
*
|
298
|
+
* Optionally, you can provide a value to check if it matches the value present at the path
|
299
|
+
* on the target object. This matcher uses 'deep equality' (like `toEqual()`) and recursively checks
|
300
|
+
* the equality of all fields.
|
301
|
+
*
|
302
|
+
* @example
|
303
|
+
* expect(user).toHaveProperty('address.city', 'New York');
|
304
|
+
* expect(config).toHaveProperty(['settings', 'theme'], 'dark');
|
305
|
+
*/
|
122
306
|
toHaveProperty: <E>(property: string | (string | number)[], value?: E) => void;
|
307
|
+
/**
|
308
|
+
* Using exact equality with floating point numbers is a bad idea.
|
309
|
+
* Rounding means that intuitive things fail.
|
310
|
+
* The default for `precision` is 2.
|
311
|
+
*
|
312
|
+
* @example
|
313
|
+
* expect(price).toBeCloseTo(9.99, 2);
|
314
|
+
*/
|
123
315
|
toBeCloseTo: (number: number, numDigits?: number) => void;
|
316
|
+
/**
|
317
|
+
* Ensures that a mock function is called an exact number of times.
|
318
|
+
*
|
319
|
+
* Also under the alias `expect.toBeCalledTimes`.
|
320
|
+
*
|
321
|
+
* @example
|
322
|
+
* expect(mockFunc).toHaveBeenCalledTimes(2);
|
323
|
+
*/
|
124
324
|
toHaveBeenCalledTimes: (times: number) => void;
|
325
|
+
/**
|
326
|
+
* Ensures that a mock function is called an exact number of times.
|
327
|
+
*
|
328
|
+
* Alias for `expect.toHaveBeenCalledTimes`.
|
329
|
+
*
|
330
|
+
* @example
|
331
|
+
* expect(mockFunc).toBeCalledTimes(2);
|
332
|
+
*/
|
333
|
+
toBeCalledTimes: (times: number) => void;
|
334
|
+
/**
|
335
|
+
* Ensures that a mock function is called.
|
336
|
+
*
|
337
|
+
* Also under the alias `expect.toBeCalled`.
|
338
|
+
*
|
339
|
+
* @example
|
340
|
+
* expect(mockFunc).toHaveBeenCalled();
|
341
|
+
*/
|
125
342
|
toHaveBeenCalled: () => void;
|
343
|
+
/**
|
344
|
+
* Ensures that a mock function is called.
|
345
|
+
*
|
346
|
+
* Alias for `expect.toHaveBeenCalled`.
|
347
|
+
*
|
348
|
+
* @example
|
349
|
+
* expect(mockFunc).toBeCalled();
|
350
|
+
*/
|
126
351
|
toBeCalled: () => void;
|
352
|
+
/**
|
353
|
+
* Ensure that a mock function is called with specific arguments.
|
354
|
+
*
|
355
|
+
* Also under the alias `expect.toBeCalledWith`.
|
356
|
+
*
|
357
|
+
* @example
|
358
|
+
* expect(mockFunc).toHaveBeenCalledWith('arg1', 42);
|
359
|
+
*/
|
127
360
|
toHaveBeenCalledWith: <E extends any[]>(...args: E) => void;
|
361
|
+
/**
|
362
|
+
* Ensure that a mock function is called with specific arguments.
|
363
|
+
*
|
364
|
+
* Alias for `expect.toHaveBeenCalledWith`.
|
365
|
+
*
|
366
|
+
* @example
|
367
|
+
* expect(mockFunc).toBeCalledWith('arg1', 42);
|
368
|
+
*/
|
128
369
|
toBeCalledWith: <E extends any[]>(...args: E) => void;
|
370
|
+
/**
|
371
|
+
* Ensure that a mock function is called with specific arguments on an Nth call.
|
372
|
+
*
|
373
|
+
* Also under the alias `expect.nthCalledWith`.
|
374
|
+
*
|
375
|
+
* @example
|
376
|
+
* expect(mockFunc).toHaveBeenNthCalledWith(2, 'secondArg');
|
377
|
+
*/
|
129
378
|
toHaveBeenNthCalledWith: <E extends any[]>(n: number, ...args: E) => void;
|
379
|
+
/**
|
380
|
+
* Ensure that a mock function is called with specific arguments on an Nth call.
|
381
|
+
*
|
382
|
+
* Alias for `expect.toHaveBeenNthCalledWith`.
|
383
|
+
*
|
384
|
+
* @example
|
385
|
+
* expect(mockFunc).nthCalledWith(2, 'secondArg');
|
386
|
+
*/
|
130
387
|
nthCalledWith: <E extends any[]>(nthCall: number, ...args: E) => void;
|
388
|
+
/**
|
389
|
+
* If you have a mock function, you can use `.toHaveBeenLastCalledWith`
|
390
|
+
* to test what arguments it was last called with.
|
391
|
+
*
|
392
|
+
* Also under the alias `expect.lastCalledWith`.
|
393
|
+
*
|
394
|
+
* @example
|
395
|
+
* expect(mockFunc).toHaveBeenLastCalledWith('lastArg');
|
396
|
+
*/
|
131
397
|
toHaveBeenLastCalledWith: <E extends any[]>(...args: E) => void;
|
398
|
+
/**
|
399
|
+
* If you have a mock function, you can use `.lastCalledWith`
|
400
|
+
* to test what arguments it was last called with.
|
401
|
+
*
|
402
|
+
* Alias for `expect.toHaveBeenLastCalledWith`.
|
403
|
+
*
|
404
|
+
* @example
|
405
|
+
* expect(mockFunc).lastCalledWith('lastArg');
|
406
|
+
*/
|
132
407
|
lastCalledWith: <E extends any[]>(...args: E) => void;
|
408
|
+
/**
|
409
|
+
* Used to test that a function throws when it is called.
|
410
|
+
*
|
411
|
+
* Also under the alias `expect.toThrowError`.
|
412
|
+
*
|
413
|
+
* @example
|
414
|
+
* expect(() => functionWithError()).toThrow('Error message');
|
415
|
+
* expect(() => parseJSON('invalid')).toThrow(SyntaxError);
|
416
|
+
*/
|
133
417
|
toThrow: (expected?: string | Constructable | RegExp | Error) => void;
|
418
|
+
/**
|
419
|
+
* Used to test that a function throws when it is called.
|
420
|
+
*
|
421
|
+
* Alias for `expect.toThrow`.
|
422
|
+
*
|
423
|
+
* @example
|
424
|
+
* expect(() => functionWithError()).toThrowError('Error message');
|
425
|
+
* expect(() => parseJSON('invalid')).toThrowError(SyntaxError);
|
426
|
+
*/
|
134
427
|
toThrowError: (expected?: string | Constructable | RegExp | Error) => void;
|
428
|
+
/**
|
429
|
+
* Use to test that the mock function successfully returned (i.e., did not throw an error) at least one time
|
430
|
+
*
|
431
|
+
* Alias for `expect.toHaveReturned`.
|
432
|
+
*
|
433
|
+
* @example
|
434
|
+
* expect(mockFunc).toReturn();
|
435
|
+
*/
|
135
436
|
toReturn: () => void;
|
437
|
+
/**
|
438
|
+
* Use to test that the mock function successfully returned (i.e., did not throw an error) at least one time
|
439
|
+
*
|
440
|
+
* Also under the alias `expect.toReturn`.
|
441
|
+
*
|
442
|
+
* @example
|
443
|
+
* expect(mockFunc).toHaveReturned();
|
444
|
+
*/
|
136
445
|
toHaveReturned: () => void;
|
446
|
+
/**
|
447
|
+
* Use to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times.
|
448
|
+
* Any calls to the mock function that throw an error are not counted toward the number of times the function returned.
|
449
|
+
*
|
450
|
+
* Alias for `expect.toHaveReturnedTimes`.
|
451
|
+
*
|
452
|
+
* @example
|
453
|
+
* expect(mockFunc).toReturnTimes(3);
|
454
|
+
*/
|
137
455
|
toReturnTimes: (times: number) => void;
|
456
|
+
/**
|
457
|
+
* Use to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times.
|
458
|
+
* Any calls to the mock function that throw an error are not counted toward the number of times the function returned.
|
459
|
+
*
|
460
|
+
* Also under the alias `expect.toReturnTimes`.
|
461
|
+
*
|
462
|
+
* @example
|
463
|
+
* expect(mockFunc).toHaveReturnedTimes(3);
|
464
|
+
*/
|
138
465
|
toHaveReturnedTimes: (times: number) => void;
|
466
|
+
/**
|
467
|
+
* Use to ensure that a mock function returned a specific value.
|
468
|
+
*
|
469
|
+
* Alias for `expect.toHaveReturnedWith`.
|
470
|
+
*
|
471
|
+
* @example
|
472
|
+
* expect(mockFunc).toReturnWith('returnValue');
|
473
|
+
*/
|
139
474
|
toReturnWith: <E>(value: E) => void;
|
475
|
+
/**
|
476
|
+
* Use to ensure that a mock function returned a specific value.
|
477
|
+
*
|
478
|
+
* Also under the alias `expect.toReturnWith`.
|
479
|
+
*
|
480
|
+
* @example
|
481
|
+
* expect(mockFunc).toHaveReturnedWith('returnValue');
|
482
|
+
*/
|
140
483
|
toHaveReturnedWith: <E>(value: E) => void;
|
484
|
+
/**
|
485
|
+
* Use to test the specific value that a mock function last returned.
|
486
|
+
* If the last call to the mock function threw an error, then this matcher will fail
|
487
|
+
* no matter what value you provided as the expected return value.
|
488
|
+
*
|
489
|
+
* Also under the alias `expect.lastReturnedWith`.
|
490
|
+
*
|
491
|
+
* @example
|
492
|
+
* expect(mockFunc).toHaveLastReturnedWith('lastValue');
|
493
|
+
*/
|
141
494
|
toHaveLastReturnedWith: <E>(value: E) => void;
|
495
|
+
/**
|
496
|
+
* Use to test the specific value that a mock function last returned.
|
497
|
+
* If the last call to the mock function threw an error, then this matcher will fail
|
498
|
+
* no matter what value you provided as the expected return value.
|
499
|
+
*
|
500
|
+
* Alias for `expect.toHaveLastReturnedWith`.
|
501
|
+
*
|
502
|
+
* @example
|
503
|
+
* expect(mockFunc).lastReturnedWith('lastValue');
|
504
|
+
*/
|
142
505
|
lastReturnedWith: <E>(value: E) => void;
|
506
|
+
/**
|
507
|
+
* Use to test the specific value that a mock function returned for the nth call.
|
508
|
+
* If the nth call to the mock function threw an error, then this matcher will fail
|
509
|
+
* no matter what value you provided as the expected return value.
|
510
|
+
*
|
511
|
+
* Also under the alias `expect.nthReturnedWith`.
|
512
|
+
*
|
513
|
+
* @example
|
514
|
+
* expect(mockFunc).toHaveNthReturnedWith(2, 'nthValue');
|
515
|
+
*/
|
143
516
|
toHaveNthReturnedWith: <E>(nthCall: number, value: E) => void;
|
517
|
+
/**
|
518
|
+
* Use to test the specific value that a mock function returned for the nth call.
|
519
|
+
* If the nth call to the mock function threw an error, then this matcher will fail
|
520
|
+
* no matter what value you provided as the expected return value.
|
521
|
+
*
|
522
|
+
* Alias for `expect.toHaveNthReturnedWith`.
|
523
|
+
*
|
524
|
+
* @example
|
525
|
+
* expect(mockFunc).nthReturnedWith(2, 'nthValue');
|
526
|
+
*/
|
144
527
|
nthReturnedWith: <E>(nthCall: number, value: E) => void;
|
145
528
|
}
|
146
529
|
type VitestAssertion<A, T> = {
|
@@ -151,15 +534,79 @@ type Promisify<O> = {
|
|
151
534
|
};
|
152
535
|
type PromisifyAssertion<T> = Promisify<Assertion<T>>;
|
153
536
|
interface Assertion<T = any> extends VitestAssertion<Chai.Assertion, T>, JestAssertion<T> {
|
537
|
+
/**
|
538
|
+
* Ensures a value is of a specific type.
|
539
|
+
*
|
540
|
+
* @example
|
541
|
+
* expect(value).toBeTypeOf('string');
|
542
|
+
* expect(number).toBeTypeOf('number');
|
543
|
+
*/
|
154
544
|
toBeTypeOf: (expected: 'bigint' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'undefined') => void;
|
545
|
+
/**
|
546
|
+
* Asserts that a mock function was called exactly once.
|
547
|
+
*
|
548
|
+
* @example
|
549
|
+
* expect(mockFunc).toHaveBeenCalledOnce();
|
550
|
+
*/
|
155
551
|
toHaveBeenCalledOnce: () => void;
|
552
|
+
/**
|
553
|
+
* Checks that a value satisfies a custom matcher function.
|
554
|
+
*
|
555
|
+
* @param matcher - A function returning a boolean based on the custom condition
|
556
|
+
* @param message - Optional custom error message on failure
|
557
|
+
*
|
558
|
+
* @example
|
559
|
+
* expect(age).toSatisfy(val => val >= 18, 'Age must be at least 18');
|
560
|
+
*/
|
156
561
|
toSatisfy: <E>(matcher: (value: E) => boolean, message?: string) => void;
|
562
|
+
/**
|
563
|
+
* Checks that a promise resolves successfully at least once.
|
564
|
+
*
|
565
|
+
* @example
|
566
|
+
* await expect(promise).toHaveResolved();
|
567
|
+
*/
|
157
568
|
toHaveResolved: () => void;
|
569
|
+
/**
|
570
|
+
* Checks that a promise resolves to a specific value.
|
571
|
+
*
|
572
|
+
* @example
|
573
|
+
* await expect(promise).toHaveResolvedWith('success');
|
574
|
+
*/
|
158
575
|
toHaveResolvedWith: <E>(value: E) => void;
|
576
|
+
/**
|
577
|
+
* Ensures a promise resolves a specific number of times.
|
578
|
+
*
|
579
|
+
* @example
|
580
|
+
* expect(mockAsyncFunc).toHaveResolvedTimes(3);
|
581
|
+
*/
|
159
582
|
toHaveResolvedTimes: (times: number) => void;
|
583
|
+
/**
|
584
|
+
* Asserts that the last resolved value of a promise matches an expected value.
|
585
|
+
*
|
586
|
+
* @example
|
587
|
+
* await expect(mockAsyncFunc).toHaveLastResolvedWith('finalResult');
|
588
|
+
*/
|
160
589
|
toHaveLastResolvedWith: <E>(value: E) => void;
|
590
|
+
/**
|
591
|
+
* Ensures a specific value was returned by a promise on the nth resolution.
|
592
|
+
*
|
593
|
+
* @example
|
594
|
+
* await expect(mockAsyncFunc).toHaveNthResolvedWith(2, 'secondResult');
|
595
|
+
*/
|
161
596
|
toHaveNthResolvedWith: <E>(nthCall: number, value: E) => void;
|
597
|
+
/**
|
598
|
+
* Verifies that a promise resolves.
|
599
|
+
*
|
600
|
+
* @example
|
601
|
+
* await expect(someAsyncFunc).resolves.toBe(42);
|
602
|
+
*/
|
162
603
|
resolves: PromisifyAssertion<T>;
|
604
|
+
/**
|
605
|
+
* Verifies that a promise rejects.
|
606
|
+
*
|
607
|
+
* @example
|
608
|
+
* await expect(someAsyncFunc).rejects.toThrow('error');
|
609
|
+
*/
|
163
610
|
rejects: PromisifyAssertion<T>;
|
164
611
|
}
|
165
612
|
declare global {
|
@@ -227,6 +674,10 @@ declare class StringMatching extends AsymmetricMatcher<RegExp> {
|
|
227
674
|
}
|
228
675
|
declare const JestAsymmetricMatchers: ChaiPlugin;
|
229
676
|
|
677
|
+
declare const JestChaiExpect: ChaiPlugin;
|
678
|
+
|
679
|
+
declare const JestExtend: ChaiPlugin;
|
680
|
+
|
230
681
|
declare function equals(a: unknown, b: unknown, customTesters?: Array<Tester>, strictCheck?: boolean): boolean;
|
231
682
|
declare function isAsymmetric(obj: any): boolean;
|
232
683
|
declare function hasAsymmetric(obj: any, seen?: Set<unknown>): boolean;
|
@@ -248,16 +699,7 @@ declare function getObjectSubset(object: any, subset: any, customTesters: Array<
|
|
248
699
|
stripped: number;
|
249
700
|
};
|
250
701
|
|
251
|
-
declare const MATCHERS_OBJECT: unique symbol;
|
252
|
-
declare const JEST_MATCHERS_OBJECT: unique symbol;
|
253
|
-
declare const GLOBAL_EXPECT: unique symbol;
|
254
|
-
declare const ASYMMETRIC_MATCHERS_OBJECT: unique symbol;
|
255
|
-
|
256
702
|
declare function getState<State extends MatcherState = MatcherState>(expect: ExpectStatic): State;
|
257
703
|
declare function setState<State extends MatcherState = MatcherState>(state: Partial<State>, expect: ExpectStatic): void;
|
258
704
|
|
259
|
-
declare const JestChaiExpect: ChaiPlugin;
|
260
|
-
|
261
|
-
declare const JestExtend: ChaiPlugin;
|
262
|
-
|
263
705
|
export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, type Assertion, AsymmetricMatcher, type AsymmetricMatcherInterface, type AsymmetricMatchersContaining, type AsyncExpectationResult, type ChaiPlugin, type ExpectStatic, type ExpectationResult, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, type JestAssertion, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, type MatcherHintOptions, type MatcherState, type MatchersObject, ObjectContaining, type PromisifyAssertion, type RawMatcherFn, StringContaining, StringMatching, type SyncExpectationResult, type Tester, type TesterContext, addCustomEqualityTesters, arrayBufferEquality, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality };
|
package/dist/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { getType, stringify, isObject, assertTypes } from '@vitest/utils';
|
2
|
-
import c from 'tinyrainbow';
|
3
2
|
import { diff, printDiffOrStringify } from '@vitest/utils/diff';
|
3
|
+
import c from 'tinyrainbow';
|
4
4
|
import { isMockFunction } from '@vitest/spy';
|
5
5
|
import { processError } from '@vitest/utils/error';
|
6
6
|
import { use, util } from 'chai';
|
@@ -12,39 +12,6 @@ const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for(
|
|
12
12
|
"asymmetric-matchers-object"
|
13
13
|
);
|
14
14
|
|
15
|
-
if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) {
|
16
|
-
const globalState = /* @__PURE__ */ new WeakMap();
|
17
|
-
const matchers = /* @__PURE__ */ Object.create(null);
|
18
|
-
const customEqualityTesters = [];
|
19
|
-
const assymetricMatchers = /* @__PURE__ */ Object.create(null);
|
20
|
-
Object.defineProperty(globalThis, MATCHERS_OBJECT, {
|
21
|
-
get: () => globalState
|
22
|
-
});
|
23
|
-
Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
|
24
|
-
configurable: true,
|
25
|
-
get: () => ({
|
26
|
-
state: globalState.get(globalThis[GLOBAL_EXPECT]),
|
27
|
-
matchers,
|
28
|
-
customEqualityTesters
|
29
|
-
})
|
30
|
-
});
|
31
|
-
Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, {
|
32
|
-
get: () => assymetricMatchers
|
33
|
-
});
|
34
|
-
}
|
35
|
-
function getState(expect) {
|
36
|
-
return globalThis[MATCHERS_OBJECT].get(expect);
|
37
|
-
}
|
38
|
-
function setState(state, expect) {
|
39
|
-
const map = globalThis[MATCHERS_OBJECT];
|
40
|
-
const current = map.get(expect) || {};
|
41
|
-
const results = Object.defineProperties(current, {
|
42
|
-
...Object.getOwnPropertyDescriptors(current),
|
43
|
-
...Object.getOwnPropertyDescriptors(state)
|
44
|
-
});
|
45
|
-
map.set(expect, results);
|
46
|
-
}
|
47
|
-
|
48
15
|
const EXPECTED_COLOR = c.green;
|
49
16
|
const RECEIVED_COLOR = c.red;
|
50
17
|
const INVERTED_COLOR = c.inverse;
|
@@ -229,6 +196,7 @@ function eq(a, b, aStack, bStack, customTesters, hasKey2) {
|
|
229
196
|
const numB = +b;
|
230
197
|
return numA === numB || Number.isNaN(numA) && Number.isNaN(numB);
|
231
198
|
}
|
199
|
+
// RegExps are compared by their source patterns and flags.
|
232
200
|
case "[object RegExp]":
|
233
201
|
return a.source === b.source && a.flags === b.flags;
|
234
202
|
}
|
@@ -610,6 +578,39 @@ function getObjectSubset(object, subset, customTesters) {
|
|
610
578
|
return { subset: getObjectSubsetWithContext()(object, subset), stripped };
|
611
579
|
}
|
612
580
|
|
581
|
+
if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) {
|
582
|
+
const globalState = /* @__PURE__ */ new WeakMap();
|
583
|
+
const matchers = /* @__PURE__ */ Object.create(null);
|
584
|
+
const customEqualityTesters = [];
|
585
|
+
const assymetricMatchers = /* @__PURE__ */ Object.create(null);
|
586
|
+
Object.defineProperty(globalThis, MATCHERS_OBJECT, {
|
587
|
+
get: () => globalState
|
588
|
+
});
|
589
|
+
Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
|
590
|
+
configurable: true,
|
591
|
+
get: () => ({
|
592
|
+
state: globalState.get(globalThis[GLOBAL_EXPECT]),
|
593
|
+
matchers,
|
594
|
+
customEqualityTesters
|
595
|
+
})
|
596
|
+
});
|
597
|
+
Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, {
|
598
|
+
get: () => assymetricMatchers
|
599
|
+
});
|
600
|
+
}
|
601
|
+
function getState(expect) {
|
602
|
+
return globalThis[MATCHERS_OBJECT].get(expect);
|
603
|
+
}
|
604
|
+
function setState(state, expect) {
|
605
|
+
const map = globalThis[MATCHERS_OBJECT];
|
606
|
+
const current = map.get(expect) || {};
|
607
|
+
const results = Object.defineProperties(current, {
|
608
|
+
...Object.getOwnPropertyDescriptors(current),
|
609
|
+
...Object.getOwnPropertyDescriptors(state)
|
610
|
+
});
|
611
|
+
map.set(expect, results);
|
612
|
+
}
|
613
|
+
|
613
614
|
class AsymmetricMatcher {
|
614
615
|
constructor(sample, inverse = false) {
|
615
616
|
this.sample = sample;
|
@@ -907,9 +908,20 @@ const JestAsymmetricMatchers = (chai, utils) => {
|
|
907
908
|
};
|
908
909
|
};
|
909
910
|
|
910
|
-
function
|
911
|
+
function createAssertionMessage(util, assertion, hasArgs) {
|
912
|
+
const not = util.flag(assertion, "negate") ? "not." : "";
|
913
|
+
const name = `${util.flag(assertion, "_name")}(${hasArgs ? "expected" : ""})`;
|
914
|
+
const promiseName = util.flag(assertion, "promise");
|
915
|
+
const promise = promiseName ? `.${promiseName}` : "";
|
916
|
+
return `expect(actual)${promise}.${not}${name}`;
|
917
|
+
}
|
918
|
+
function recordAsyncExpect(_test, promise, assertion, error) {
|
919
|
+
const test = _test;
|
911
920
|
if (test && promise instanceof Promise) {
|
912
921
|
promise = promise.finally(() => {
|
922
|
+
if (!test.promises) {
|
923
|
+
return;
|
924
|
+
}
|
913
925
|
const index = test.promises.indexOf(promise);
|
914
926
|
if (index !== -1) {
|
915
927
|
test.promises.splice(index, 1);
|
@@ -919,13 +931,43 @@ function recordAsyncExpect(test, promise) {
|
|
919
931
|
test.promises = [];
|
920
932
|
}
|
921
933
|
test.promises.push(promise);
|
934
|
+
let resolved = false;
|
935
|
+
test.onFinished ?? (test.onFinished = []);
|
936
|
+
test.onFinished.push(() => {
|
937
|
+
var _a;
|
938
|
+
if (!resolved) {
|
939
|
+
const processor = ((_a = globalThis.__vitest_worker__) == null ? void 0 : _a.onFilterStackTrace) || ((s) => s || "");
|
940
|
+
const stack = processor(error.stack);
|
941
|
+
console.warn([
|
942
|
+
`Promise returned by \`${assertion}\` was not awaited. `,
|
943
|
+
"Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in Vitest 3. ",
|
944
|
+
"Please remember to await the assertion.\n",
|
945
|
+
stack
|
946
|
+
].join(""));
|
947
|
+
}
|
948
|
+
});
|
949
|
+
return {
|
950
|
+
then(onFullfilled, onRejected) {
|
951
|
+
resolved = true;
|
952
|
+
return promise.then(onFullfilled, onRejected);
|
953
|
+
},
|
954
|
+
catch(onRejected) {
|
955
|
+
return promise.catch(onRejected);
|
956
|
+
},
|
957
|
+
finally(onFinally) {
|
958
|
+
return promise.finally(onFinally);
|
959
|
+
},
|
960
|
+
[Symbol.toStringTag]: "Promise"
|
961
|
+
};
|
922
962
|
}
|
923
963
|
return promise;
|
924
964
|
}
|
925
965
|
function wrapAssertion(utils, name, fn) {
|
926
966
|
return function(...args) {
|
927
967
|
var _a;
|
928
|
-
|
968
|
+
if (name !== "withTest") {
|
969
|
+
utils.flag(this, "_name", name);
|
970
|
+
}
|
929
971
|
if (!utils.flag(this, "soft")) {
|
930
972
|
return fn.apply(this, args);
|
931
973
|
}
|
@@ -1464,7 +1506,7 @@ const JestChaiExpect = (chai, utils) => {
|
|
1464
1506
|
["toThrow", "toThrowError"],
|
1465
1507
|
function(expected) {
|
1466
1508
|
if (typeof expected === "string" || typeof expected === "undefined" || expected instanceof RegExp) {
|
1467
|
-
return this.throws(expected);
|
1509
|
+
return this.throws(expected === "" ? /^$/ : expected);
|
1468
1510
|
}
|
1469
1511
|
const obj = this._obj;
|
1470
1512
|
const promise = utils.flag(this, "promise");
|
@@ -1723,6 +1765,7 @@ const JestChaiExpect = (chai, utils) => {
|
|
1723
1765
|
return result instanceof chai.Assertion ? proxy : result;
|
1724
1766
|
}
|
1725
1767
|
return (...args) => {
|
1768
|
+
utils.flag(this, "_name", key);
|
1726
1769
|
const promise = obj.then(
|
1727
1770
|
(value) => {
|
1728
1771
|
utils.flag(this, "object", value);
|
@@ -1743,7 +1786,12 @@ const JestChaiExpect = (chai, utils) => {
|
|
1743
1786
|
throw _error;
|
1744
1787
|
}
|
1745
1788
|
);
|
1746
|
-
return recordAsyncExpect(
|
1789
|
+
return recordAsyncExpect(
|
1790
|
+
test,
|
1791
|
+
promise,
|
1792
|
+
createAssertionMessage(utils, this, !!args.length),
|
1793
|
+
error
|
1794
|
+
);
|
1747
1795
|
};
|
1748
1796
|
}
|
1749
1797
|
});
|
@@ -1777,6 +1825,7 @@ const JestChaiExpect = (chai, utils) => {
|
|
1777
1825
|
return result instanceof chai.Assertion ? proxy : result;
|
1778
1826
|
}
|
1779
1827
|
return (...args) => {
|
1828
|
+
utils.flag(this, "_name", key);
|
1780
1829
|
const promise = wrapper.then(
|
1781
1830
|
(value) => {
|
1782
1831
|
const _error = new AssertionError(
|
@@ -1800,7 +1849,12 @@ const JestChaiExpect = (chai, utils) => {
|
|
1800
1849
|
return result.call(this, ...args);
|
1801
1850
|
}
|
1802
1851
|
);
|
1803
|
-
return recordAsyncExpect(
|
1852
|
+
return recordAsyncExpect(
|
1853
|
+
test,
|
1854
|
+
promise,
|
1855
|
+
createAssertionMessage(utils, this, !!args.length),
|
1856
|
+
error
|
1857
|
+
);
|
1804
1858
|
};
|
1805
1859
|
}
|
1806
1860
|
});
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vitest/expect",
|
3
3
|
"type": "module",
|
4
|
-
"version": "2.1.
|
4
|
+
"version": "2.1.5",
|
5
5
|
"description": "Jest's expect matchers as a Chai plugin",
|
6
6
|
"license": "MIT",
|
7
7
|
"funding": "https://opencollective.com/vitest",
|
@@ -30,15 +30,15 @@
|
|
30
30
|
"dist"
|
31
31
|
],
|
32
32
|
"dependencies": {
|
33
|
-
"chai": "^5.1.
|
33
|
+
"chai": "^5.1.2",
|
34
34
|
"tinyrainbow": "^1.2.0",
|
35
|
-
"@vitest/
|
36
|
-
"@vitest/
|
35
|
+
"@vitest/utils": "2.1.5",
|
36
|
+
"@vitest/spy": "2.1.5"
|
37
37
|
},
|
38
38
|
"devDependencies": {
|
39
39
|
"@types/chai": "4.3.6",
|
40
40
|
"rollup-plugin-copy": "^3.5.0",
|
41
|
-
"@vitest/runner": "2.1.
|
41
|
+
"@vitest/runner": "2.1.5"
|
42
42
|
},
|
43
43
|
"scripts": {
|
44
44
|
"build": "rimraf dist && rollup -c",
|