@vitest/expect 4.0.0-beta.1 → 4.0.0-beta.11
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/LICENSE +1 -1
- package/dist/index.d.ts +37 -64
- package/dist/index.js +51 -28
- package/package.json +6 -7
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2021-Present Vitest
|
|
3
|
+
Copyright (c) 2021-Present VoidZero Inc. and Vitest contributors
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { MockInstance } from '@vitest/spy';
|
|
2
|
-
import {
|
|
2
|
+
import { Constructable } from '@vitest/utils';
|
|
3
3
|
import { Formatter } from 'tinyrainbow';
|
|
4
4
|
import { diff, printDiffOrStringify } from '@vitest/utils/diff';
|
|
5
5
|
export { DiffOptions } from '@vitest/utils/diff';
|
|
6
|
+
import { stringify } from '@vitest/utils/display';
|
|
7
|
+
import * as chai from 'chai';
|
|
8
|
+
export { chai };
|
|
6
9
|
|
|
7
10
|
declare const MATCHERS_OBJECT: unique symbol;
|
|
8
11
|
declare const JEST_MATCHERS_OBJECT: unique symbol;
|
|
9
12
|
declare const GLOBAL_EXPECT: unique symbol;
|
|
10
13
|
declare const ASYMMETRIC_MATCHERS_OBJECT: unique symbol;
|
|
11
14
|
|
|
12
|
-
/* eslint-disable unicorn/no-instanceof-builtins -- we check both */
|
|
13
|
-
|
|
14
15
|
interface AsymmetricMatcherInterface {
|
|
15
|
-
asymmetricMatch: (other: unknown) => boolean;
|
|
16
|
+
asymmetricMatch: (other: unknown, customTesters?: Array<Tester>) => boolean;
|
|
16
17
|
toString: () => string;
|
|
17
18
|
getExpectedType?: () => string;
|
|
18
19
|
toAsymmetricMatcher?: () => string;
|
|
@@ -23,11 +24,10 @@ declare abstract class AsymmetricMatcher<
|
|
|
23
24
|
> implements AsymmetricMatcherInterface {
|
|
24
25
|
protected sample: T;
|
|
25
26
|
protected inverse: boolean;
|
|
26
|
-
// should have "jest" to be compatible with its ecosystem
|
|
27
27
|
$$typeof: symbol;
|
|
28
28
|
constructor(sample: T, inverse?: boolean);
|
|
29
29
|
protected getMatcherContext(expect?: Chai.ExpectStatic): State;
|
|
30
|
-
abstract asymmetricMatch(other: unknown): boolean;
|
|
30
|
+
abstract asymmetricMatch(other: unknown, customTesters?: Array<Tester>): boolean;
|
|
31
31
|
abstract toString(): string;
|
|
32
32
|
getExpectedType?(): string;
|
|
33
33
|
toAsymmetricMatcher?(): string;
|
|
@@ -43,17 +43,18 @@ declare class Anything extends AsymmetricMatcher<void> {
|
|
|
43
43
|
toString(): string;
|
|
44
44
|
toAsymmetricMatcher(): string;
|
|
45
45
|
}
|
|
46
|
-
declare class ObjectContaining extends AsymmetricMatcher<Record<string, unknown>> {
|
|
46
|
+
declare class ObjectContaining extends AsymmetricMatcher<Record<string | symbol | number, unknown>> {
|
|
47
47
|
constructor(sample: Record<string, unknown>, inverse?: boolean);
|
|
48
48
|
getPrototype(obj: object): any;
|
|
49
|
-
hasProperty(obj: object | null, property: string): boolean;
|
|
50
|
-
|
|
49
|
+
hasProperty(obj: object | null, property: string | symbol): boolean;
|
|
50
|
+
getProperties(obj: object): (string | symbol)[];
|
|
51
|
+
asymmetricMatch(other: any, customTesters?: Array<Tester>): boolean;
|
|
51
52
|
toString(): string;
|
|
52
53
|
getExpectedType(): string;
|
|
53
54
|
}
|
|
54
55
|
declare class ArrayContaining<T = unknown> extends AsymmetricMatcher<Array<T>> {
|
|
55
56
|
constructor(sample: Array<T>, inverse?: boolean);
|
|
56
|
-
asymmetricMatch(other: Array<T>): boolean;
|
|
57
|
+
asymmetricMatch(other: Array<T>, customTesters?: Array<Tester>): boolean;
|
|
57
58
|
toString(): string;
|
|
58
59
|
getExpectedType(): string;
|
|
59
60
|
}
|
|
@@ -77,17 +78,17 @@ declare function matcherHint(matcherName: string, received?: string, expected?:
|
|
|
77
78
|
declare function printReceived(object: unknown): string;
|
|
78
79
|
declare function printExpected(value: unknown): string;
|
|
79
80
|
declare function getMatcherUtils(): {
|
|
80
|
-
EXPECTED_COLOR: Formatter
|
|
81
|
-
RECEIVED_COLOR: Formatter
|
|
82
|
-
INVERTED_COLOR: Formatter
|
|
83
|
-
BOLD_WEIGHT: Formatter
|
|
84
|
-
DIM_COLOR: Formatter
|
|
85
|
-
diff: typeof diff
|
|
86
|
-
matcherHint: typeof matcherHint
|
|
87
|
-
printReceived: typeof printReceived
|
|
88
|
-
printExpected: typeof printExpected
|
|
89
|
-
printDiffOrStringify: typeof printDiffOrStringify
|
|
90
|
-
printWithType: typeof printWithType
|
|
81
|
+
EXPECTED_COLOR: Formatter;
|
|
82
|
+
RECEIVED_COLOR: Formatter;
|
|
83
|
+
INVERTED_COLOR: Formatter;
|
|
84
|
+
BOLD_WEIGHT: Formatter;
|
|
85
|
+
DIM_COLOR: Formatter;
|
|
86
|
+
diff: typeof diff;
|
|
87
|
+
matcherHint: typeof matcherHint;
|
|
88
|
+
printReceived: typeof printReceived;
|
|
89
|
+
printExpected: typeof printExpected;
|
|
90
|
+
printDiffOrStringify: typeof printDiffOrStringify;
|
|
91
|
+
printWithType: typeof printWithType;
|
|
91
92
|
};
|
|
92
93
|
declare function printWithType<T>(name: string, value: T, print: (value: T) => string): string;
|
|
93
94
|
declare function addCustomEqualityTesters(newTesters: Array<Tester>): void;
|
|
@@ -129,16 +130,14 @@ interface MatcherState {
|
|
|
129
130
|
isExpectingAssertions?: boolean;
|
|
130
131
|
isExpectingAssertionsError?: Error | null;
|
|
131
132
|
isNot: boolean;
|
|
132
|
-
// environment: VitestEnvironment
|
|
133
133
|
promise: string;
|
|
134
|
-
// snapshotState: SnapshotState
|
|
135
134
|
suppressedErrors: Array<Error>;
|
|
136
135
|
testPath?: string;
|
|
137
136
|
utils: ReturnType<typeof getMatcherUtils> & {
|
|
138
|
-
diff: typeof diff
|
|
139
|
-
stringify: typeof stringify
|
|
140
|
-
iterableEquality: Tester
|
|
141
|
-
subsetEquality: Tester
|
|
137
|
+
diff: typeof diff;
|
|
138
|
+
stringify: typeof stringify;
|
|
139
|
+
iterableEquality: Tester;
|
|
140
|
+
subsetEquality: Tester;
|
|
142
141
|
};
|
|
143
142
|
soft?: boolean;
|
|
144
143
|
poll?: boolean;
|
|
@@ -157,9 +156,6 @@ interface RawMatcherFn<
|
|
|
157
156
|
> {
|
|
158
157
|
(this: T, received: any, ...expected: E): ExpectationResult;
|
|
159
158
|
}
|
|
160
|
-
// Allow unused `T` to preserve its name for extensions.
|
|
161
|
-
// Type parameter names must be identical when extending those types.
|
|
162
|
-
// eslint-disable-next-line
|
|
163
159
|
interface Matchers<T = any> {}
|
|
164
160
|
type MatchersObject<T extends MatcherState = MatcherState> = Record<string, RawMatcherFn<T>> & ThisType<T> & { [K in keyof Matchers<T>]? : RawMatcherFn<T, Parameters<Matchers<T>[K]>> };
|
|
165
161
|
interface ExpectStatic extends Chai.ExpectStatic, Matchers, AsymmetricMatchersContaining {
|
|
@@ -366,6 +362,13 @@ interface JestAssertion<T = any> extends jest.Matchers<void, T>, CustomMatcher {
|
|
|
366
362
|
*/
|
|
367
363
|
toBeNull: () => void;
|
|
368
364
|
/**
|
|
365
|
+
* Used to check that a variable is nullable (null or undefined).
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
* expect(value).toBeNullable();
|
|
369
|
+
*/
|
|
370
|
+
toBeNullable: () => void;
|
|
371
|
+
/**
|
|
369
372
|
* Ensure that a variable is not undefined.
|
|
370
373
|
*
|
|
371
374
|
* @example
|
|
@@ -736,52 +739,22 @@ interface Assertion<T = any> extends VitestAssertion<Chai.Assertion, T>, JestAss
|
|
|
736
739
|
rejects: PromisifyAssertion<T>;
|
|
737
740
|
}
|
|
738
741
|
declare global {
|
|
739
|
-
// support augmenting jest.Matchers by other libraries
|
|
740
|
-
// eslint-disable-next-line ts/no-namespace
|
|
741
742
|
namespace jest {
|
|
742
|
-
|
|
743
|
-
interface Matchers<
|
|
743
|
+
interface Matchers<
|
|
744
744
|
R,
|
|
745
745
|
T = {}
|
|
746
746
|
> {}
|
|
747
747
|
}
|
|
748
748
|
}
|
|
749
749
|
|
|
750
|
-
// selectively ported from https://github.com/jest-community/jest-extended
|
|
751
750
|
declare const customMatchers: MatchersObject;
|
|
752
751
|
|
|
753
|
-
// Jest Expect Compact
|
|
754
752
|
declare const JestChaiExpect: ChaiPlugin;
|
|
755
753
|
|
|
756
754
|
declare const JestExtend: ChaiPlugin;
|
|
757
755
|
|
|
758
|
-
/*
|
|
759
|
-
Copyright (c) 2008-2016 Pivotal Labs
|
|
760
|
-
|
|
761
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
|
762
|
-
a copy of this software and associated documentation files (the
|
|
763
|
-
"Software"), to deal in the Software without restriction, including
|
|
764
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
|
765
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
|
766
|
-
permit persons to whom the Software is furnished to do so, subject to
|
|
767
|
-
the following conditions:
|
|
768
|
-
|
|
769
|
-
The above copyright notice and this permission notice shall be
|
|
770
|
-
included in all copies or substantial portions of the Software.
|
|
771
|
-
|
|
772
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
773
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
774
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
775
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
776
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
777
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
778
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
779
|
-
|
|
780
|
-
*/
|
|
781
|
-
|
|
782
|
-
// Extracted out of jasmine 2.5.2
|
|
783
756
|
declare function equals(a: unknown, b: unknown, customTesters?: Array<Tester>, strictCheck?: boolean): boolean;
|
|
784
|
-
declare function isAsymmetric(obj: any):
|
|
757
|
+
declare function isAsymmetric(obj: any): obj is AsymmetricMatcher<any>;
|
|
785
758
|
declare function hasAsymmetric(obj: any, seen?: Set<any>): boolean;
|
|
786
759
|
declare function isA(typeName: string, value: unknown): boolean;
|
|
787
760
|
declare function fnNameFor(func: Function): string;
|
|
@@ -797,8 +770,8 @@ declare function generateToBeMessage(deepEqualityName: string, expected?: string
|
|
|
797
770
|
declare function pluralize(word: string, count: number): string;
|
|
798
771
|
declare function getObjectKeys(object: object): Array<string | symbol>;
|
|
799
772
|
declare function getObjectSubset(object: any, subset: any, customTesters: Array<Tester>): {
|
|
800
|
-
subset: any
|
|
801
|
-
stripped: number
|
|
773
|
+
subset: any;
|
|
774
|
+
stripped: number;
|
|
802
775
|
};
|
|
803
776
|
|
|
804
777
|
declare function getState<State extends MatcherState = MatcherState>(expect: ExpectStatic): State;
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { getType, stringify, isObject, noop, assertTypes } from '@vitest/utils';
|
|
2
1
|
import { printDiffOrStringify, diff } from '@vitest/utils/diff';
|
|
2
|
+
import { stringify } from '@vitest/utils/display';
|
|
3
|
+
import { getType, isObject, noop, assertTypes } from '@vitest/utils/helpers';
|
|
3
4
|
import c from 'tinyrainbow';
|
|
4
5
|
import { isMockFunction } from '@vitest/spy';
|
|
5
6
|
import { processError } from '@vitest/utils/error';
|
|
6
7
|
import { use, util } from 'chai';
|
|
8
|
+
import * as chai from 'chai';
|
|
9
|
+
export { chai };
|
|
7
10
|
|
|
8
11
|
const MATCHERS_OBJECT = Symbol.for("matchers-object");
|
|
9
12
|
const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
|
|
@@ -178,24 +181,24 @@ function hasAsymmetric(obj, seen = new Set()) {
|
|
|
178
181
|
}
|
|
179
182
|
return false;
|
|
180
183
|
}
|
|
181
|
-
function asymmetricMatch(a, b) {
|
|
184
|
+
function asymmetricMatch(a, b, customTesters) {
|
|
182
185
|
const asymmetricA = isAsymmetric(a);
|
|
183
186
|
const asymmetricB = isAsymmetric(b);
|
|
184
187
|
if (asymmetricA && asymmetricB) {
|
|
185
188
|
return undefined;
|
|
186
189
|
}
|
|
187
190
|
if (asymmetricA) {
|
|
188
|
-
return a.asymmetricMatch(b);
|
|
191
|
+
return a.asymmetricMatch(b, customTesters);
|
|
189
192
|
}
|
|
190
193
|
if (asymmetricB) {
|
|
191
|
-
return b.asymmetricMatch(a);
|
|
194
|
+
return b.asymmetricMatch(a, customTesters);
|
|
192
195
|
}
|
|
193
196
|
}
|
|
194
197
|
// Equality function lovingly adapted from isEqual in
|
|
195
198
|
// [Underscore](http://underscorejs.org)
|
|
196
199
|
function eq(a, b, aStack, bStack, customTesters, hasKey) {
|
|
197
200
|
let result = true;
|
|
198
|
-
const asymmetricResult = asymmetricMatch(a, b);
|
|
201
|
+
const asymmetricResult = asymmetricMatch(a, b, customTesters);
|
|
199
202
|
if (asymmetricResult !== undefined) {
|
|
200
203
|
return asymmetricResult;
|
|
201
204
|
}
|
|
@@ -339,7 +342,7 @@ function hasDefinedKey(obj, key) {
|
|
|
339
342
|
return hasKey(obj, key) && obj[key] !== undefined;
|
|
340
343
|
}
|
|
341
344
|
function hasKey(obj, key) {
|
|
342
|
-
return Object.
|
|
345
|
+
return Object.hasOwn(obj, key);
|
|
343
346
|
}
|
|
344
347
|
function isA(typeName, value) {
|
|
345
348
|
return Object.prototype.toString.apply(value) === `[object ${typeName}]`;
|
|
@@ -367,7 +370,7 @@ function hasProperty(obj, property) {
|
|
|
367
370
|
if (!obj) {
|
|
368
371
|
return false;
|
|
369
372
|
}
|
|
370
|
-
if (Object.
|
|
373
|
+
if (Object.hasOwn(obj, property)) {
|
|
371
374
|
return true;
|
|
372
375
|
}
|
|
373
376
|
return hasProperty(getPrototype(obj), property);
|
|
@@ -514,7 +517,7 @@ function hasPropertyInObject(object, key) {
|
|
|
514
517
|
if (shouldTerminate) {
|
|
515
518
|
return false;
|
|
516
519
|
}
|
|
517
|
-
return Object.
|
|
520
|
+
return Object.hasOwn(object, key) || hasPropertyInObject(Object.getPrototypeOf(object), key);
|
|
518
521
|
}
|
|
519
522
|
function isObjectWithKeys(a) {
|
|
520
523
|
return isObject(a) && !(a instanceof Error) && !Array.isArray(a) && !(a instanceof Date);
|
|
@@ -658,7 +661,7 @@ function getObjectSubset(object, subset, customTesters) {
|
|
|
658
661
|
};
|
|
659
662
|
}
|
|
660
663
|
|
|
661
|
-
if (!Object.
|
|
664
|
+
if (!Object.hasOwn(globalThis, MATCHERS_OBJECT)) {
|
|
662
665
|
const globalState = new WeakMap();
|
|
663
666
|
const matchers = Object.create(null);
|
|
664
667
|
const customEqualityTesters = [];
|
|
@@ -769,19 +772,32 @@ class ObjectContaining extends AsymmetricMatcher {
|
|
|
769
772
|
if (!obj) {
|
|
770
773
|
return false;
|
|
771
774
|
}
|
|
772
|
-
if (Object.
|
|
775
|
+
if (Object.hasOwn(obj, property)) {
|
|
773
776
|
return true;
|
|
774
777
|
}
|
|
775
778
|
return this.hasProperty(this.getPrototype(obj), property);
|
|
776
779
|
}
|
|
777
|
-
|
|
780
|
+
getProperties(obj) {
|
|
781
|
+
return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj).filter((s) => {
|
|
782
|
+
var _Object$getOwnPropert;
|
|
783
|
+
return (_Object$getOwnPropert = Object.getOwnPropertyDescriptor(obj, s)) === null || _Object$getOwnPropert === void 0 ? void 0 : _Object$getOwnPropert.enumerable;
|
|
784
|
+
})];
|
|
785
|
+
}
|
|
786
|
+
asymmetricMatch(other, customTesters) {
|
|
778
787
|
if (typeof this.sample !== "object") {
|
|
779
788
|
throw new TypeError(`You must provide an object to ${this.toString()}, not '${typeof this.sample}'.`);
|
|
780
789
|
}
|
|
781
790
|
let result = true;
|
|
782
|
-
const
|
|
783
|
-
for (const property
|
|
784
|
-
|
|
791
|
+
const properties = this.getProperties(this.sample);
|
|
792
|
+
for (const property of properties) {
|
|
793
|
+
var _Object$getOwnPropert2, _Object$getOwnPropert3;
|
|
794
|
+
if (!this.hasProperty(other, property)) {
|
|
795
|
+
result = false;
|
|
796
|
+
break;
|
|
797
|
+
}
|
|
798
|
+
const value = ((_Object$getOwnPropert2 = Object.getOwnPropertyDescriptor(this.sample, property)) === null || _Object$getOwnPropert2 === void 0 ? void 0 : _Object$getOwnPropert2.value) ?? this.sample[property];
|
|
799
|
+
const otherValue = ((_Object$getOwnPropert3 = Object.getOwnPropertyDescriptor(other, property)) === null || _Object$getOwnPropert3 === void 0 ? void 0 : _Object$getOwnPropert3.value) ?? other[property];
|
|
800
|
+
if (!equals(value, otherValue, customTesters)) {
|
|
785
801
|
result = false;
|
|
786
802
|
break;
|
|
787
803
|
}
|
|
@@ -799,12 +815,11 @@ class ArrayContaining extends AsymmetricMatcher {
|
|
|
799
815
|
constructor(sample, inverse = false) {
|
|
800
816
|
super(sample, inverse);
|
|
801
817
|
}
|
|
802
|
-
asymmetricMatch(other) {
|
|
818
|
+
asymmetricMatch(other, customTesters) {
|
|
803
819
|
if (!Array.isArray(this.sample)) {
|
|
804
820
|
throw new TypeError(`You must provide an array to ${this.toString()}, not '${typeof this.sample}'.`);
|
|
805
821
|
}
|
|
806
|
-
const
|
|
807
|
-
const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every((item) => other.some((another) => equals(item, another, matcherContext.customTesters)));
|
|
822
|
+
const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every((item) => other.some((another) => equals(item, another, customTesters)));
|
|
808
823
|
return this.inverse ? !result : result;
|
|
809
824
|
}
|
|
810
825
|
toString() {
|
|
@@ -1241,6 +1256,10 @@ const JestChaiExpect = (chai, utils) => {
|
|
|
1241
1256
|
const obj = utils.flag(this, "object");
|
|
1242
1257
|
this.assert(obj === null, "expected #{this} to be null", "expected #{this} not to be null", null, obj);
|
|
1243
1258
|
});
|
|
1259
|
+
def("toBeNullable", function() {
|
|
1260
|
+
const obj = utils.flag(this, "object");
|
|
1261
|
+
this.assert(obj == null, "expected #{this} to be nullish", "expected #{this} not to be nullish", null, obj);
|
|
1262
|
+
});
|
|
1244
1263
|
def("toBeDefined", function() {
|
|
1245
1264
|
const obj = utils.flag(this, "object");
|
|
1246
1265
|
this.assert(typeof obj !== "undefined", "expected #{this} to be defined", "expected #{this} to be undefined", obj);
|
|
@@ -1264,7 +1283,7 @@ const JestChaiExpect = (chai, utils) => {
|
|
|
1264
1283
|
const actual = this._obj;
|
|
1265
1284
|
const [propertyName, expected] = args;
|
|
1266
1285
|
const getValue = () => {
|
|
1267
|
-
const hasOwn = Object.
|
|
1286
|
+
const hasOwn = Object.hasOwn(actual, propertyName);
|
|
1268
1287
|
if (hasOwn) {
|
|
1269
1288
|
return {
|
|
1270
1289
|
value: actual[propertyName],
|
|
@@ -1383,7 +1402,7 @@ const JestChaiExpect = (chai, utils) => {
|
|
|
1383
1402
|
def(["toHaveBeenLastCalledWith", "lastCalledWith"], function(...args) {
|
|
1384
1403
|
const spy = getSpy(this);
|
|
1385
1404
|
const spyName = spy.getMockName();
|
|
1386
|
-
const lastCall = spy.mock.calls
|
|
1405
|
+
const lastCall = spy.mock.calls.at(-1);
|
|
1387
1406
|
this.assert(lastCall && equalsArgumentArray(lastCall, args), `expected last "${spyName}" call to have been called with #{exp}`, `expected last "${spyName}" call to not have been called with #{exp}`, args, lastCall);
|
|
1388
1407
|
});
|
|
1389
1408
|
/**
|
|
@@ -1522,22 +1541,22 @@ const JestChaiExpect = (chai, utils) => {
|
|
|
1522
1541
|
[{
|
|
1523
1542
|
name: "toHaveLastResolvedWith",
|
|
1524
1543
|
condition: (spy, value) => {
|
|
1525
|
-
const result = spy.mock.settledResults
|
|
1526
|
-
return result && result.type === "fulfilled" && equals(result.value, value);
|
|
1544
|
+
const result = spy.mock.settledResults.at(-1);
|
|
1545
|
+
return Boolean(result && result.type === "fulfilled" && equals(result.value, value));
|
|
1527
1546
|
},
|
|
1528
1547
|
action: "resolve"
|
|
1529
1548
|
}, {
|
|
1530
1549
|
name: ["toHaveLastReturnedWith", "lastReturnedWith"],
|
|
1531
1550
|
condition: (spy, value) => {
|
|
1532
|
-
const result = spy.mock.results
|
|
1533
|
-
return result && result.type === "return" && equals(result.value, value);
|
|
1551
|
+
const result = spy.mock.results.at(-1);
|
|
1552
|
+
return Boolean(result && result.type === "return" && equals(result.value, value));
|
|
1534
1553
|
},
|
|
1535
1554
|
action: "return"
|
|
1536
1555
|
}].forEach(({ name, condition, action }) => {
|
|
1537
1556
|
def(name, function(value) {
|
|
1538
1557
|
const spy = getSpy(this);
|
|
1539
1558
|
const results = action === "return" ? spy.mock.results : spy.mock.settledResults;
|
|
1540
|
-
const result = results
|
|
1559
|
+
const result = results.at(-1);
|
|
1541
1560
|
const spyName = spy.getMockName();
|
|
1542
1561
|
this.assert(condition(spy, value), `expected last "${spyName}" call to ${action} #{exp}`, `expected last "${spyName}" call to not ${action} #{exp}`, value, result === null || result === void 0 ? void 0 : result.value);
|
|
1543
1562
|
});
|
|
@@ -1695,6 +1714,7 @@ function getMatcherState(assertion, expect) {
|
|
|
1695
1714
|
const obj = assertion._obj;
|
|
1696
1715
|
const isNot = util.flag(assertion, "negate");
|
|
1697
1716
|
const promise = util.flag(assertion, "promise") || "";
|
|
1717
|
+
const customMessage = util.flag(assertion, "message");
|
|
1698
1718
|
const jestUtils = {
|
|
1699
1719
|
...getMatcherUtils(),
|
|
1700
1720
|
diff,
|
|
@@ -1716,7 +1736,8 @@ function getMatcherState(assertion, expect) {
|
|
|
1716
1736
|
return {
|
|
1717
1737
|
state: matcherState,
|
|
1718
1738
|
isNot,
|
|
1719
|
-
obj
|
|
1739
|
+
obj,
|
|
1740
|
+
customMessage
|
|
1720
1741
|
};
|
|
1721
1742
|
}
|
|
1722
1743
|
class JestExtendError extends Error {
|
|
@@ -1730,19 +1751,21 @@ function JestExtendPlugin(c, expect, matchers) {
|
|
|
1730
1751
|
return (_, utils) => {
|
|
1731
1752
|
Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => {
|
|
1732
1753
|
function expectWrapper(...args) {
|
|
1733
|
-
const { state, isNot, obj } = getMatcherState(this, expect);
|
|
1754
|
+
const { state, isNot, obj, customMessage } = getMatcherState(this, expect);
|
|
1734
1755
|
const result = expectAssertion.call(state, obj, ...args);
|
|
1735
1756
|
if (result && typeof result === "object" && typeof result.then === "function") {
|
|
1736
1757
|
const thenable = result;
|
|
1737
1758
|
return thenable.then(({ pass, message, actual, expected }) => {
|
|
1738
1759
|
if (pass && isNot || !pass && !isNot) {
|
|
1739
|
-
|
|
1760
|
+
const errorMessage = customMessage != null ? customMessage : message();
|
|
1761
|
+
throw new JestExtendError(errorMessage, actual, expected);
|
|
1740
1762
|
}
|
|
1741
1763
|
});
|
|
1742
1764
|
}
|
|
1743
1765
|
const { pass, message, actual, expected } = result;
|
|
1744
1766
|
if (pass && isNot || !pass && !isNot) {
|
|
1745
|
-
|
|
1767
|
+
const errorMessage = customMessage != null ? customMessage : message();
|
|
1768
|
+
throw new JestExtendError(errorMessage, actual, expected);
|
|
1746
1769
|
}
|
|
1747
1770
|
}
|
|
1748
1771
|
const softWrapper = wrapAssertion(utils, expectAssertionName, expectWrapper);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest/expect",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.0.0-beta.
|
|
4
|
+
"version": "4.0.0-beta.11",
|
|
5
5
|
"description": "Jest's expect matchers as a Chai plugin",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": "https://opencollective.com/vitest",
|
|
@@ -30,14 +30,13 @@
|
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@types/chai": "^5.2.2",
|
|
33
|
-
"chai": "^
|
|
34
|
-
"tinyrainbow": "^
|
|
35
|
-
"@vitest/spy": "4.0.0-beta.
|
|
36
|
-
"@vitest/utils": "4.0.0-beta.
|
|
33
|
+
"chai": "^6.0.1",
|
|
34
|
+
"tinyrainbow": "^3.0.3",
|
|
35
|
+
"@vitest/spy": "4.0.0-beta.11",
|
|
36
|
+
"@vitest/utils": "4.0.0-beta.11"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"
|
|
40
|
-
"@vitest/runner": "4.0.0-beta.1"
|
|
39
|
+
"@vitest/runner": "4.0.0-beta.11"
|
|
41
40
|
},
|
|
42
41
|
"scripts": {
|
|
43
42
|
"build": "rimraf dist && rollup -c",
|