@vitest/expect
Advanced tools
Comparing version 2.1.4 to 2.1.5
@@ -100,51 +100,429 @@ import { stringify, Constructable } from '@vitest/utils'; | ||
interface AsymmetricMatchersContaining { | ||
/** | ||
* Matches if the received string contains the expected substring. | ||
* | ||
* @example | ||
* expect('I have an apple').toEqual(expect.stringContaining('apple')); | ||
* expect({ a: 'test string' }).toEqual({ a: expect.stringContaining('test') }); | ||
*/ | ||
stringContaining: (expected: string) => any; | ||
/** | ||
* Matches if the received object contains all properties of the expected object. | ||
* | ||
* @example | ||
* expect({ a: '1', b: 2 }).toEqual(expect.objectContaining({ a: '1' })) | ||
*/ | ||
objectContaining: <T = any>(expected: T) => any; | ||
/** | ||
* Matches if the received array contains all elements in the expected array. | ||
* | ||
* @example | ||
* expect(['a', 'b', 'c']).toEqual(expect.arrayContaining(['b', 'a'])); | ||
*/ | ||
arrayContaining: <T = unknown>(expected: Array<T>) => any; | ||
/** | ||
* Matches if the received string or regex matches the expected pattern. | ||
* | ||
* @example | ||
* expect('hello world').toEqual(expect.stringMatching(/^hello/)); | ||
* expect('hello world').toEqual(expect.stringMatching('hello')); | ||
*/ | ||
stringMatching: (expected: string | RegExp) => any; | ||
/** | ||
* Matches if the received number is within a certain precision of the expected number. | ||
* | ||
* @param precision - Optional decimal precision for comparison. Default is 2. | ||
* | ||
* @example | ||
* expect(10.45).toEqual(expect.closeTo(10.5, 1)); | ||
* expect(5.11).toEqual(expect.closeTo(5.12)); // with default precision | ||
*/ | ||
closeTo: (expected: number, precision?: number) => any; | ||
} | ||
interface JestAssertion<T = any> extends jest.Matchers<void, T> { | ||
/** | ||
* Used when you want to check that two objects have the same value. | ||
* This matcher recursively checks the equality of all fields, rather than checking for object identity. | ||
* | ||
* @example | ||
* expect(user).toEqual({ name: 'Alice', age: 30 }); | ||
*/ | ||
toEqual: <E>(expected: E) => void; | ||
/** | ||
* Use to test that objects have the same types as well as structure. | ||
* | ||
* @example | ||
* expect(user).toStrictEqual({ name: 'Alice', age: 30 }); | ||
*/ | ||
toStrictEqual: <E>(expected: E) => void; | ||
/** | ||
* Checks that a value is what you expect. It calls `Object.is` to compare values. | ||
* Don't use `toBe` with floating-point numbers. | ||
* | ||
* @example | ||
* expect(result).toBe(42); | ||
* expect(status).toBe(true); | ||
*/ | ||
toBe: <E>(expected: E) => void; | ||
/** | ||
* Check that a string matches a regular expression. | ||
* | ||
* @example | ||
* expect(message).toMatch(/hello/); | ||
* expect(greeting).toMatch('world'); | ||
*/ | ||
toMatch: (expected: string | RegExp) => void; | ||
/** | ||
* Used to check that a JavaScript object matches a subset of the properties of an object | ||
* | ||
* @example | ||
* expect(user).toMatchObject({ | ||
* name: 'Alice', | ||
* address: { city: 'Wonderland' } | ||
* }); | ||
*/ | ||
toMatchObject: <E extends object | any[]>(expected: E) => void; | ||
/** | ||
* Used when you want to check that an item is in a list. | ||
* For testing the items in the list, this uses `===`, a strict equality check. | ||
* | ||
* @example | ||
* expect(items).toContain('apple'); | ||
* expect(numbers).toContain(5); | ||
*/ | ||
toContain: <E>(item: E) => void; | ||
/** | ||
* Used when you want to check that an item is in a list. | ||
* For testing the items in the list, this matcher recursively checks the | ||
* equality of all fields, rather than checking for object identity. | ||
* | ||
* @example | ||
* expect(items).toContainEqual({ name: 'apple', quantity: 1 }); | ||
*/ | ||
toContainEqual: <E>(item: E) => void; | ||
/** | ||
* Use when you don't care what a value is, you just want to ensure a value | ||
* is true in a boolean context. In JavaScript, there are six falsy values: | ||
* `false`, `0`, `''`, `null`, `undefined`, and `NaN`. Everything else is truthy. | ||
* | ||
* @example | ||
* expect(user.isActive).toBeTruthy(); | ||
*/ | ||
toBeTruthy: () => void; | ||
/** | ||
* When you don't care what a value is, you just want to | ||
* ensure a value is false in a boolean context. | ||
* | ||
* @example | ||
* expect(user.isActive).toBeFalsy(); | ||
*/ | ||
toBeFalsy: () => void; | ||
/** | ||
* For comparing floating point numbers. | ||
* | ||
* @example | ||
* expect(score).toBeGreaterThan(10); | ||
*/ | ||
toBeGreaterThan: (num: number | bigint) => void; | ||
/** | ||
* For comparing floating point numbers. | ||
* | ||
* @example | ||
* expect(score).toBeGreaterThanOrEqual(10); | ||
*/ | ||
toBeGreaterThanOrEqual: (num: number | bigint) => void; | ||
/** | ||
* For comparing floating point numbers. | ||
* | ||
* @example | ||
* expect(score).toBeLessThan(10); | ||
*/ | ||
toBeLessThan: (num: number | bigint) => void; | ||
/** | ||
* For comparing floating point numbers. | ||
* | ||
* @example | ||
* expect(score).toBeLessThanOrEqual(10); | ||
*/ | ||
toBeLessThanOrEqual: (num: number | bigint) => void; | ||
/** | ||
* Used to check that a variable is NaN. | ||
* | ||
* @example | ||
* expect(value).toBeNaN(); | ||
*/ | ||
toBeNaN: () => void; | ||
/** | ||
* Used to check that a variable is undefined. | ||
* | ||
* @example | ||
* expect(value).toBeUndefined(); | ||
*/ | ||
toBeUndefined: () => void; | ||
/** | ||
* This is the same as `.toBe(null)` but the error messages are a bit nicer. | ||
* So use `.toBeNull()` when you want to check that something is null. | ||
* | ||
* @example | ||
* expect(value).toBeNull(); | ||
*/ | ||
toBeNull: () => void; | ||
/** | ||
* Ensure that a variable is not undefined. | ||
* | ||
* @example | ||
* expect(value).toBeDefined(); | ||
*/ | ||
toBeDefined: () => void; | ||
/** | ||
* Ensure that an object is an instance of a class. | ||
* This matcher uses `instanceof` underneath. | ||
* | ||
* @example | ||
* expect(new Date()).toBeInstanceOf(Date); | ||
*/ | ||
toBeInstanceOf: <E>(expected: E) => void; | ||
toBeCalledTimes: (times: number) => void; | ||
/** | ||
* Used to check that an object has a `.length` property | ||
* and it is set to a certain numeric value. | ||
* | ||
* @example | ||
* expect([1, 2, 3]).toHaveLength(3); | ||
* expect('hello').toHaveLength(5); | ||
*/ | ||
toHaveLength: (length: number) => void; | ||
/** | ||
* Use to check if a property at the specified path exists on an object. | ||
* For checking deeply nested properties, you may use dot notation or an array containing | ||
* the path segments for deep references. | ||
* | ||
* Optionally, you can provide a value to check if it matches the value present at the path | ||
* on the target object. This matcher uses 'deep equality' (like `toEqual()`) and recursively checks | ||
* the equality of all fields. | ||
* | ||
* @example | ||
* expect(user).toHaveProperty('address.city', 'New York'); | ||
* expect(config).toHaveProperty(['settings', 'theme'], 'dark'); | ||
*/ | ||
toHaveProperty: <E>(property: string | (string | number)[], value?: E) => void; | ||
/** | ||
* Using exact equality with floating point numbers is a bad idea. | ||
* Rounding means that intuitive things fail. | ||
* The default for `precision` is 2. | ||
* | ||
* @example | ||
* expect(price).toBeCloseTo(9.99, 2); | ||
*/ | ||
toBeCloseTo: (number: number, numDigits?: number) => void; | ||
/** | ||
* Ensures that a mock function is called an exact number of times. | ||
* | ||
* Also under the alias `expect.toBeCalledTimes`. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveBeenCalledTimes(2); | ||
*/ | ||
toHaveBeenCalledTimes: (times: number) => void; | ||
/** | ||
* Ensures that a mock function is called an exact number of times. | ||
* | ||
* Alias for `expect.toHaveBeenCalledTimes`. | ||
* | ||
* @example | ||
* expect(mockFunc).toBeCalledTimes(2); | ||
*/ | ||
toBeCalledTimes: (times: number) => void; | ||
/** | ||
* Ensures that a mock function is called. | ||
* | ||
* Also under the alias `expect.toBeCalled`. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveBeenCalled(); | ||
*/ | ||
toHaveBeenCalled: () => void; | ||
/** | ||
* Ensures that a mock function is called. | ||
* | ||
* Alias for `expect.toHaveBeenCalled`. | ||
* | ||
* @example | ||
* expect(mockFunc).toBeCalled(); | ||
*/ | ||
toBeCalled: () => void; | ||
/** | ||
* Ensure that a mock function is called with specific arguments. | ||
* | ||
* Also under the alias `expect.toBeCalledWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveBeenCalledWith('arg1', 42); | ||
*/ | ||
toHaveBeenCalledWith: <E extends any[]>(...args: E) => void; | ||
/** | ||
* Ensure that a mock function is called with specific arguments. | ||
* | ||
* Alias for `expect.toHaveBeenCalledWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).toBeCalledWith('arg1', 42); | ||
*/ | ||
toBeCalledWith: <E extends any[]>(...args: E) => void; | ||
/** | ||
* Ensure that a mock function is called with specific arguments on an Nth call. | ||
* | ||
* Also under the alias `expect.nthCalledWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveBeenNthCalledWith(2, 'secondArg'); | ||
*/ | ||
toHaveBeenNthCalledWith: <E extends any[]>(n: number, ...args: E) => void; | ||
/** | ||
* Ensure that a mock function is called with specific arguments on an Nth call. | ||
* | ||
* Alias for `expect.toHaveBeenNthCalledWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).nthCalledWith(2, 'secondArg'); | ||
*/ | ||
nthCalledWith: <E extends any[]>(nthCall: number, ...args: E) => void; | ||
/** | ||
* If you have a mock function, you can use `.toHaveBeenLastCalledWith` | ||
* to test what arguments it was last called with. | ||
* | ||
* Also under the alias `expect.lastCalledWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveBeenLastCalledWith('lastArg'); | ||
*/ | ||
toHaveBeenLastCalledWith: <E extends any[]>(...args: E) => void; | ||
/** | ||
* If you have a mock function, you can use `.lastCalledWith` | ||
* to test what arguments it was last called with. | ||
* | ||
* Alias for `expect.toHaveBeenLastCalledWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).lastCalledWith('lastArg'); | ||
*/ | ||
lastCalledWith: <E extends any[]>(...args: E) => void; | ||
/** | ||
* Used to test that a function throws when it is called. | ||
* | ||
* Also under the alias `expect.toThrowError`. | ||
* | ||
* @example | ||
* expect(() => functionWithError()).toThrow('Error message'); | ||
* expect(() => parseJSON('invalid')).toThrow(SyntaxError); | ||
*/ | ||
toThrow: (expected?: string | Constructable | RegExp | Error) => void; | ||
/** | ||
* Used to test that a function throws when it is called. | ||
* | ||
* Alias for `expect.toThrow`. | ||
* | ||
* @example | ||
* expect(() => functionWithError()).toThrowError('Error message'); | ||
* expect(() => parseJSON('invalid')).toThrowError(SyntaxError); | ||
*/ | ||
toThrowError: (expected?: string | Constructable | RegExp | Error) => void; | ||
/** | ||
* Use to test that the mock function successfully returned (i.e., did not throw an error) at least one time | ||
* | ||
* Alias for `expect.toHaveReturned`. | ||
* | ||
* @example | ||
* expect(mockFunc).toReturn(); | ||
*/ | ||
toReturn: () => void; | ||
/** | ||
* Use to test that the mock function successfully returned (i.e., did not throw an error) at least one time | ||
* | ||
* Also under the alias `expect.toReturn`. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveReturned(); | ||
*/ | ||
toHaveReturned: () => void; | ||
/** | ||
* Use to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times. | ||
* Any calls to the mock function that throw an error are not counted toward the number of times the function returned. | ||
* | ||
* Alias for `expect.toHaveReturnedTimes`. | ||
* | ||
* @example | ||
* expect(mockFunc).toReturnTimes(3); | ||
*/ | ||
toReturnTimes: (times: number) => void; | ||
/** | ||
* Use to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times. | ||
* Any calls to the mock function that throw an error are not counted toward the number of times the function returned. | ||
* | ||
* Also under the alias `expect.toReturnTimes`. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveReturnedTimes(3); | ||
*/ | ||
toHaveReturnedTimes: (times: number) => void; | ||
/** | ||
* Use to ensure that a mock function returned a specific value. | ||
* | ||
* Alias for `expect.toHaveReturnedWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).toReturnWith('returnValue'); | ||
*/ | ||
toReturnWith: <E>(value: E) => void; | ||
/** | ||
* Use to ensure that a mock function returned a specific value. | ||
* | ||
* Also under the alias `expect.toReturnWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveReturnedWith('returnValue'); | ||
*/ | ||
toHaveReturnedWith: <E>(value: E) => void; | ||
/** | ||
* Use to test the specific value that a mock function last returned. | ||
* If the last call to the mock function threw an error, then this matcher will fail | ||
* no matter what value you provided as the expected return value. | ||
* | ||
* Also under the alias `expect.lastReturnedWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveLastReturnedWith('lastValue'); | ||
*/ | ||
toHaveLastReturnedWith: <E>(value: E) => void; | ||
/** | ||
* Use to test the specific value that a mock function last returned. | ||
* If the last call to the mock function threw an error, then this matcher will fail | ||
* no matter what value you provided as the expected return value. | ||
* | ||
* Alias for `expect.toHaveLastReturnedWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).lastReturnedWith('lastValue'); | ||
*/ | ||
lastReturnedWith: <E>(value: E) => void; | ||
/** | ||
* Use to test the specific value that a mock function returned for the nth call. | ||
* If the nth call to the mock function threw an error, then this matcher will fail | ||
* no matter what value you provided as the expected return value. | ||
* | ||
* Also under the alias `expect.nthReturnedWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveNthReturnedWith(2, 'nthValue'); | ||
*/ | ||
toHaveNthReturnedWith: <E>(nthCall: number, value: E) => void; | ||
/** | ||
* Use to test the specific value that a mock function returned for the nth call. | ||
* If the nth call to the mock function threw an error, then this matcher will fail | ||
* no matter what value you provided as the expected return value. | ||
* | ||
* Alias for `expect.toHaveNthReturnedWith`. | ||
* | ||
* @example | ||
* expect(mockFunc).nthReturnedWith(2, 'nthValue'); | ||
*/ | ||
nthReturnedWith: <E>(nthCall: number, value: E) => void; | ||
@@ -160,11 +538,75 @@ } | ||
interface Assertion<T = any> extends VitestAssertion<Chai.Assertion, T>, JestAssertion<T> { | ||
/** | ||
* Ensures a value is of a specific type. | ||
* | ||
* @example | ||
* expect(value).toBeTypeOf('string'); | ||
* expect(number).toBeTypeOf('number'); | ||
*/ | ||
toBeTypeOf: (expected: 'bigint' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'undefined') => void; | ||
/** | ||
* Asserts that a mock function was called exactly once. | ||
* | ||
* @example | ||
* expect(mockFunc).toHaveBeenCalledOnce(); | ||
*/ | ||
toHaveBeenCalledOnce: () => void; | ||
/** | ||
* Checks that a value satisfies a custom matcher function. | ||
* | ||
* @param matcher - A function returning a boolean based on the custom condition | ||
* @param message - Optional custom error message on failure | ||
* | ||
* @example | ||
* expect(age).toSatisfy(val => val >= 18, 'Age must be at least 18'); | ||
*/ | ||
toSatisfy: <E>(matcher: (value: E) => boolean, message?: string) => void; | ||
/** | ||
* Checks that a promise resolves successfully at least once. | ||
* | ||
* @example | ||
* await expect(promise).toHaveResolved(); | ||
*/ | ||
toHaveResolved: () => void; | ||
/** | ||
* Checks that a promise resolves to a specific value. | ||
* | ||
* @example | ||
* await expect(promise).toHaveResolvedWith('success'); | ||
*/ | ||
toHaveResolvedWith: <E>(value: E) => void; | ||
/** | ||
* Ensures a promise resolves a specific number of times. | ||
* | ||
* @example | ||
* expect(mockAsyncFunc).toHaveResolvedTimes(3); | ||
*/ | ||
toHaveResolvedTimes: (times: number) => void; | ||
/** | ||
* Asserts that the last resolved value of a promise matches an expected value. | ||
* | ||
* @example | ||
* await expect(mockAsyncFunc).toHaveLastResolvedWith('finalResult'); | ||
*/ | ||
toHaveLastResolvedWith: <E>(value: E) => void; | ||
/** | ||
* Ensures a specific value was returned by a promise on the nth resolution. | ||
* | ||
* @example | ||
* await expect(mockAsyncFunc).toHaveNthResolvedWith(2, 'secondResult'); | ||
*/ | ||
toHaveNthResolvedWith: <E>(nthCall: number, value: E) => void; | ||
/** | ||
* Verifies that a promise resolves. | ||
* | ||
* @example | ||
* await expect(someAsyncFunc).resolves.toBe(42); | ||
*/ | ||
resolves: PromisifyAssertion<T>; | ||
/** | ||
* Verifies that a promise rejects. | ||
* | ||
* @example | ||
* await expect(someAsyncFunc).rejects.toThrow('error'); | ||
*/ | ||
rejects: PromisifyAssertion<T>; | ||
@@ -171,0 +613,0 @@ } |
@@ -911,5 +911,16 @@ import { getType, stringify, isObject, assertTypes } from '@vitest/utils'; | ||
function recordAsyncExpect(test, promise) { | ||
function createAssertionMessage(util, assertion, hasArgs) { | ||
const not = util.flag(assertion, "negate") ? "not." : ""; | ||
const name = `${util.flag(assertion, "_name")}(${hasArgs ? "expected" : ""})`; | ||
const promiseName = util.flag(assertion, "promise"); | ||
const promise = promiseName ? `.${promiseName}` : ""; | ||
return `expect(actual)${promise}.${not}${name}`; | ||
} | ||
function recordAsyncExpect(_test, promise, assertion, error) { | ||
const test = _test; | ||
if (test && promise instanceof Promise) { | ||
promise = promise.finally(() => { | ||
if (!test.promises) { | ||
return; | ||
} | ||
const index = test.promises.indexOf(promise); | ||
@@ -924,2 +935,30 @@ if (index !== -1) { | ||
test.promises.push(promise); | ||
let resolved = false; | ||
test.onFinished ?? (test.onFinished = []); | ||
test.onFinished.push(() => { | ||
var _a; | ||
if (!resolved) { | ||
const processor = ((_a = globalThis.__vitest_worker__) == null ? void 0 : _a.onFilterStackTrace) || ((s) => s || ""); | ||
const stack = processor(error.stack); | ||
console.warn([ | ||
`Promise returned by \`${assertion}\` was not awaited. `, | ||
"Vitest currently auto-awaits hanging assertions at the end of the test, but this will cause the test to fail in Vitest 3. ", | ||
"Please remember to await the assertion.\n", | ||
stack | ||
].join("")); | ||
} | ||
}); | ||
return { | ||
then(onFullfilled, onRejected) { | ||
resolved = true; | ||
return promise.then(onFullfilled, onRejected); | ||
}, | ||
catch(onRejected) { | ||
return promise.catch(onRejected); | ||
}, | ||
finally(onFinally) { | ||
return promise.finally(onFinally); | ||
}, | ||
[Symbol.toStringTag]: "Promise" | ||
}; | ||
} | ||
@@ -931,3 +970,5 @@ return promise; | ||
var _a; | ||
utils.flag(this, "_name", name); | ||
if (name !== "withTest") { | ||
utils.flag(this, "_name", name); | ||
} | ||
if (!utils.flag(this, "soft")) { | ||
@@ -1730,2 +1771,3 @@ return fn.apply(this, args); | ||
return (...args) => { | ||
utils.flag(this, "_name", key); | ||
const promise = obj.then( | ||
@@ -1751,3 +1793,8 @@ (value) => { | ||
); | ||
return recordAsyncExpect(test, promise); | ||
return recordAsyncExpect( | ||
test, | ||
promise, | ||
createAssertionMessage(utils, this, !!args.length), | ||
error | ||
); | ||
}; | ||
@@ -1786,2 +1833,3 @@ } | ||
return (...args) => { | ||
utils.flag(this, "_name", key); | ||
const promise = wrapper.then( | ||
@@ -1810,3 +1858,8 @@ (value) => { | ||
); | ||
return recordAsyncExpect(test, promise); | ||
return recordAsyncExpect( | ||
test, | ||
promise, | ||
createAssertionMessage(utils, this, !!args.length), | ||
error | ||
); | ||
}; | ||
@@ -1813,0 +1866,0 @@ } |
{ | ||
"name": "@vitest/expect", | ||
"type": "module", | ||
"version": "2.1.4", | ||
"version": "2.1.5", | ||
"description": "Jest's expect matchers as a Chai plugin", | ||
@@ -35,4 +35,4 @@ "license": "MIT", | ||
"tinyrainbow": "^1.2.0", | ||
"@vitest/spy": "2.1.4", | ||
"@vitest/utils": "2.1.4" | ||
"@vitest/utils": "2.1.5", | ||
"@vitest/spy": "2.1.5" | ||
}, | ||
@@ -42,3 +42,3 @@ "devDependencies": { | ||
"rollup-plugin-copy": "^3.5.0", | ||
"@vitest/runner": "2.1.4" | ||
"@vitest/runner": "2.1.5" | ||
}, | ||
@@ -45,0 +45,0 @@ "scripts": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
165487
2751
+ Added@vitest/pretty-format@2.1.5(transitive)
+ Added@vitest/spy@2.1.5(transitive)
+ Added@vitest/utils@2.1.5(transitive)
- Removed@vitest/pretty-format@2.1.4(transitive)
- Removed@vitest/spy@2.1.4(transitive)
- Removed@vitest/utils@2.1.4(transitive)
Updated@vitest/spy@2.1.5
Updated@vitest/utils@2.1.5