@vitest/expect 2.0.0-beta.10 → 2.0.0-beta.12

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 (3) hide show
  1. package/README.md +5 -1
  2. package/dist/index.js +680 -454
  3. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -8,7 +8,9 @@ import { use, util } from 'chai';
8
8
  const MATCHERS_OBJECT = Symbol.for("matchers-object");
9
9
  const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
10
10
  const GLOBAL_EXPECT = Symbol.for("expect-global");
11
- const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for("asymmetric-matchers-object");
11
+ const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for(
12
+ "asymmetric-matchers-object"
13
+ );
12
14
 
13
15
  if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) {
14
16
  const globalState = /* @__PURE__ */ new WeakMap();
@@ -83,14 +85,17 @@ function getMatcherUtils() {
83
85
  dimString += "()";
84
86
  } else {
85
87
  hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected);
86
- if (secondArgument)
88
+ if (secondArgument) {
87
89
  hint += DIM_COLOR(", ") + secondArgumentColor(secondArgument);
90
+ }
88
91
  dimString = ")";
89
92
  }
90
- if (comment !== "")
93
+ if (comment !== "") {
91
94
  dimString += ` // ${comment}`;
92
- if (dimString !== "")
95
+ }
96
+ if (dimString !== "") {
93
97
  hint += DIM_COLOR(dimString);
98
+ }
94
99
  return hint;
95
100
  }
96
101
  const SPACE_SYMBOL = "\xB7";
@@ -133,51 +138,71 @@ function isAsymmetric(obj) {
133
138
  return !!obj && typeof obj === "object" && "asymmetricMatch" in obj && isA("Function", obj.asymmetricMatch);
134
139
  }
135
140
  function hasAsymmetric(obj, seen = /* @__PURE__ */ new Set()) {
136
- if (seen.has(obj))
141
+ if (seen.has(obj)) {
137
142
  return false;
143
+ }
138
144
  seen.add(obj);
139
- if (isAsymmetric(obj))
145
+ if (isAsymmetric(obj)) {
140
146
  return true;
141
- if (Array.isArray(obj))
147
+ }
148
+ if (Array.isArray(obj)) {
142
149
  return obj.some((i) => hasAsymmetric(i, seen));
143
- if (obj instanceof Set)
150
+ }
151
+ if (obj instanceof Set) {
144
152
  return Array.from(obj).some((i) => hasAsymmetric(i, seen));
145
- if (isObject(obj))
153
+ }
154
+ if (isObject(obj)) {
146
155
  return Object.values(obj).some((v) => hasAsymmetric(v, seen));
156
+ }
147
157
  return false;
148
158
  }
149
159
  function asymmetricMatch(a, b) {
150
160
  const asymmetricA = isAsymmetric(a);
151
161
  const asymmetricB = isAsymmetric(b);
152
- if (asymmetricA && asymmetricB)
162
+ if (asymmetricA && asymmetricB) {
153
163
  return void 0;
154
- if (asymmetricA)
164
+ }
165
+ if (asymmetricA) {
155
166
  return a.asymmetricMatch(b);
156
- if (asymmetricB)
167
+ }
168
+ if (asymmetricB) {
157
169
  return b.asymmetricMatch(a);
170
+ }
158
171
  }
159
172
  function eq(a, b, aStack, bStack, customTesters, hasKey2) {
160
173
  let result = true;
161
174
  const asymmetricResult = asymmetricMatch(a, b);
162
- if (asymmetricResult !== void 0)
175
+ if (asymmetricResult !== void 0) {
163
176
  return asymmetricResult;
177
+ }
164
178
  const testerContext = { equals };
165
179
  for (let i = 0; i < customTesters.length; i++) {
166
- const customTesterResult = customTesters[i].call(testerContext, a, b, customTesters);
167
- if (customTesterResult !== void 0)
180
+ const customTesterResult = customTesters[i].call(
181
+ testerContext,
182
+ a,
183
+ b,
184
+ customTesters
185
+ );
186
+ if (customTesterResult !== void 0) {
168
187
  return customTesterResult;
188
+ }
169
189
  }
170
- if (a instanceof Error && b instanceof Error)
190
+ if (a instanceof Error && b instanceof Error) {
171
191
  return a.message === b.message;
172
- if (typeof URL === "function" && a instanceof URL && b instanceof URL)
192
+ }
193
+ if (typeof URL === "function" && a instanceof URL && b instanceof URL) {
173
194
  return a.href === b.href;
174
- if (Object.is(a, b))
195
+ }
196
+ if (Object.is(a, b)) {
175
197
  return true;
176
- if (a === null || b === null)
198
+ }
199
+ if (a === null || b === null) {
177
200
  return a === b;
201
+ }
178
202
  const className = Object.prototype.toString.call(a);
179
- if (className !== Object.prototype.toString.call(b))
203
+ if (className !== Object.prototype.toString.call(b)) {
180
204
  return false;
205
+ }
181
206
  switch (className) {
182
207
  case "[object Boolean]":
183
208
  case "[object String]":
@@ -197,31 +222,37 @@ function eq(a, b, aStack, bStack, customTesters, hasKey2) {
197
222
  case "[object RegExp]":
198
223
  return a.source === b.source && a.flags === b.flags;
199
224
  }
200
- if (typeof a !== "object" || typeof b !== "object")
225
+ if (typeof a !== "object" || typeof b !== "object") {
201
226
  return false;
202
- if (isDomNode(a) && isDomNode(b))
227
+ }
228
+ if (isDomNode(a) && isDomNode(b)) {
203
229
  return a.isEqualNode(b);
230
+ }
204
231
  let length = aStack.length;
205
232
  while (length--) {
206
- if (aStack[length] === a)
233
+ if (aStack[length] === a) {
207
234
  return bStack[length] === b;
208
- else if (bStack[length] === b)
235
+ } else if (bStack[length] === b) {
209
236
  return false;
237
+ }
210
238
  }
211
239
  aStack.push(a);
212
240
  bStack.push(b);
213
- if (className === "[object Array]" && a.length !== b.length)
241
+ if (className === "[object Array]" && a.length !== b.length) {
214
242
  return false;
243
+ }
215
244
  const aKeys = keys(a, hasKey2);
216
245
  let key;
217
246
  let size = aKeys.length;
218
- if (keys(b, hasKey2).length !== size)
247
+ if (keys(b, hasKey2).length !== size) {
219
248
  return false;
249
+ }
220
250
  while (size--) {
221
251
  key = aKeys[size];
222
252
  result = hasKey2(b, key) && eq(a[key], b[key], aStack, bStack, customTesters, hasKey2);
223
- if (!result)
253
+ if (!result) {
224
254
  return false;
255
+ }
225
256
  }
226
257
  aStack.pop();
227
258
  bStack.pop();
@@ -230,8 +261,9 @@ function eq(a, b, aStack, bStack, customTesters, hasKey2) {
230
261
  function keys(obj, hasKey2) {
231
262
  const keys2 = [];
232
263
  for (const key in obj) {
233
- if (hasKey2(obj, key))
264
+ if (hasKey2(obj, key)) {
234
265
  keys2.push(key);
266
+ }
235
267
  }
236
268
  return keys2.concat(
237
269
  Object.getOwnPropertySymbols(obj).filter(
@@ -252,23 +284,28 @@ function isDomNode(obj) {
252
284
  return obj !== null && typeof obj === "object" && "nodeType" in obj && typeof obj.nodeType === "number" && "nodeName" in obj && typeof obj.nodeName === "string" && "isEqualNode" in obj && typeof obj.isEqualNode === "function";
253
285
  }
254
286
  function fnNameFor(func) {
255
- if (func.name)
287
+ if (func.name) {
256
288
  return func.name;
289
+ }
257
290
  const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*(?:\*\s*)?([\w$]+)\s*\(/);
258
291
  return matches ? matches[1] : "<anonymous>";
259
292
  }
260
293
  function getPrototype(obj) {
261
- if (Object.getPrototypeOf)
294
+ if (Object.getPrototypeOf) {
262
295
  return Object.getPrototypeOf(obj);
263
- if (obj.constructor.prototype === obj)
296
+ }
297
+ if (obj.constructor.prototype === obj) {
264
298
  return null;
299
+ }
265
300
  return obj.constructor.prototype;
266
301
  }
267
302
  function hasProperty(obj, property) {
268
- if (!obj)
303
+ if (!obj) {
269
304
  return false;
270
- if (Object.prototype.hasOwnProperty.call(obj, property))
305
+ }
306
+ if (Object.prototype.hasOwnProperty.call(obj, property)) {
271
307
  return true;
308
+ }
272
309
  return hasProperty(getPrototype(obj), property);
273
310
  }
274
311
  const IS_KEYED_SENTINEL = "@@__IMMUTABLE_KEYED__@@";
@@ -309,12 +346,14 @@ function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) {
309
346
  if (typeof a !== "object" || typeof b !== "object" || Array.isArray(a) || Array.isArray(b) || !hasIterator(a) || !hasIterator(b)) {
310
347
  return void 0;
311
348
  }
312
- if (a.constructor !== b.constructor)
349
+ if (a.constructor !== b.constructor) {
313
350
  return false;
351
+ }
314
352
  let length = aStack.length;
315
353
  while (length--) {
316
- if (aStack[length] === a)
354
+ if (aStack[length] === a) {
317
355
  return bStack[length] === b;
356
+ }
318
357
  }
319
358
  aStack.push(a);
320
359
  bStack.push(b);
@@ -323,13 +362,7 @@ function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) {
323
362
  iterableEqualityWithStack
324
363
  ];
325
364
  function iterableEqualityWithStack(a2, b2) {
326
- return iterableEquality(
327
- a2,
328
- b2,
329
- [...customTesters],
330
- [...aStack],
331
- [...bStack]
332
- );
365
+ return iterableEquality(a2, b2, [...customTesters], [...aStack], [...bStack]);
333
366
  }
334
367
  if (a.size !== void 0) {
335
368
  if (a.size !== b.size) {
@@ -341,8 +374,9 @@ function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) {
341
374
  let has = false;
342
375
  for (const bValue of b) {
343
376
  const isEqual = equals(aValue, bValue, filteredCustomTesters);
344
- if (isEqual === true)
377
+ if (isEqual === true) {
345
378
  has = true;
379
+ }
346
380
  }
347
381
  if (has === false) {
348
382
  allFound = false;
@@ -359,12 +393,22 @@ function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) {
359
393
  if (!b.has(aEntry[0]) || !equals(aEntry[1], b.get(aEntry[0]), filteredCustomTesters)) {
360
394
  let has = false;
361
395
  for (const bEntry of b) {
362
- const matchedKey = equals(aEntry[0], bEntry[0], filteredCustomTesters);
396
+ const matchedKey = equals(
397
+ aEntry[0],
398
+ bEntry[0],
399
+ filteredCustomTesters
400
+ );
363
401
  let matchedValue = false;
364
- if (matchedKey === true)
365
- matchedValue = equals(aEntry[1], bEntry[1], filteredCustomTesters);
366
- if (matchedValue === true)
402
+ if (matchedKey === true) {
403
+ matchedValue = equals(
404
+ aEntry[1],
405
+ bEntry[1],
406
+ filteredCustomTesters
407
+ );
408
+ }
409
+ if (matchedValue === true) {
367
410
  has = true;
411
+ }
368
412
  }
369
413
  if (has === false) {
370
414
  allFound = false;
@@ -384,13 +428,15 @@ function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) {
384
428
  return false;
385
429
  }
386
430
  }
387
- if (!bIterator.next().done)
431
+ if (!bIterator.next().done) {
388
432
  return false;
433
+ }
389
434
  if (!isImmutableList(a) && !isImmutableOrderedKeyed(a) && !isImmutableOrderedSet(a) && !isImmutableRecord(a)) {
390
435
  const aEntries = Object.entries(a);
391
436
  const bEntries = Object.entries(b);
392
- if (!equals(aEntries, bEntries))
437
+ if (!equals(aEntries, bEntries)) {
393
438
  return false;
439
+ }
394
440
  }
395
441
  aStack.pop();
396
442
  bStack.pop();
@@ -398,22 +444,27 @@ function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) {
398
444
  }
399
445
  function hasPropertyInObject(object, key) {
400
446
  const shouldTerminate = !object || typeof object !== "object" || object === Object.prototype;
401
- if (shouldTerminate)
447
+ if (shouldTerminate) {
402
448
  return false;
449
+ }
403
450
  return Object.prototype.hasOwnProperty.call(object, key) || hasPropertyInObject(Object.getPrototypeOf(object), key);
404
451
  }
405
452
  function isObjectWithKeys(a) {
406
453
  return isObject(a) && !(a instanceof Error) && !Array.isArray(a) && !(a instanceof Date);
407
454
  }
408
455
  function subsetEquality(object, subset, customTesters = []) {
409
- const filteredCustomTesters = customTesters.filter((t) => t !== subsetEquality);
456
+ const filteredCustomTesters = customTesters.filter(
457
+ (t) => t !== subsetEquality
458
+ );
410
459
  const subsetEqualityWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object2, subset2) => {
411
- if (!isObjectWithKeys(subset2))
460
+ if (!isObjectWithKeys(subset2)) {
412
461
  return void 0;
462
+ }
413
463
  return Object.keys(subset2).every((key) => {
414
464
  if (subset2[key] != null && typeof subset2[key] === "object") {
415
- if (seenReferences.has(subset2[key]))
465
+ if (seenReferences.has(subset2[key])) {
416
466
  return equals(object2[key], subset2[key], filteredCustomTesters);
467
+ }
417
468
  seenReferences.set(subset2[key], true);
418
469
  }
419
470
  const result = object2 != null && hasPropertyInObject(object2, key) && equals(object2[key], subset2[key], [
@@ -427,16 +478,18 @@ function subsetEquality(object, subset, customTesters = []) {
427
478
  return subsetEqualityWithContext()(object, subset);
428
479
  }
429
480
  function typeEquality(a, b) {
430
- if (a == null || b == null || a.constructor === b.constructor)
481
+ if (a == null || b == null || a.constructor === b.constructor) {
431
482
  return void 0;
483
+ }
432
484
  return false;
433
485
  }
434
486
  function arrayBufferEquality(a, b) {
435
487
  let dataViewA = a;
436
488
  let dataViewB = b;
437
489
  if (!(a instanceof DataView && b instanceof DataView)) {
438
- if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer))
490
+ if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer)) {
439
491
  return void 0;
492
+ }
440
493
  try {
441
494
  dataViewA = new DataView(a);
442
495
  dataViewB = new DataView(b);
@@ -444,25 +497,30 @@ function arrayBufferEquality(a, b) {
444
497
  return void 0;
445
498
  }
446
499
  }
447
- if (dataViewA.byteLength !== dataViewB.byteLength)
500
+ if (dataViewA.byteLength !== dataViewB.byteLength) {
448
501
  return false;
502
+ }
449
503
  for (let i = 0; i < dataViewA.byteLength; i++) {
450
- if (dataViewA.getUint8(i) !== dataViewB.getUint8(i))
504
+ if (dataViewA.getUint8(i) !== dataViewB.getUint8(i)) {
451
505
  return false;
506
+ }
452
507
  }
453
508
  return true;
454
509
  }
455
510
  function sparseArrayEquality(a, b, customTesters = []) {
456
- if (!Array.isArray(a) || !Array.isArray(b))
511
+ if (!Array.isArray(a) || !Array.isArray(b)) {
457
512
  return void 0;
513
+ }
458
514
  const aKeys = Object.keys(a);
459
515
  const bKeys = Object.keys(b);
460
- const filteredCustomTesters = customTesters.filter((t) => t !== sparseArrayEquality);
516
+ const filteredCustomTesters = customTesters.filter(
517
+ (t) => t !== sparseArrayEquality
518
+ );
461
519
  return equals(a, b, filteredCustomTesters, true) && equals(aKeys, bKeys);
462
520
  }
463
521
  function generateToBeMessage(deepEqualityName, expected = "#{this}", actual = "#{exp}") {
464
522
  const toBeMessage = `expected ${expected} to be ${actual} // Object.is equality`;
465
- if (["toStrictEqual", "toEqual"].includes(deepEqualityName))
523
+ if (["toStrictEqual", "toEqual"].includes(deepEqualityName)) {
466
524
  return `${toBeMessage}
467
525
 
468
526
  If it should pass with deep equality, replace "toBe" with "${deepEqualityName}"
@@ -470,6 +528,7 @@ If it should pass with deep equality, replace "toBe" with "${deepEqualityName}"
470
528
  Expected: ${expected}
471
529
  Received: serializes to the same string
472
530
  `;
531
+ }
473
532
  return toBeMessage;
474
533
  }
475
534
  function pluralize(word, count) {
@@ -509,18 +568,26 @@ function getObjectSubset(object, subset, customTesters = []) {
509
568
  seenReferences.set(object2, trimmed);
510
569
  for (const key of getObjectKeys(object2)) {
511
570
  if (hasPropertyInObject(subset2, key)) {
512
- trimmed[key] = seenReferences.has(object2[key]) ? seenReferences.get(object2[key]) : getObjectSubsetWithContext(seenReferences)(object2[key], subset2[key]);
571
+ trimmed[key] = seenReferences.has(object2[key]) ? seenReferences.get(object2[key]) : getObjectSubsetWithContext(seenReferences)(
572
+ object2[key],
573
+ subset2[key]
574
+ );
513
575
  } else {
514
576
  if (!seenReferences.has(object2[key])) {
515
577
  stripped += 1;
516
- if (isObject(object2[key]))
578
+ if (isObject(object2[key])) {
517
579
  stripped += getObjectKeys(object2[key]).length;
518
- getObjectSubsetWithContext(seenReferences)(object2[key], subset2[key]);
580
+ }
581
+ getObjectSubsetWithContext(seenReferences)(
582
+ object2[key],
583
+ subset2[key]
584
+ );
519
585
  }
520
586
  }
521
587
  }
522
- if (getObjectKeys(trimmed).length > 0)
588
+ if (getObjectKeys(trimmed).length > 0) {
523
589
  return trimmed;
590
+ }
524
591
  }
525
592
  return object2;
526
593
  };
@@ -553,15 +620,17 @@ class AsymmetricMatcher {
553
620
  // https://github.com/chaijs/loupe/blob/9b8a6deabcd50adc056a64fb705896194710c5c6/src/index.ts#L29
554
621
  [Symbol.for("chai/inspect")](options) {
555
622
  const result = stringify(this, options.depth, { min: true });
556
- if (result.length <= options.truncate)
623
+ if (result.length <= options.truncate) {
557
624
  return result;
625
+ }
558
626
  return `${this.toString()}{\u2026}`;
559
627
  }
560
628
  }
561
629
  class StringContaining extends AsymmetricMatcher {
562
630
  constructor(sample, inverse = false) {
563
- if (!isA("String", sample))
631
+ if (!isA("String", sample)) {
564
632
  throw new Error("Expected is not a string");
633
+ }
565
634
  super(sample, inverse);
566
635
  }
567
636
  asymmetricMatch(other) {
@@ -591,17 +660,21 @@ class ObjectContaining extends AsymmetricMatcher {
591
660
  super(sample, inverse);
592
661
  }
593
662
  getPrototype(obj) {
594
- if (Object.getPrototypeOf)
663
+ if (Object.getPrototypeOf) {
595
664
  return Object.getPrototypeOf(obj);
596
- if (obj.constructor.prototype === obj)
665
+ }
666
+ if (obj.constructor.prototype === obj) {
597
667
  return null;
668
+ }
598
669
  return obj.constructor.prototype;
599
670
  }
600
671
  hasProperty(obj, property) {
601
- if (!obj)
672
+ if (!obj) {
602
673
  return false;
603
- if (Object.prototype.hasOwnProperty.call(obj, property))
674
+ }
675
+ if (Object.prototype.hasOwnProperty.call(obj, property)) {
604
676
  return true;
677
+ }
605
678
  return this.hasProperty(this.getPrototype(obj), property);
606
679
  }
607
680
  asymmetricMatch(other) {
@@ -613,7 +686,11 @@ class ObjectContaining extends AsymmetricMatcher {
613
686
  let result = true;
614
687
  const matcherContext = this.getMatcherContext();
615
688
  for (const property in this.sample) {
616
- if (!this.hasProperty(other, property) || !equals(this.sample[property], other[property], matcherContext.customTesters)) {
689
+ if (!this.hasProperty(other, property) || !equals(
690
+ this.sample[property],
691
+ other[property],
692
+ matcherContext.customTesters
693
+ )) {
617
694
  result = false;
618
695
  break;
619
696
  }
@@ -639,7 +716,9 @@ class ArrayContaining extends AsymmetricMatcher {
639
716
  }
640
717
  const matcherContext = this.getMatcherContext();
641
718
  const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every(
642
- (item) => other.some((another) => equals(item, another, matcherContext.customTesters))
719
+ (item) => other.some(
720
+ (another) => equals(item, another, matcherContext.customTesters)
721
+ )
643
722
  );
644
723
  return this.inverse ? !result : result;
645
724
  }
@@ -660,43 +739,56 @@ class Any extends AsymmetricMatcher {
660
739
  super(sample);
661
740
  }
662
741
  fnNameFor(func) {
663
- if (func.name)
742
+ if (func.name) {
664
743
  return func.name;
744
+ }
665
745
  const functionToString = Function.prototype.toString;
666
746
  const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*(?:\*\s*)?([\w$]+)\s*\(/);
667
747
  return matches ? matches[1] : "<anonymous>";
668
748
  }
669
749
  asymmetricMatch(other) {
670
- if (this.sample === String)
750
+ if (this.sample === String) {
671
751
  return typeof other == "string" || other instanceof String;
672
- if (this.sample === Number)
752
+ }
753
+ if (this.sample === Number) {
673
754
  return typeof other == "number" || other instanceof Number;
674
- if (this.sample === Function)
755
+ }
756
+ if (this.sample === Function) {
675
757
  return typeof other == "function" || other instanceof Function;
676
- if (this.sample === Boolean)
758
+ }
759
+ if (this.sample === Boolean) {
677
760
  return typeof other == "boolean" || other instanceof Boolean;
678
- if (this.sample === BigInt)
761
+ }
762
+ if (this.sample === BigInt) {
679
763
  return typeof other == "bigint" || other instanceof BigInt;
680
- if (this.sample === Symbol)
764
+ }
765
+ if (this.sample === Symbol) {
681
766
  return typeof other == "symbol" || other instanceof Symbol;
682
- if (this.sample === Object)
767
+ }
768
+ if (this.sample === Object) {
683
769
  return typeof other == "object";
770
+ }
684
771
  return other instanceof this.sample;
685
772
  }
686
773
  toString() {
687
774
  return "Any";
688
775
  }
689
776
  getExpectedType() {
690
- if (this.sample === String)
777
+ if (this.sample === String) {
691
778
  return "string";
692
- if (this.sample === Number)
779
+ }
780
+ if (this.sample === Number) {
693
781
  return "number";
694
- if (this.sample === Function)
782
+ }
783
+ if (this.sample === Function) {
695
784
  return "function";
696
- if (this.sample === Object)
785
+ }
786
+ if (this.sample === Object) {
697
787
  return "object";
698
- if (this.sample === Boolean)
788
+ }
789
+ if (this.sample === Boolean) {
699
790
  return "boolean";
791
+ }
700
792
  return this.fnNameFor(this.sample);
701
793
  }
702
794
  toAsymmetricMatcher() {
@@ -705,8 +797,9 @@ class Any extends AsymmetricMatcher {
705
797
  }
706
798
  class StringMatching extends AsymmetricMatcher {
707
799
  constructor(sample, inverse = false) {
708
- if (!isA("String", sample) && !isA("RegExp", sample))
800
+ if (!isA("String", sample) && !isA("RegExp", sample)) {
709
801
  throw new Error("Expected is not a String or a RegExp");
802
+ }
710
803
  super(new RegExp(sample), inverse);
711
804
  }
712
805
  asymmetricMatch(other) {
@@ -723,17 +816,20 @@ class StringMatching extends AsymmetricMatcher {
723
816
  class CloseTo extends AsymmetricMatcher {
724
817
  precision;
725
818
  constructor(sample, precision = 2, inverse = false) {
726
- if (!isA("Number", sample))
819
+ if (!isA("Number", sample)) {
727
820
  throw new Error("Expected is not a Number");
728
- if (!isA("Number", precision))
821
+ }
822
+ if (!isA("Number", precision)) {
729
823
  throw new Error("Precision is not a Number");
824
+ }
730
825
  super(sample);
731
826
  this.inverse = inverse;
732
827
  this.precision = precision;
733
828
  }
734
829
  asymmetricMatch(other) {
735
- if (!isA("Number", other))
830
+ if (!isA("Number", other)) {
736
831
  return false;
832
+ }
737
833
  let result = false;
738
834
  if (other === Number.POSITIVE_INFINITY && this.sample === Number.POSITIVE_INFINITY) {
739
835
  result = true;
@@ -759,16 +855,8 @@ class CloseTo extends AsymmetricMatcher {
759
855
  }
760
856
  }
761
857
  const JestAsymmetricMatchers = (chai, utils) => {
762
- utils.addMethod(
763
- chai.expect,
764
- "anything",
765
- () => new Anything()
766
- );
767
- utils.addMethod(
768
- chai.expect,
769
- "any",
770
- (expected) => new Any(expected)
771
- );
858
+ utils.addMethod(chai.expect, "anything", () => new Anything());
859
+ utils.addMethod(chai.expect, "any", (expected) => new Any(expected));
772
860
  utils.addMethod(
773
861
  chai.expect,
774
862
  "stringContaining",
@@ -807,11 +895,13 @@ function recordAsyncExpect(test, promise) {
807
895
  if (test && promise instanceof Promise) {
808
896
  promise = promise.finally(() => {
809
897
  const index = test.promises.indexOf(promise);
810
- if (index !== -1)
898
+ if (index !== -1) {
811
899
  test.promises.splice(index, 1);
900
+ }
812
901
  });
813
- if (!test.promises)
902
+ if (!test.promises) {
814
903
  test.promises = [];
904
+ }
815
905
  test.promises.push(promise);
816
906
  }
817
907
  return promise;
@@ -819,11 +909,13 @@ function recordAsyncExpect(test, promise) {
819
909
  function wrapSoft(utils, fn) {
820
910
  return function(...args) {
821
911
  var _a;
822
- if (!utils.flag(this, "soft"))
912
+ if (!utils.flag(this, "soft")) {
823
913
  return fn.apply(this, args);
914
+ }
824
915
  const test = utils.flag(this, "vitest-test");
825
- if (!test)
916
+ if (!test) {
826
917
  throw new Error("expect.soft() can only be used inside a test");
918
+ }
827
919
  try {
828
920
  return fn.apply(this, args);
829
921
  } catch (err) {
@@ -843,12 +935,17 @@ const JestChaiExpect = (chai, utils) => {
843
935
  const addMethod = (n) => {
844
936
  const softWrapper = wrapSoft(utils, fn);
845
937
  utils.addMethod(chai.Assertion.prototype, n, softWrapper);
846
- utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, n, softWrapper);
938
+ utils.addMethod(
939
+ globalThis[JEST_MATCHERS_OBJECT].matchers,
940
+ n,
941
+ softWrapper
942
+ );
847
943
  };
848
- if (Array.isArray(name))
944
+ if (Array.isArray(name)) {
849
945
  name.forEach((n) => addMethod(n));
850
- else
946
+ } else {
851
947
  addMethod(name);
948
+ }
852
949
  }
853
950
  ["throw", "throws", "Throw"].forEach((m) => {
854
951
  utils.overwriteMethod(chai.Assertion.prototype, m, (_super) => {
@@ -881,11 +978,10 @@ const JestChaiExpect = (chai, utils) => {
881
978
  });
882
979
  def("toEqual", function(expected) {
883
980
  const actual = utils.flag(this, "object");
884
- const equal = equals(
885
- actual,
886
- expected,
887
- [...customTesters, iterableEquality]
888
- );
981
+ const equal = equals(actual, expected, [
982
+ ...customTesters,
983
+ iterableEquality
984
+ ]);
889
985
  return this.assert(
890
986
  equal,
891
987
  "expected #{this} to deeply equal #{exp}",
@@ -936,13 +1032,13 @@ const JestChaiExpect = (chai, utils) => {
936
1032
  if (toStrictEqualPass) {
937
1033
  deepEqualityName = "toStrictEqual";
938
1034
  } else {
939
- const toEqualPass = equals(
940
- actual,
941
- expected,
942
- [...customTesters, iterableEquality]
943
- );
944
- if (toEqualPass)
1035
+ const toEqualPass = equals(actual, expected, [
1036
+ ...customTesters,
1037
+ iterableEquality
1038
+ ]);
1039
+ if (toEqualPass) {
945
1040
  deepEqualityName = "toEqual";
1041
+ }
946
1042
  }
947
1043
  }
948
1044
  return this.assert(
@@ -955,30 +1051,41 @@ const JestChaiExpect = (chai, utils) => {
955
1051
  });
956
1052
  def("toMatchObject", function(expected) {
957
1053
  const actual = this._obj;
958
- const pass = equals(actual, expected, [...customTesters, iterableEquality, subsetEquality]);
1054
+ const pass = equals(actual, expected, [
1055
+ ...customTesters,
1056
+ iterableEquality,
1057
+ subsetEquality
1058
+ ]);
959
1059
  const isNot = utils.flag(this, "negate");
960
- const { subset: actualSubset, stripped } = getObjectSubset(actual, expected);
1060
+ const { subset: actualSubset, stripped } = getObjectSubset(
1061
+ actual,
1062
+ expected
1063
+ );
961
1064
  if (pass && isNot || !pass && !isNot) {
962
- const msg = utils.getMessage(
963
- this,
964
- [
965
- pass,
966
- "expected #{this} to match object #{exp}",
967
- "expected #{this} to not match object #{exp}",
968
- expected,
969
- actualSubset,
970
- false
971
- ]
972
- );
1065
+ const msg = utils.getMessage(this, [
1066
+ pass,
1067
+ "expected #{this} to match object #{exp}",
1068
+ "expected #{this} to not match object #{exp}",
1069
+ expected,
1070
+ actualSubset,
1071
+ false
1072
+ ]);
973
1073
  const message = stripped === 0 ? msg : `${msg}
974
1074
  (${stripped} matching ${stripped === 1 ? "property" : "properties"} omitted from actual)`;
975
- throw new AssertionError(message, { showDiff: true, expected, actual: actualSubset });
1075
+ throw new AssertionError(message, {
1076
+ showDiff: true,
1077
+ expected,
1078
+ actual: actualSubset
1079
+ });
976
1080
  }
977
1081
  });
978
1082
  def("toMatch", function(expected) {
979
1083
  const actual = this._obj;
980
- if (typeof actual !== "string")
981
- throw new TypeError(`.toMatch() expects to receive a string, but got ${typeof actual}`);
1084
+ if (typeof actual !== "string") {
1085
+ throw new TypeError(
1086
+ `.toMatch() expects to receive a string, but got ${typeof actual}`
1087
+ );
1088
+ }
982
1089
  return this.assert(
983
1090
  typeof expected === "string" ? actual.includes(expected) : actual.match(expected),
984
1091
  `expected #{this} to match #{exp}`,
@@ -990,8 +1097,11 @@ const JestChaiExpect = (chai, utils) => {
990
1097
  def("toContain", function(item) {
991
1098
  const actual = this._obj;
992
1099
  if (typeof Node !== "undefined" && actual instanceof Node) {
993
- if (!(item instanceof Node))
994
- throw new TypeError(`toContain() expected a DOM node as the argument, but got ${typeof item}`);
1100
+ if (!(item instanceof Node)) {
1101
+ throw new TypeError(
1102
+ `toContain() expected a DOM node as the argument, but got ${typeof item}`
1103
+ );
1104
+ }
995
1105
  return this.assert(
996
1106
  actual.contains(item),
997
1107
  "expected #{this} to contain element #{exp}",
@@ -1021,8 +1131,9 @@ const JestChaiExpect = (chai, utils) => {
1021
1131
  actual
1022
1132
  );
1023
1133
  }
1024
- if (actual != null && typeof actual !== "string")
1134
+ if (actual != null && typeof actual !== "string") {
1025
1135
  utils.flag(this, "object", Array.from(actual));
1136
+ }
1026
1137
  return this.contain(item);
1027
1138
  });
1028
1139
  def("toContainEqual", function(expected) {
@@ -1121,49 +1232,61 @@ const JestChaiExpect = (chai, utils) => {
1121
1232
  def("toBeDefined", function() {
1122
1233
  const negate = utils.flag(this, "negate");
1123
1234
  utils.flag(this, "negate", false);
1124
- if (negate)
1235
+ if (negate) {
1125
1236
  return this.be.undefined;
1237
+ }
1126
1238
  return this.not.be.undefined;
1127
1239
  });
1128
- def("toBeTypeOf", function(expected) {
1129
- const actual = typeof this._obj;
1130
- const equal = expected === actual;
1131
- return this.assert(
1132
- equal,
1133
- "expected #{this} to be type of #{exp}",
1134
- "expected #{this} not to be type of #{exp}",
1135
- expected,
1136
- actual
1137
- );
1138
- });
1240
+ def(
1241
+ "toBeTypeOf",
1242
+ function(expected) {
1243
+ const actual = typeof this._obj;
1244
+ const equal = expected === actual;
1245
+ return this.assert(
1246
+ equal,
1247
+ "expected #{this} to be type of #{exp}",
1248
+ "expected #{this} not to be type of #{exp}",
1249
+ expected,
1250
+ actual
1251
+ );
1252
+ }
1253
+ );
1139
1254
  def("toBeInstanceOf", function(obj) {
1140
1255
  return this.instanceOf(obj);
1141
1256
  });
1142
1257
  def("toHaveLength", function(length) {
1143
1258
  return this.have.length(length);
1144
1259
  });
1145
- def("toHaveProperty", function(...args) {
1146
- if (Array.isArray(args[0]))
1147
- args[0] = args[0].map((key) => String(key).replace(/([.[\]])/g, "\\$1")).join(".");
1148
- const actual = this._obj;
1149
- const [propertyName, expected] = args;
1150
- const getValue = () => {
1151
- const hasOwn = Object.prototype.hasOwnProperty.call(actual, propertyName);
1152
- if (hasOwn)
1153
- return { value: actual[propertyName], exists: true };
1154
- return utils.getPathInfo(actual, propertyName);
1155
- };
1156
- const { value, exists } = getValue();
1157
- const pass = exists && (args.length === 1 || equals(expected, value, customTesters));
1158
- const valueString = args.length === 1 ? "" : ` with value ${utils.objDisplay(expected)}`;
1159
- return this.assert(
1160
- pass,
1161
- `expected #{this} to have property "${propertyName}"${valueString}`,
1162
- `expected #{this} to not have property "${propertyName}"${valueString}`,
1163
- expected,
1164
- exists ? value : void 0
1165
- );
1166
- });
1260
+ def(
1261
+ "toHaveProperty",
1262
+ function(...args) {
1263
+ if (Array.isArray(args[0])) {
1264
+ args[0] = args[0].map((key) => String(key).replace(/([.[\]])/g, "\\$1")).join(".");
1265
+ }
1266
+ const actual = this._obj;
1267
+ const [propertyName, expected] = args;
1268
+ const getValue = () => {
1269
+ const hasOwn = Object.prototype.hasOwnProperty.call(
1270
+ actual,
1271
+ propertyName
1272
+ );
1273
+ if (hasOwn) {
1274
+ return { value: actual[propertyName], exists: true };
1275
+ }
1276
+ return utils.getPathInfo(actual, propertyName);
1277
+ };
1278
+ const { value, exists } = getValue();
1279
+ const pass = exists && (args.length === 1 || equals(expected, value, customTesters));
1280
+ const valueString = args.length === 1 ? "" : ` with value ${utils.objDisplay(expected)}`;
1281
+ return this.assert(
1282
+ pass,
1283
+ `expected #{this} to have property "${propertyName}"${valueString}`,
1284
+ `expected #{this} to not have property "${propertyName}"${valueString}`,
1285
+ expected,
1286
+ exists ? value : void 0
1287
+ );
1288
+ }
1289
+ );
1167
1290
  def("toBeCloseTo", function(received, precision = 2) {
1168
1291
  const expected = this._obj;
1169
1292
  let pass = false;
@@ -1188,8 +1311,11 @@ const JestChaiExpect = (chai, utils) => {
1188
1311
  );
1189
1312
  });
1190
1313
  const assertIsMock = (assertion) => {
1191
- if (!isMockFunction(assertion._obj))
1192
- throw new TypeError(`${utils.inspect(assertion._obj)} is not a spy or a call to a spy!`);
1314
+ if (!isMockFunction(assertion._obj)) {
1315
+ throw new TypeError(
1316
+ `${utils.inspect(assertion._obj)} is not a spy or a call to a spy!`
1317
+ );
1318
+ }
1193
1319
  };
1194
1320
  const getSpy = (assertion) => {
1195
1321
  assertIsMock(assertion);
@@ -1198,58 +1324,79 @@ const JestChaiExpect = (chai, utils) => {
1198
1324
  const ordinalOf = (i) => {
1199
1325
  const j = i % 10;
1200
1326
  const k = i % 100;
1201
- if (j === 1 && k !== 11)
1327
+ if (j === 1 && k !== 11) {
1202
1328
  return `${i}st`;
1203
- if (j === 2 && k !== 12)
1329
+ }
1330
+ if (j === 2 && k !== 12) {
1204
1331
  return `${i}nd`;
1205
- if (j === 3 && k !== 13)
1332
+ }
1333
+ if (j === 3 && k !== 13) {
1206
1334
  return `${i}rd`;
1335
+ }
1207
1336
  return `${i}th`;
1208
1337
  };
1209
1338
  const formatCalls = (spy, msg, showActualCall) => {
1210
1339
  if (spy.mock.calls) {
1211
- msg += c().gray(`
1340
+ msg += c().gray(
1341
+ `
1212
1342
 
1213
1343
  Received:
1214
1344
 
1215
1345
  ${spy.mock.calls.map((callArg, i) => {
1216
- let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call:
1346
+ let methodCall = c().bold(
1347
+ ` ${ordinalOf(i + 1)} ${spy.getMockName()} call:
1217
1348
 
1218
- `);
1219
- if (showActualCall)
1220
- methodCall += diff(showActualCall, callArg, { omitAnnotationLines: true });
1221
- else
1222
- methodCall += stringify(callArg).split("\n").map((line) => ` ${line}`).join("\n");
1223
- methodCall += "\n";
1224
- return methodCall;
1225
- }).join("\n")}`);
1349
+ `
1350
+ );
1351
+ if (showActualCall) {
1352
+ methodCall += diff(showActualCall, callArg, {
1353
+ omitAnnotationLines: true
1354
+ });
1355
+ } else {
1356
+ methodCall += stringify(callArg).split("\n").map((line) => ` ${line}`).join("\n");
1357
+ }
1358
+ methodCall += "\n";
1359
+ return methodCall;
1360
+ }).join("\n")}`
1361
+ );
1226
1362
  }
1227
- msg += c().gray(`
1363
+ msg += c().gray(
1364
+ `
1228
1365
 
1229
1366
  Number of calls: ${c().bold(spy.mock.calls.length)}
1230
- `);
1367
+ `
1368
+ );
1231
1369
  return msg;
1232
1370
  };
1233
1371
  const formatReturns = (spy, results, msg, showActualReturn) => {
1234
- msg += c().gray(`
1372
+ msg += c().gray(
1373
+ `
1235
1374
 
1236
1375
  Received:
1237
1376
 
1238
1377
  ${results.map((callReturn, i) => {
1239
- let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:
1378
+ let methodCall = c().bold(
1379
+ ` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:
1240
1380
 
1241
- `);
1242
- if (showActualReturn)
1243
- methodCall += diff(showActualReturn, callReturn.value, { omitAnnotationLines: true });
1244
- else
1245
- methodCall += stringify(callReturn).split("\n").map((line) => ` ${line}`).join("\n");
1246
- methodCall += "\n";
1247
- return methodCall;
1248
- }).join("\n")}`);
1249
- msg += c().gray(`
1381
+ `
1382
+ );
1383
+ if (showActualReturn) {
1384
+ methodCall += diff(showActualReturn, callReturn.value, {
1385
+ omitAnnotationLines: true
1386
+ });
1387
+ } else {
1388
+ methodCall += stringify(callReturn).split("\n").map((line) => ` ${line}`).join("\n");
1389
+ }
1390
+ methodCall += "\n";
1391
+ return methodCall;
1392
+ }).join("\n")}`
1393
+ );
1394
+ msg += c().gray(
1395
+ `
1250
1396
 
1251
1397
  Number of calls: ${c().bold(spy.mock.calls.length)}
1252
- `);
1398
+ `
1399
+ );
1253
1400
  return msg;
1254
1401
  };
1255
1402
  def(["toHaveBeenCalledTimes", "toBeCalledTimes"], function(number) {
@@ -1284,131 +1431,146 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
1284
1431
  const callCount = spy.mock.calls.length;
1285
1432
  const called = callCount > 0;
1286
1433
  const isNot = utils.flag(this, "negate");
1287
- let msg = utils.getMessage(
1288
- this,
1289
- [
1290
- called,
1291
- `expected "${spyName}" to be called at least once`,
1292
- `expected "${spyName}" to not be called at all, but actually been called ${callCount} times`,
1293
- true,
1294
- called
1295
- ]
1296
- );
1297
- if (called && isNot)
1434
+ let msg = utils.getMessage(this, [
1435
+ called,
1436
+ `expected "${spyName}" to be called at least once`,
1437
+ `expected "${spyName}" to not be called at all, but actually been called ${callCount} times`,
1438
+ true,
1439
+ called
1440
+ ]);
1441
+ if (called && isNot) {
1298
1442
  msg = formatCalls(spy, msg);
1299
- if (called && isNot || !called && !isNot)
1443
+ }
1444
+ if (called && isNot || !called && !isNot) {
1300
1445
  throw new AssertionError(msg);
1446
+ }
1301
1447
  });
1302
1448
  def(["toHaveBeenCalledWith", "toBeCalledWith"], function(...args) {
1303
1449
  const spy = getSpy(this);
1304
1450
  const spyName = spy.getMockName();
1305
- const pass = spy.mock.calls.some((callArg) => equals(callArg, args, [...customTesters, iterableEquality]));
1306
- const isNot = utils.flag(this, "negate");
1307
- const msg = utils.getMessage(
1308
- this,
1309
- [
1310
- pass,
1311
- `expected "${spyName}" to be called with arguments: #{exp}`,
1312
- `expected "${spyName}" to not be called with arguments: #{exp}`,
1313
- args
1314
- ]
1315
- );
1316
- if (pass && isNot || !pass && !isNot)
1317
- throw new AssertionError(formatCalls(spy, msg, args));
1318
- });
1319
- def(["toHaveBeenNthCalledWith", "nthCalledWith"], function(times, ...args) {
1320
- const spy = getSpy(this);
1321
- const spyName = spy.getMockName();
1322
- const nthCall = spy.mock.calls[times - 1];
1323
- const callCount = spy.mock.calls.length;
1324
- const isCalled = times <= callCount;
1325
- this.assert(
1326
- equals(nthCall, args, [...customTesters, iterableEquality]),
1327
- `expected ${ordinalOf(times)} "${spyName}" call to have been called with #{exp}${isCalled ? `` : `, but called only ${callCount} times`}`,
1328
- `expected ${ordinalOf(times)} "${spyName}" call to not have been called with #{exp}`,
1329
- args,
1330
- nthCall,
1331
- isCalled
1451
+ const pass = spy.mock.calls.some(
1452
+ (callArg) => equals(callArg, args, [...customTesters, iterableEquality])
1332
1453
  );
1333
- });
1334
- def(["toHaveBeenLastCalledWith", "lastCalledWith"], function(...args) {
1335
- const spy = getSpy(this);
1336
- const spyName = spy.getMockName();
1337
- const lastCall = spy.mock.calls[spy.mock.calls.length - 1];
1338
- this.assert(
1339
- equals(lastCall, args, [...customTesters, iterableEquality]),
1340
- `expected last "${spyName}" call to have been called with #{exp}`,
1341
- `expected last "${spyName}" call to not have been called with #{exp}`,
1342
- args,
1343
- lastCall
1344
- );
1345
- });
1346
- def(["toThrow", "toThrowError"], function(expected) {
1347
- if (typeof expected === "string" || typeof expected === "undefined" || expected instanceof RegExp)
1348
- return this.throws(expected);
1349
- const obj = this._obj;
1350
- const promise = utils.flag(this, "promise");
1351
1454
  const isNot = utils.flag(this, "negate");
1352
- let thrown = null;
1353
- if (promise === "rejects") {
1354
- thrown = obj;
1355
- } else if (promise === "resolves" && typeof obj !== "function") {
1356
- if (!isNot) {
1357
- const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't";
1358
- const error = {
1359
- showDiff: false
1360
- };
1361
- throw new AssertionError(message, error, utils.flag(this, "ssfi"));
1362
- } else {
1363
- return;
1364
- }
1365
- } else {
1366
- let isThrow = false;
1367
- try {
1368
- obj();
1369
- } catch (err) {
1370
- isThrow = true;
1371
- thrown = err;
1372
- }
1373
- if (!isThrow && !isNot) {
1374
- const message = utils.flag(this, "message") || "expected function to throw an error, but it didn't";
1375
- const error = {
1376
- showDiff: false
1377
- };
1378
- throw new AssertionError(message, error, utils.flag(this, "ssfi"));
1379
- }
1455
+ const msg = utils.getMessage(this, [
1456
+ pass,
1457
+ `expected "${spyName}" to be called with arguments: #{exp}`,
1458
+ `expected "${spyName}" to not be called with arguments: #{exp}`,
1459
+ args
1460
+ ]);
1461
+ if (pass && isNot || !pass && !isNot) {
1462
+ throw new AssertionError(formatCalls(spy, msg, args));
1380
1463
  }
1381
- if (typeof expected === "function") {
1382
- const name = expected.name || expected.prototype.constructor.name;
1383
- return this.assert(
1384
- thrown && thrown instanceof expected,
1385
- `expected error to be instance of ${name}`,
1386
- `expected error not to be instance of ${name}`,
1387
- expected,
1388
- thrown
1464
+ });
1465
+ def(
1466
+ ["toHaveBeenNthCalledWith", "nthCalledWith"],
1467
+ function(times, ...args) {
1468
+ const spy = getSpy(this);
1469
+ const spyName = spy.getMockName();
1470
+ const nthCall = spy.mock.calls[times - 1];
1471
+ const callCount = spy.mock.calls.length;
1472
+ const isCalled = times <= callCount;
1473
+ this.assert(
1474
+ equals(nthCall, args, [...customTesters, iterableEquality]),
1475
+ `expected ${ordinalOf(
1476
+ times
1477
+ )} "${spyName}" call to have been called with #{exp}${isCalled ? `` : `, but called only ${callCount} times`}`,
1478
+ `expected ${ordinalOf(
1479
+ times
1480
+ )} "${spyName}" call to not have been called with #{exp}`,
1481
+ args,
1482
+ nthCall,
1483
+ isCalled
1389
1484
  );
1390
1485
  }
1391
- if (expected instanceof Error) {
1392
- return this.assert(
1393
- thrown && expected.message === thrown.message,
1394
- `expected error to have message: ${expected.message}`,
1395
- `expected error not to have message: ${expected.message}`,
1396
- expected.message,
1397
- thrown && thrown.message
1486
+ );
1487
+ def(
1488
+ ["toHaveBeenLastCalledWith", "lastCalledWith"],
1489
+ function(...args) {
1490
+ const spy = getSpy(this);
1491
+ const spyName = spy.getMockName();
1492
+ const lastCall = spy.mock.calls[spy.mock.calls.length - 1];
1493
+ this.assert(
1494
+ equals(lastCall, args, [...customTesters, iterableEquality]),
1495
+ `expected last "${spyName}" call to have been called with #{exp}`,
1496
+ `expected last "${spyName}" call to not have been called with #{exp}`,
1497
+ args,
1498
+ lastCall
1398
1499
  );
1399
1500
  }
1400
- if (typeof expected === "object" && "asymmetricMatch" in expected && typeof expected.asymmetricMatch === "function") {
1401
- const matcher = expected;
1402
- return this.assert(
1403
- thrown && matcher.asymmetricMatch(thrown),
1404
- "expected error to match asymmetric matcher",
1405
- "expected error not to match asymmetric matcher",
1406
- matcher,
1407
- thrown
1501
+ );
1502
+ def(
1503
+ ["toThrow", "toThrowError"],
1504
+ function(expected) {
1505
+ if (typeof expected === "string" || typeof expected === "undefined" || expected instanceof RegExp) {
1506
+ return this.throws(expected);
1507
+ }
1508
+ const obj = this._obj;
1509
+ const promise = utils.flag(this, "promise");
1510
+ const isNot = utils.flag(this, "negate");
1511
+ let thrown = null;
1512
+ if (promise === "rejects") {
1513
+ thrown = obj;
1514
+ } else if (promise === "resolves" && typeof obj !== "function") {
1515
+ if (!isNot) {
1516
+ const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't";
1517
+ const error = {
1518
+ showDiff: false
1519
+ };
1520
+ throw new AssertionError(message, error, utils.flag(this, "ssfi"));
1521
+ } else {
1522
+ return;
1523
+ }
1524
+ } else {
1525
+ let isThrow = false;
1526
+ try {
1527
+ obj();
1528
+ } catch (err) {
1529
+ isThrow = true;
1530
+ thrown = err;
1531
+ }
1532
+ if (!isThrow && !isNot) {
1533
+ const message = utils.flag(this, "message") || "expected function to throw an error, but it didn't";
1534
+ const error = {
1535
+ showDiff: false
1536
+ };
1537
+ throw new AssertionError(message, error, utils.flag(this, "ssfi"));
1538
+ }
1539
+ }
1540
+ if (typeof expected === "function") {
1541
+ const name = expected.name || expected.prototype.constructor.name;
1542
+ return this.assert(
1543
+ thrown && thrown instanceof expected,
1544
+ `expected error to be instance of ${name}`,
1545
+ `expected error not to be instance of ${name}`,
1546
+ expected,
1547
+ thrown
1548
+ );
1549
+ }
1550
+ if (expected instanceof Error) {
1551
+ return this.assert(
1552
+ thrown && expected.message === thrown.message,
1553
+ `expected error to have message: ${expected.message}`,
1554
+ `expected error not to have message: ${expected.message}`,
1555
+ expected.message,
1556
+ thrown && thrown.message
1557
+ );
1558
+ }
1559
+ if (typeof expected === "object" && "asymmetricMatch" in expected && typeof expected.asymmetricMatch === "function") {
1560
+ const matcher = expected;
1561
+ return this.assert(
1562
+ thrown && matcher.asymmetricMatch(thrown),
1563
+ "expected error to match asymmetric matcher",
1564
+ "expected error not to match asymmetric matcher",
1565
+ matcher,
1566
+ thrown
1567
+ );
1568
+ }
1569
+ throw new Error(
1570
+ `"toThrow" expects string, RegExp, function, Error instance or asymmetric matcher, got "${typeof expected}"`
1408
1571
  );
1409
1572
  }
1410
- throw new Error(`"toThrow" expects string, RegExp, function, Error instance or asymmetric matcher, got "${typeof expected}"`);
1411
- });
1573
+ );
1412
1574
  [
1413
1575
  {
1414
1576
  name: "toHaveResolved",
@@ -1438,12 +1600,18 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
1438
1600
  [
1439
1601
  {
1440
1602
  name: "toHaveResolvedTimes",
1441
- condition: (spy, times) => spy.mock.settledResults.reduce((s, { type }) => type === "fulfilled" ? ++s : s, 0) === times,
1603
+ condition: (spy, times) => spy.mock.settledResults.reduce(
1604
+ (s, { type }) => type === "fulfilled" ? ++s : s,
1605
+ 0
1606
+ ) === times,
1442
1607
  action: "resolved"
1443
1608
  },
1444
1609
  {
1445
1610
  name: ["toHaveReturnedTimes", "toReturnTimes"],
1446
- condition: (spy, times) => spy.mock.results.reduce((s, { type }) => type === "throw" ? s : ++s, 0) === times,
1611
+ condition: (spy, times) => spy.mock.results.reduce(
1612
+ (s, { type }) => type === "throw" ? s : ++s,
1613
+ 0
1614
+ ) === times,
1447
1615
  action: "called"
1448
1616
  }
1449
1617
  ].forEach(({ name, condition, action }) => {
@@ -1464,12 +1632,16 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
1464
1632
  [
1465
1633
  {
1466
1634
  name: "toHaveResolvedWith",
1467
- condition: (spy, value) => spy.mock.settledResults.some(({ type, value: result }) => type === "fulfilled" && equals(value, result)),
1635
+ condition: (spy, value) => spy.mock.settledResults.some(
1636
+ ({ type, value: result }) => type === "fulfilled" && equals(value, result)
1637
+ ),
1468
1638
  action: "resolve"
1469
1639
  },
1470
1640
  {
1471
1641
  name: ["toHaveReturnedWith", "toReturnWith"],
1472
- condition: (spy, value) => spy.mock.results.some(({ type, value: result }) => type === "return" && equals(value, result)),
1642
+ condition: (spy, value) => spy.mock.results.some(
1643
+ ({ type, value: result }) => type === "return" && equals(value, result)
1644
+ ),
1473
1645
  action: "return"
1474
1646
  }
1475
1647
  ].forEach(({ name, condition, action }) => {
@@ -1479,15 +1651,12 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
1479
1651
  const isNot = utils.flag(this, "negate");
1480
1652
  if (pass && isNot || !pass && !isNot) {
1481
1653
  const spyName = spy.getMockName();
1482
- const msg = utils.getMessage(
1483
- this,
1484
- [
1485
- pass,
1486
- `expected "${spyName}" to ${action} with: #{exp} at least once`,
1487
- `expected "${spyName}" to not ${action} with: #{exp}`,
1488
- value
1489
- ]
1490
- );
1654
+ const msg = utils.getMessage(this, [
1655
+ pass,
1656
+ `expected "${spyName}" to ${action} with: #{exp} at least once`,
1657
+ `expected "${spyName}" to not ${action} with: #{exp}`,
1658
+ value
1659
+ ]);
1491
1660
  const results = action === "return" ? spy.mock.results : spy.mock.settledResults;
1492
1661
  throw new AssertionError(formatReturns(spy, results, msg, value));
1493
1662
  }
@@ -1562,84 +1731,121 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
1562
1731
  return this.be.satisfy(matcher, message);
1563
1732
  });
1564
1733
  def("withContext", function(context) {
1565
- for (const key in context)
1734
+ for (const key in context) {
1566
1735
  utils.flag(this, key, context[key]);
1736
+ }
1567
1737
  return this;
1568
1738
  });
1569
- utils.addProperty(chai.Assertion.prototype, "resolves", function __VITEST_RESOLVES__() {
1570
- const error = new Error("resolves");
1571
- utils.flag(this, "promise", "resolves");
1572
- utils.flag(this, "error", error);
1573
- const test = utils.flag(this, "vitest-test");
1574
- const obj = utils.flag(this, "object");
1575
- if (utils.flag(this, "poll"))
1576
- throw new SyntaxError(`expect.poll() is not supported in combination with .resolves`);
1577
- if (typeof (obj == null ? void 0 : obj.then) !== "function")
1578
- throw new TypeError(`You must provide a Promise to expect() when using .resolves, not '${typeof obj}'.`);
1579
- const proxy = new Proxy(this, {
1580
- get: (target, key, receiver) => {
1581
- const result = Reflect.get(target, key, receiver);
1582
- if (typeof result !== "function")
1583
- return result instanceof chai.Assertion ? proxy : result;
1584
- return async (...args) => {
1585
- const promise = obj.then(
1586
- (value) => {
1587
- utils.flag(this, "object", value);
1588
- return result.call(this, ...args);
1589
- },
1590
- (err) => {
1591
- const _error = new AssertionError(
1592
- `promise rejected "${utils.inspect(err)}" instead of resolving`,
1593
- { showDiff: false }
1594
- );
1595
- _error.cause = err;
1596
- _error.stack = error.stack.replace(error.message, _error.message);
1597
- throw _error;
1598
- }
1599
- );
1600
- return recordAsyncExpect(test, promise);
1601
- };
1739
+ utils.addProperty(
1740
+ chai.Assertion.prototype,
1741
+ "resolves",
1742
+ function __VITEST_RESOLVES__() {
1743
+ const error = new Error("resolves");
1744
+ utils.flag(this, "promise", "resolves");
1745
+ utils.flag(this, "error", error);
1746
+ const test = utils.flag(this, "vitest-test");
1747
+ const obj = utils.flag(this, "object");
1748
+ if (utils.flag(this, "poll")) {
1749
+ throw new SyntaxError(
1750
+ `expect.poll() is not supported in combination with .resolves`
1751
+ );
1602
1752
  }
1603
- });
1604
- return proxy;
1605
- });
1606
- utils.addProperty(chai.Assertion.prototype, "rejects", function __VITEST_REJECTS__() {
1607
- const error = new Error("rejects");
1608
- utils.flag(this, "promise", "rejects");
1609
- utils.flag(this, "error", error);
1610
- const test = utils.flag(this, "vitest-test");
1611
- const obj = utils.flag(this, "object");
1612
- const wrapper = typeof obj === "function" ? obj() : obj;
1613
- if (utils.flag(this, "poll"))
1614
- throw new SyntaxError(`expect.poll() is not supported in combination with .rejects`);
1615
- if (typeof (wrapper == null ? void 0 : wrapper.then) !== "function")
1616
- throw new TypeError(`You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`);
1617
- const proxy = new Proxy(this, {
1618
- get: (target, key, receiver) => {
1619
- const result = Reflect.get(target, key, receiver);
1620
- if (typeof result !== "function")
1621
- return result instanceof chai.Assertion ? proxy : result;
1622
- return async (...args) => {
1623
- const promise = wrapper.then(
1624
- (value) => {
1625
- const _error = new AssertionError(
1626
- `promise resolved "${utils.inspect(value)}" instead of rejecting`,
1627
- { showDiff: true, expected: new Error("rejected promise"), actual: value }
1628
- );
1629
- _error.stack = error.stack.replace(error.message, _error.message);
1630
- throw _error;
1631
- },
1632
- (err) => {
1633
- utils.flag(this, "object", err);
1634
- return result.call(this, ...args);
1635
- }
1636
- );
1637
- return recordAsyncExpect(test, promise);
1638
- };
1753
+ if (typeof (obj == null ? void 0 : obj.then) !== "function") {
1754
+ throw new TypeError(
1755
+ `You must provide a Promise to expect() when using .resolves, not '${typeof obj}'.`
1756
+ );
1639
1757
  }
1640
- });
1641
- return proxy;
1642
- });
1758
+ const proxy = new Proxy(this, {
1759
+ get: (target, key, receiver) => {
1760
+ const result = Reflect.get(target, key, receiver);
1761
+ if (typeof result !== "function") {
1762
+ return result instanceof chai.Assertion ? proxy : result;
1763
+ }
1764
+ return async (...args) => {
1765
+ const promise = obj.then(
1766
+ (value) => {
1767
+ utils.flag(this, "object", value);
1768
+ return result.call(this, ...args);
1769
+ },
1770
+ (err) => {
1771
+ const _error = new AssertionError(
1772
+ `promise rejected "${utils.inspect(
1773
+ err
1774
+ )}" instead of resolving`,
1775
+ { showDiff: false }
1776
+ );
1777
+ _error.cause = err;
1778
+ _error.stack = error.stack.replace(
1779
+ error.message,
1780
+ _error.message
1781
+ );
1782
+ throw _error;
1783
+ }
1784
+ );
1785
+ return recordAsyncExpect(test, promise);
1786
+ };
1787
+ }
1788
+ });
1789
+ return proxy;
1790
+ }
1791
+ );
1792
+ utils.addProperty(
1793
+ chai.Assertion.prototype,
1794
+ "rejects",
1795
+ function __VITEST_REJECTS__() {
1796
+ const error = new Error("rejects");
1797
+ utils.flag(this, "promise", "rejects");
1798
+ utils.flag(this, "error", error);
1799
+ const test = utils.flag(this, "vitest-test");
1800
+ const obj = utils.flag(this, "object");
1801
+ const wrapper = typeof obj === "function" ? obj() : obj;
1802
+ if (utils.flag(this, "poll")) {
1803
+ throw new SyntaxError(
1804
+ `expect.poll() is not supported in combination with .rejects`
1805
+ );
1806
+ }
1807
+ if (typeof (wrapper == null ? void 0 : wrapper.then) !== "function") {
1808
+ throw new TypeError(
1809
+ `You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`
1810
+ );
1811
+ }
1812
+ const proxy = new Proxy(this, {
1813
+ get: (target, key, receiver) => {
1814
+ const result = Reflect.get(target, key, receiver);
1815
+ if (typeof result !== "function") {
1816
+ return result instanceof chai.Assertion ? proxy : result;
1817
+ }
1818
+ return async (...args) => {
1819
+ const promise = wrapper.then(
1820
+ (value) => {
1821
+ const _error = new AssertionError(
1822
+ `promise resolved "${utils.inspect(
1823
+ value
1824
+ )}" instead of rejecting`,
1825
+ {
1826
+ showDiff: true,
1827
+ expected: new Error("rejected promise"),
1828
+ actual: value
1829
+ }
1830
+ );
1831
+ _error.stack = error.stack.replace(
1832
+ error.message,
1833
+ _error.message
1834
+ );
1835
+ throw _error;
1836
+ },
1837
+ (err) => {
1838
+ utils.flag(this, "object", err);
1839
+ return result.call(this, ...args);
1840
+ }
1841
+ );
1842
+ return recordAsyncExpect(test, promise);
1843
+ };
1844
+ }
1845
+ });
1846
+ return proxy;
1847
+ }
1848
+ );
1643
1849
  };
1644
1850
 
1645
1851
  function getMatcherState(assertion, expect) {
@@ -1680,71 +1886,91 @@ class JestExtendError extends Error {
1680
1886
  }
1681
1887
  function JestExtendPlugin(c, expect, matchers) {
1682
1888
  return (_, utils) => {
1683
- Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => {
1684
- function expectWrapper(...args) {
1685
- const { state, isNot, obj } = getMatcherState(this, expect);
1686
- const result = expectAssertion.call(state, obj, ...args);
1687
- if (result && typeof result === "object" && result instanceof Promise) {
1688
- return result.then(({ pass: pass2, message: message2, actual: actual2, expected: expected2 }) => {
1689
- if (pass2 && isNot || !pass2 && !isNot)
1690
- throw new JestExtendError(message2(), actual2, expected2);
1691
- });
1692
- }
1693
- const { pass, message, actual, expected } = result;
1694
- if (pass && isNot || !pass && !isNot)
1695
- throw new JestExtendError(message(), actual, expected);
1696
- }
1697
- const softWrapper = wrapSoft(utils, expectWrapper);
1698
- utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, softWrapper);
1699
- utils.addMethod(c.Assertion.prototype, expectAssertionName, softWrapper);
1700
- class CustomMatcher extends AsymmetricMatcher {
1701
- constructor(inverse = false, ...sample) {
1702
- super(sample, inverse);
1703
- }
1704
- asymmetricMatch(other) {
1705
- const { pass } = expectAssertion.call(
1706
- this.getMatcherContext(expect),
1707
- other,
1708
- ...this.sample
1709
- );
1710
- return this.inverse ? !pass : pass;
1711
- }
1712
- toString() {
1713
- return `${this.inverse ? "not." : ""}${expectAssertionName}`;
1714
- }
1715
- getExpectedType() {
1716
- return "any";
1889
+ Object.entries(matchers).forEach(
1890
+ ([expectAssertionName, expectAssertion]) => {
1891
+ function expectWrapper(...args) {
1892
+ const { state, isNot, obj } = getMatcherState(this, expect);
1893
+ const result = expectAssertion.call(state, obj, ...args);
1894
+ if (result && typeof result === "object" && result instanceof Promise) {
1895
+ return result.then(({ pass: pass2, message: message2, actual: actual2, expected: expected2 }) => {
1896
+ if (pass2 && isNot || !pass2 && !isNot) {
1897
+ throw new JestExtendError(message2(), actual2, expected2);
1898
+ }
1899
+ });
1900
+ }
1901
+ const { pass, message, actual, expected } = result;
1902
+ if (pass && isNot || !pass && !isNot) {
1903
+ throw new JestExtendError(message(), actual, expected);
1904
+ }
1717
1905
  }
1718
- toAsymmetricMatcher() {
1719
- return `${this.toString()}<${this.sample.map(String).join(", ")}>`;
1906
+ const softWrapper = wrapSoft(utils, expectWrapper);
1907
+ utils.addMethod(
1908
+ globalThis[JEST_MATCHERS_OBJECT].matchers,
1909
+ expectAssertionName,
1910
+ softWrapper
1911
+ );
1912
+ utils.addMethod(
1913
+ c.Assertion.prototype,
1914
+ expectAssertionName,
1915
+ softWrapper
1916
+ );
1917
+ class CustomMatcher extends AsymmetricMatcher {
1918
+ constructor(inverse = false, ...sample) {
1919
+ super(sample, inverse);
1920
+ }
1921
+ asymmetricMatch(other) {
1922
+ const { pass } = expectAssertion.call(
1923
+ this.getMatcherContext(expect),
1924
+ other,
1925
+ ...this.sample
1926
+ );
1927
+ return this.inverse ? !pass : pass;
1928
+ }
1929
+ toString() {
1930
+ return `${this.inverse ? "not." : ""}${expectAssertionName}`;
1931
+ }
1932
+ getExpectedType() {
1933
+ return "any";
1934
+ }
1935
+ toAsymmetricMatcher() {
1936
+ return `${this.toString()}<${this.sample.map(String).join(", ")}>`;
1937
+ }
1720
1938
  }
1939
+ const customMatcher = (...sample) => new CustomMatcher(false, ...sample);
1940
+ Object.defineProperty(expect, expectAssertionName, {
1941
+ configurable: true,
1942
+ enumerable: true,
1943
+ value: customMatcher,
1944
+ writable: true
1945
+ });
1946
+ Object.defineProperty(expect.not, expectAssertionName, {
1947
+ configurable: true,
1948
+ enumerable: true,
1949
+ value: (...sample) => new CustomMatcher(true, ...sample),
1950
+ writable: true
1951
+ });
1952
+ Object.defineProperty(
1953
+ globalThis[ASYMMETRIC_MATCHERS_OBJECT],
1954
+ expectAssertionName,
1955
+ {
1956
+ configurable: true,
1957
+ enumerable: true,
1958
+ value: customMatcher,
1959
+ writable: true
1960
+ }
1961
+ );
1721
1962
  }
1722
- const customMatcher = (...sample) => new CustomMatcher(false, ...sample);
1723
- Object.defineProperty(expect, expectAssertionName, {
1724
- configurable: true,
1725
- enumerable: true,
1726
- value: customMatcher,
1727
- writable: true
1728
- });
1729
- Object.defineProperty(expect.not, expectAssertionName, {
1730
- configurable: true,
1731
- enumerable: true,
1732
- value: (...sample) => new CustomMatcher(true, ...sample),
1733
- writable: true
1734
- });
1735
- Object.defineProperty(globalThis[ASYMMETRIC_MATCHERS_OBJECT], expectAssertionName, {
1736
- configurable: true,
1737
- enumerable: true,
1738
- value: customMatcher,
1739
- writable: true
1740
- });
1741
- });
1963
+ );
1742
1964
  };
1743
1965
  }
1744
1966
  const JestExtend = (chai, utils) => {
1745
- utils.addMethod(chai.expect, "extend", (expect, expects) => {
1746
- use(JestExtendPlugin(chai, expect, expects));
1747
- });
1967
+ utils.addMethod(
1968
+ chai.expect,
1969
+ "extend",
1970
+ (expect, expects) => {
1971
+ use(JestExtendPlugin(chai, expect, expects));
1972
+ }
1973
+ );
1748
1974
  };
1749
1975
 
1750
1976
  export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality };