dev-api: add developer portal, OpenAPI spec, and Flatenbadet case study

- New /developers/ page with API docs, SDKs, pricing, use cases
- OpenAPI 3.0 spec for Orders, Missions, Photos, Analytics
- Case study: Glasskiosken i Flatenbadet — complete ROI analysis
- Updated /order/ with recurring missions and frequency dropdown
This commit is contained in:
Bernt
2026-07-14 15:27:33 +00:00
parent 3c522e39f0
commit 1a12fb870b
6296 changed files with 911440 additions and 55607 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-Present Vitest Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+17
View File
@@ -0,0 +1,17 @@
# @vitest/expect
Jest's expect matchers as a Chai plugin.
## Usage
```js
import * as chai from 'chai'
import { JestAsymmetricMatchers, JestChaiExpect, JestExtend } from '@vitest/expect'
// allows using expect.extend instead of chai.use to extend plugins
chai.use(JestExtend)
// adds all jest matchers to expect
chai.use(JestChaiExpect)
// adds asymmetric matchers like stringContaining, objectContaining
chai.use(JestAsymmetricMatchers)
```
+1968
View File
@@ -0,0 +1,1968 @@
// Type definitions for chai 4.3
// Project: http://chaijs.com/
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
// Andrew Brown <https://github.com/AGBrown>
// Olivier Chevet <https://github.com/olivr70>
// Matt Wistrand <https://github.com/mwistrand>
// Shaun Luttin <https://github.com/shaunluttin>
// Satana Charuwichitratana <https://github.com/micksatana>
// Erik Schierboom <https://github.com/ErikSchierboom>
// Bogdan Paranytsia <https://github.com/bparan>
// CXuesong <https://github.com/CXuesong>
// Joey Kilpatrick <https://github.com/joeykilpatrick>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 3.0
declare namespace Chai {
type Message = string | (() => string);
type ObjectProperty = string | symbol | number;
interface PathInfo {
parent: object;
name: string;
value?: any;
exists: boolean;
}
interface ErrorConstructor {
new(...args: any[]): Error;
}
interface ChaiUtils {
addChainableMethod(
// object to define the method on, e.g. chai.Assertion.prototype
ctx: object,
// method name
name: string,
// method itself; any arguments
method: (...args: any[]) => void,
// called when property is accessed
chainingBehavior?: () => void,
): void;
overwriteChainableMethod(
ctx: object,
name: string,
method: (...args: any[]) => void,
chainingBehavior?: () => void,
): void;
addLengthGuard(
fn: Function,
assertionName: string,
isChainable: boolean,
): void;
addMethod(ctx: object, name: string, method: Function): void;
addProperty(ctx: object, name: string, getter: () => any): void;
overwriteMethod(ctx: object, name: string, method: Function): void;
overwriteProperty(ctx: object, name: string, getter: () => any): void;
compareByInspect(a: object, b: object): -1 | 1;
expectTypes(obj: object, types: string[]): void;
flag(obj: object, key: string, value?: any): any;
getActual(obj: object, args: AssertionArgs): any;
getProperties(obj: object): string[];
getEnumerableProperties(obj: object): string[];
getOwnEnumerablePropertySymbols(obj: object): symbol[];
getOwnEnumerableProperties(obj: object): Array<string | symbol>;
getMessage(errorLike: Error | string): string;
getMessage(obj: any, args: AssertionArgs): string;
inspect(obj: any, showHidden?: boolean, depth?: number, colors?: boolean): string;
isProxyEnabled(): boolean;
objDisplay(obj: object): void;
proxify(obj: object, nonChainableMethodName: string): object;
test(obj: object, args: AssertionArgs): boolean;
transferFlags(assertion: Assertion, obj: object, includeAll?: boolean): void;
compatibleInstance(thrown: Error, errorLike: Error | ErrorConstructor): boolean;
compatibleConstructor(thrown: Error, errorLike: Error | ErrorConstructor): boolean;
compatibleMessage(thrown: Error, errMatcher: string | RegExp): boolean;
getConstructorName(constructorFn: Function): string;
getFuncName(constructorFn: Function): string | null;
// Reexports from pathval:
hasProperty(obj: object | undefined | null, name: ObjectProperty): boolean;
getPathInfo(obj: object, path: string): PathInfo;
getPathValue(obj: object, path: string): object | undefined;
}
type ChaiPlugin = (chai: ChaiStatic, utils: ChaiUtils) => void;
interface ChaiStatic {
expect: ExpectStatic;
should(): Should;
/**
* Provides a way to extend the internals of Chai
*/
use(fn: ChaiPlugin): ChaiStatic;
util: ChaiUtils;
assert: AssertStatic;
config: Config;
Assertion: AssertionStatic;
AssertionError: typeof AssertionError;
version: string;
}
export interface ExpectStatic {
(val: any, message?: string): Assertion;
fail(message?: string): never;
fail(actual: any, expected: any, message?: string, operator?: Operator): never;
}
export interface AssertStatic extends Assert {
}
// chai.Assertion.prototype.assert arguments
type AssertionArgs = [
// 'expression to be tested'
// This parameter is unused and the docs list its type as
// 'Philosophical', which is mentioned nowhere else in the source. Do
// with that what you will!
any,
Message, // message if value fails
Message, // message if negated value fails
any, // expected value
any?, // actual value
boolean?, // showDiff
];
export interface AssertionPrototype {
assert(...args: AssertionArgs): void;
_obj: any;
}
export interface AssertionStatic extends AssertionPrototype {
prototype: AssertionPrototype;
new(target: any, message?: string, ssfi?: Function, lockSsfi?: boolean): Assertion;
// Deprecated properties:
includeStack: boolean;
showDiff: boolean;
// Partials of functions on ChaiUtils:
addProperty(name: string, getter: (this: AssertionStatic) => any): void;
addMethod(name: string, method: (this: AssertionStatic, ...args: any[]) => any): void;
addChainableMethod(
name: string,
method: (this: AssertionStatic, ...args: any[]) => void,
chainingBehavior?: () => void,
): void;
overwriteProperty(name: string, getter: (this: AssertionStatic) => any): void;
overwriteMethod(name: string, method: (this: AssertionStatic, ...args: any[]) => any): void;
overwriteChainableMethod(
name: string,
method: (this: AssertionStatic, ...args: any[]) => void,
chainingBehavior?: () => void,
): void;
}
export type Operator = string; // "==" | "===" | ">" | ">=" | "<" | "<=" | "!=" | "!==";
export type OperatorComparable = boolean | null | number | string | undefined | Date;
interface ShouldAssertion {
equal(value1: any, value2: any, message?: string): void;
Throw: ShouldThrow;
throw: ShouldThrow;
exist(value: any, message?: string): void;
}
interface Should extends ShouldAssertion {
not: ShouldAssertion;
fail(message?: string): never;
fail(actual: any, expected: any, message?: string, operator?: Operator): never;
}
interface ShouldThrow {
(actual: Function, expected?: string | RegExp, message?: string): void;
(actual: Function, constructor: Error | Function, expected?: string | RegExp, message?: string): void;
}
interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
not: Assertion;
deep: Deep;
ordered: Ordered;
nested: Nested;
own: Own;
any: KeyFilter;
all: KeyFilter;
a: Assertion;
an: Assertion;
include: Include;
includes: Include;
contain: Include;
contains: Include;
ok: Assertion;
true: Assertion;
false: Assertion;
null: Assertion;
undefined: Assertion;
NaN: Assertion;
exist: Assertion;
empty: Assertion;
arguments: Assertion;
Arguments: Assertion;
finite: Assertion;
equal: Equal;
equals: Equal;
eq: Equal;
eql: Equal;
eqls: Equal;
property: Property;
ownProperty: Property;
haveOwnProperty: Property;
ownPropertyDescriptor: OwnPropertyDescriptor;
haveOwnPropertyDescriptor: OwnPropertyDescriptor;
length: Length;
lengthOf: Length;
match: Match;
matches: Match;
string(string: string, message?: string): Assertion;
keys: Keys;
key(string: string): Assertion;
throw: Throw;
throws: Throw;
Throw: Throw;
respondTo: RespondTo;
respondsTo: RespondTo;
itself: Assertion;
satisfy: Satisfy;
satisfies: Satisfy;
closeTo: CloseTo;
approximately: CloseTo;
members: Members;
increase: PropertyChange;
increases: PropertyChange;
decrease: PropertyChange;
decreases: PropertyChange;
change: PropertyChange;
changes: PropertyChange;
extensible: Assertion;
sealed: Assertion;
frozen: Assertion;
oneOf: OneOf;
}
interface LanguageChains {
to: Assertion;
be: Assertion;
been: Assertion;
is: Assertion;
that: Assertion;
which: Assertion;
and: Assertion;
has: Assertion;
have: Assertion;
with: Assertion;
at: Assertion;
of: Assertion;
same: Assertion;
but: Assertion;
does: Assertion;
}
interface NumericComparison {
above: NumberComparer;
gt: NumberComparer;
greaterThan: NumberComparer;
least: NumberComparer;
gte: NumberComparer;
greaterThanOrEqual: NumberComparer;
below: NumberComparer;
lt: NumberComparer;
lessThan: NumberComparer;
most: NumberComparer;
lte: NumberComparer;
lessThanOrEqual: NumberComparer;
within(start: number, finish: number, message?: string): Assertion;
within(start: Date, finish: Date, message?: string): Assertion;
}
interface NumberComparer {
(value: number | Date, message?: string): Assertion;
}
interface TypeComparison {
(type: string, message?: string): Assertion;
instanceof: InstanceOf;
instanceOf: InstanceOf;
}
interface InstanceOf {
(constructor: any, message?: string): Assertion;
}
interface CloseTo {
(expected: number, delta: number, message?: string): Assertion;
}
interface Nested {
include: Include;
includes: Include;
contain: Include;
contains: Include;
property: Property;
members: Members;
}
interface Own {
include: Include;
includes: Include;
contain: Include;
contains: Include;
property: Property;
}
interface Deep extends KeyFilter {
be: Assertion;
equal: Equal;
equals: Equal;
eq: Equal;
include: Include;
includes: Include;
contain: Include;
contains: Include;
property: Property;
ordered: Ordered;
nested: Nested;
oneOf: OneOf;
own: Own;
}
interface Ordered {
members: Members;
}
interface KeyFilter {
keys: Keys;
members: Members;
}
interface Equal {
(value: any, message?: string): Assertion;
}
interface Property {
(name: string | symbol, value: any, message?: string): Assertion;
(name: string | symbol, message?: string): Assertion;
}
interface OwnPropertyDescriptor {
(name: string | symbol, descriptor: PropertyDescriptor, message?: string): Assertion;
(name: string | symbol, message?: string): Assertion;
}
interface Length extends LanguageChains, NumericComparison {
(length: number, message?: string): Assertion;
}
interface Include {
(value: any, message?: string): Assertion;
keys: Keys;
deep: Deep;
ordered: Ordered;
members: Members;
any: KeyFilter;
all: KeyFilter;
oneOf: OneOf;
}
interface OneOf {
(list: ReadonlyArray<unknown>, message?: string): Assertion;
}
interface Match {
(regexp: RegExp, message?: string): Assertion;
}
interface Keys {
(...keys: string[]): Assertion;
(keys: ReadonlyArray<any> | Object): Assertion;
}
interface Throw {
(expected?: string | RegExp, message?: string): Assertion;
(constructor: Error | Function, expected?: string | RegExp, message?: string): Assertion;
}
interface RespondTo {
(method: string, message?: string): Assertion;
}
interface Satisfy {
(matcher: Function, message?: string): Assertion;
}
interface Members {
(set: ReadonlyArray<any>, message?: string): Assertion;
}
interface PropertyChange {
(object: Object, property?: string, message?: string): DeltaAssertion;
}
interface DeltaAssertion extends Assertion {
by(delta: number, msg?: string): Assertion;
}
export interface Assert {
/**
* @param expression Expression to test for truthiness.
* @param message Message to display on error.
*/
(expression: any, message?: string): asserts expression;
/**
* Throws a failure.
*
* @param message Message to display on error.
* @remarks Node.js assert module-compatible.
*/
fail(message?: string): never;
/**
* Throws a failure.
*
* T Type of the objects.
* @param actual Actual value.
* @param expected Potential expected value.
* @param message Message to display on error.
* @param operator Comparison operator, if not strict equality.
* @remarks Node.js assert module-compatible.
*/
fail<T>(actual: T, expected: T, message?: string, operator?: Operator): never;
/**
* Asserts that object is truthy.
*
* T Type of object.
* @param object Object to test.
* @param message Message to display on error.
*/
isOk<T>(value: T, message?: string): void;
/**
* Asserts that object is truthy.
*
* T Type of object.
* @param object Object to test.
* @param message Message to display on error.
*/
ok<T>(value: T, message?: string): void;
/**
* Asserts that object is falsy.
*
* T Type of object.
* @param object Object to test.
* @param message Message to display on error.
*/
isNotOk<T>(value: T, message?: string): void;
/**
* Asserts that object is falsy.
*
* T Type of object.
* @param object Object to test.
* @param message Message to display on error.
*/
notOk<T>(value: T, message?: string): void;
/**
* Asserts non-strict equality (==) of actual and expected.
*
* T Type of the objects.
* @param actual Actual value.
* @param expected Potential expected value.
* @param message Message to display on error.
*/
equal<T>(actual: T, expected: T, message?: string): void;
/**
* Asserts non-strict inequality (!=) of actual and expected.
*
* T Type of the objects.
* @param actual Actual value.
* @param expected Potential expected value.
* @param message Message to display on error.
*/
notEqual<T>(actual: T, expected: T, message?: string): void;
/**
* Asserts strict equality (===) of actual and expected.
*
* T Type of the objects.
* @param actual Actual value.
* @param expected Potential expected value.
* @param message Message to display on error.
*/
strictEqual<T>(actual: T, expected: T, message?: string): void;
/**
* Asserts strict inequality (!==) of actual and expected.
*
* T Type of the objects.
* @param actual Actual value.
* @param expected Potential expected value.
* @param message Message to display on error.
*/
notStrictEqual<T>(actual: T, expected: T, message?: string): void;
/**
* Asserts that actual is deeply equal to expected.
*
* T Type of the objects.
* @param actual Actual value.
* @param expected Potential expected value.
* @param message Message to display on error.
*/
deepEqual<T>(actual: T, expected: T, message?: string): void;
/**
* Asserts that actual is not deeply equal to expected.
*
* T Type of the objects.
* @param actual Actual value.
* @param expected Potential expected value.
* @param message Message to display on error.
*/
notDeepEqual<T>(actual: T, expected: T, message?: string): void;
/**
* Alias to deepEqual
*
* T Type of the objects.
* @param actual Actual value.
* @param expected Potential expected value.
* @param message Message to display on error.
*/
deepStrictEqual<T>(actual: T, expected: T, message?: string): void;
/**
* Asserts valueToCheck is strictly greater than (>) valueToBeAbove.
*
* @param valueToCheck Actual value.
* @param valueToBeAbove Minimum Potential expected value.
* @param message Message to display on error.
*/
isAbove(valueToCheck: number, valueToBeAbove: number, message?: string): void;
/**
* Asserts valueToCheck is greater than or equal to (>=) valueToBeAtLeast.
*
* @param valueToCheck Actual value.
* @param valueToBeAtLeast Minimum Potential expected value.
* @param message Message to display on error.
*/
isAtLeast(valueToCheck: number, valueToBeAtLeast: number, message?: string): void;
/**
* Asserts valueToCheck is strictly less than (<) valueToBeBelow.
*
* @param valueToCheck Actual value.
* @param valueToBeBelow Minimum Potential expected value.
* @param message Message to display on error.
*/
isBelow(valueToCheck: number, valueToBeBelow: number, message?: string): void;
/**
* Asserts valueToCheck is less than or equal to (<=) valueToBeAtMost.
*
* @param valueToCheck Actual value.
* @param valueToBeAtMost Minimum Potential expected value.
* @param message Message to display on error.
*/
isAtMost(valueToCheck: number, valueToBeAtMost: number, message?: string): void;
/**
* Asserts that value is true.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isTrue<T>(value: T, message?: string): void;
/**
* Asserts that value is false.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isFalse<T>(value: T, message?: string): void;
/**
* Asserts that value is not true.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNotTrue<T>(value: T, message?: string): void;
/**
* Asserts that value is not false.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNotFalse<T>(value: T, message?: string): void;
/**
* Asserts that value is null.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNull<T>(value: T, message?: string): void;
/**
* Asserts that value is not null.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNotNull<T>(value: T, message?: string): void;
/**
* Asserts that value is NaN.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNaN<T>(value: T, message?: string): void;
/**
* Asserts that value is not NaN.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNotNaN<T>(value: T, message?: string): void;
/**
* Asserts that the target is neither null nor undefined.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
exists<T>(value: T, message?: string): void;
/**
* Asserts that the target is either null or undefined.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
notExists<T>(value: T, message?: string): void;
/**
* Asserts that value is undefined.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isUndefined<T>(value: T, message?: string): void;
/**
* Asserts that value is not undefined.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isDefined<T>(value: T, message?: string): void;
/**
* Asserts that value is a function.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isFunction<T>(value: T, message?: string): void;
/**
* Asserts that value is not a function.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNotFunction<T>(value: T, message?: string): void;
/**
* Asserts that value is an object of type 'Object'
* (as revealed by Object.prototype.toString).
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
* @remarks The assertion does not match subclassed objects.
*/
isObject<T>(value: T, message?: string): void;
/**
* Asserts that value is not an object of type 'Object'
* (as revealed by Object.prototype.toString).
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNotObject<T>(value: T, message?: string): void;
/**
* Asserts that value is an array.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isArray<T>(value: T, message?: string): void;
/**
* Asserts that value is not an array.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNotArray<T>(value: T, message?: string): void;
/**
* Asserts that value is a string.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isString<T>(value: T, message?: string): void;
/**
* Asserts that value is not a string.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNotString<T>(value: T, message?: string): void;
/**
* Asserts that value is a number.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNumber<T>(value: T, message?: string): void;
/**
* Asserts that value is not a number.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNotNumber<T>(value: T, message?: string): void;
/**
* Asserts that value is a finite number.
* Unlike `.isNumber`, this will fail for `NaN` and `Infinity`.
*
* T Type of value
* @param value Actual value
* @param message Message to display on error.
*/
isFinite<T>(value: T, message?: string): void;
/**
* Asserts that value is a boolean.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isBoolean<T>(value: T, message?: string): void;
/**
* Asserts that value is not a boolean.
*
* T Type of value.
* @param value Actual value.
* @param message Message to display on error.
*/
isNotBoolean<T>(value: T, message?: string): void;
/**
* Asserts that value's type is name, as determined by Object.prototype.toString.
*
* T Type of value.
* @param value Actual value.
* @param name Potential expected type name of value.
* @param message Message to display on error.
*/
typeOf<T>(value: T, name: string, message?: string): void;
/**
* Asserts that value's type is not name, as determined by Object.prototype.toString.
*
* T Type of value.
* @param value Actual value.
* @param name Potential expected type name of value.
* @param message Message to display on error.
*/
notTypeOf<T>(value: T, name: string, message?: string): void;
/**
* Asserts that value is an instance of constructor.
*
* T Type of value.
* @param value Actual value.
* @param constructor Potential expected contructor of value.
* @param message Message to display on error.
*/
instanceOf<T>(value: T, constructor: Function, message?: string): void;
/**
* Asserts that value is not an instance of constructor.
*
* T Type of value.
* @param value Actual value.
* @param constructor Potential expected contructor of value.
* @param message Message to display on error.
*/
notInstanceOf<T>(value: T, type: Function, message?: string): void;
/**
* Asserts that haystack includes needle.
*
* @param haystack Container string.
* @param needle Potential substring of haystack.
* @param message Message to display on error.
*/
include(haystack: string, needle: string, message?: string): void;
/**
* Asserts that haystack includes needle.
*
* T Type of values in haystack.
* @param haystack Container array, set or map.
* @param needle Potential value contained in haystack.
* @param message Message to display on error.
*/
include<T>(
haystack: ReadonlyArray<T> | ReadonlySet<T> | ReadonlyMap<any, T>,
needle: T,
message?: string,
): void;
/**
* Asserts that haystack includes needle.
*
* T Type of values in haystack.
* @param haystack WeakSet container.
* @param needle Potential value contained in haystack.
* @param message Message to display on error.
*/
include<T extends object>(haystack: WeakSet<T>, needle: T, message?: string): void;
/**
* Asserts that haystack includes needle.
*
* T Type of haystack.
* @param haystack Object.
* @param needle Potential subset of the haystack's properties.
* @param message Message to display on error.
*/
include<T>(haystack: T, needle: Partial<T>, message?: string): void;
/**
* Asserts that haystack does not includes needle.
*
* @param haystack Container string.
* @param needle Potential substring of haystack.
* @param message Message to display on error.
*/
notInclude(haystack: string, needle: string, message?: string): void;
/**
* Asserts that haystack does not includes needle.
*
* T Type of values in haystack.
* @param haystack Container array, set or map.
* @param needle Potential value contained in haystack.
* @param message Message to display on error.
*/
notInclude<T>(
haystack: ReadonlyArray<T> | ReadonlySet<T> | ReadonlyMap<any, T>,
needle: T,
message?: string,
): void;
/**
* Asserts that haystack does not includes needle.
*
* T Type of values in haystack.
* @param haystack WeakSet container.
* @param needle Potential value contained in haystack.
* @param message Message to display on error.
*/
notInclude<T extends object>(haystack: WeakSet<T>, needle: T, message?: string): void;
/**
* Asserts that haystack does not includes needle.
*
* T Type of haystack.
* @param haystack Object.
* @param needle Potential subset of the haystack's properties.
* @param message Message to display on error.
*/
notInclude<T>(haystack: T, needle: Partial<T>, message?: string): void;
/**
* Asserts that haystack includes needle. Deep equality is used.
*
* @param haystack Container string.
* @param needle Potential substring of haystack.
* @param message Message to display on error.
*
* @deprecated Does not have any effect on string. Use {@link Assert#include} instead.
*/
deepInclude(haystack: string, needle: string, message?: string): void;
/**
* Asserts that haystack includes needle. Deep equality is used.
*
* T Type of values in haystack.
* @param haystack Container array, set or map.
* @param needle Potential value contained in haystack.
* @param message Message to display on error.
*/
deepInclude<T>(
haystack: ReadonlyArray<T> | ReadonlySet<T> | ReadonlyMap<any, T>,
needle: T,
message?: string,
): void;
/**
* Asserts that haystack does not includes needle.
*
* T Type of haystack.
* @param haystack Object.
* @param needle Potential subset of the haystack's properties.
* @param message Message to display on error.
*/
deepInclude<T>(haystack: T, needle: T extends WeakSet<any> ? never : Partial<T>, message?: string): void;
/**
* Asserts that haystack does not includes needle. Deep equality is used.
*
* @param haystack Container string.
* @param needle Potential substring of haystack.
* @param message Message to display on error.
*
* @deprecated Does not have any effect on string. Use {@link Assert#notInclude} instead.
*/
notDeepInclude(haystack: string, needle: string, message?: string): void;
/**
* Asserts that haystack does not includes needle. Deep equality is used.
*
* T Type of values in haystack.
* @param haystack Container array, set or map.
* @param needle Potential value contained in haystack.
* @param message Message to display on error.
*/
notDeepInclude<T>(
haystack: ReadonlyArray<T> | ReadonlySet<T> | ReadonlyMap<any, T>,
needle: T,
message?: string,
): void;
/**
* Asserts that haystack does not includes needle. Deep equality is used.
*
* T Type of haystack.
* @param haystack Object.
* @param needle Potential subset of the haystack's properties.
* @param message Message to display on error.
*/
notDeepInclude<T>(haystack: T, needle: T extends WeakSet<any> ? never : Partial<T>, message?: string): void;
/**
* Asserts that haystack includes needle. Can be used to assert the inclusion of a subset of properties in an object.
*
* Enables the use of dot- and bracket-notation for referencing nested properties.
* [] and . in property names can be escaped using double backslashes.Asserts that haystack includes needle.
* Can be used to assert the inclusion of a subset of properties in an object.
* Enables the use of dot- and bracket-notation for referencing nested properties.
* [] and . in property names can be escaped using double backslashes.
*
* @param haystack
* @param needle
* @param message Message to display on error.
*/
nestedInclude(haystack: any, needle: any, message?: string): void;
/**
* Asserts that haystack does not include needle. Can be used to assert the absence of a subset of properties in an object.
*
* Enables the use of dot- and bracket-notation for referencing nested properties.
* [] and . in property names can be escaped using double backslashes.Asserts that haystack includes needle.
* Can be used to assert the inclusion of a subset of properties in an object.
* Enables the use of dot- and bracket-notation for referencing nested properties.
* [] and . in property names can be escaped using double backslashes.
*
* @param haystack
* @param needle
* @param message Message to display on error.
*/
notNestedInclude(haystack: any, needle: any, message?: string): void;
/**
* Asserts that haystack includes needle. Can be used to assert the inclusion of a subset of properties in an object while checking for deep equality
*
* Enables the use of dot- and bracket-notation for referencing nested properties.
* [] and . in property names can be escaped using double backslashes.Asserts that haystack includes needle.
* Can be used to assert the inclusion of a subset of properties in an object.
* Enables the use of dot- and bracket-notation for referencing nested properties.
* [] and . in property names can be escaped using double backslashes.
*
* @param haystack
* @param needle
* @param message Message to display on error.
*/
deepNestedInclude(haystack: any, needle: any, message?: string): void;
/**
* Asserts that haystack does not include needle. Can be used to assert the absence of a subset of properties in an object while checking for deep equality.
*
* Enables the use of dot- and bracket-notation for referencing nested properties.
* [] and . in property names can be escaped using double backslashes.Asserts that haystack includes needle.
* Can be used to assert the inclusion of a subset of properties in an object.
* Enables the use of dot- and bracket-notation for referencing nested properties.
* [] and . in property names can be escaped using double backslashes.
*
* @param haystack
* @param needle
* @param message Message to display on error.
*/
notDeepNestedInclude(haystack: any, needle: any, message?: string): void;
/**
* Asserts that haystack includes needle. Can be used to assert the inclusion of a subset of properties in an object while ignoring inherited properties.
*
* @param haystack
* @param needle
* @param message Message to display on error.
*/
ownInclude(haystack: any, needle: any, message?: string): void;
/**
* Asserts that haystack includes needle. Can be used to assert the absence of a subset of properties in an object while ignoring inherited properties.
*
* @param haystack
* @param needle
* @param message Message to display on error.
*/
notOwnInclude(haystack: any, needle: any, message?: string): void;
/**
* Asserts that haystack includes needle. Can be used to assert the inclusion of a subset of properties in an object while ignoring inherited properties and checking for deep
*
* @param haystack
* @param needle
* @param message Message to display on error.
*/
deepOwnInclude(haystack: any, needle: any, message?: string): void;
/**
* Asserts that haystack includes needle. Can be used to assert the absence of a subset of properties in an object while ignoring inherited properties and checking for deep equality.
*
* @param haystack
* @param needle
* @param message Message to display on error.
*/
notDeepOwnInclude(haystack: any, needle: any, message?: string): void;
/**
* Asserts that value matches the regular expression regexp.
*
* @param value Actual value.
* @param regexp Potential match of value.
* @param message Message to display on error.
*/
match(value: string, regexp: RegExp, message?: string): void;
/**
* Asserts that value does not match the regular expression regexp.
*
* @param value Actual value.
* @param regexp Potential match of value.
* @param message Message to display on error.
*/
notMatch(expected: any, regexp: RegExp, message?: string): void;
/**
* Asserts that object has a property named by property.
*
* T Type of object.
* @param object Container object.
* @param property Potential contained property of object.
* @param message Message to display on error.
*/
property<T>(object: T, property: string, /* keyof T */ message?: string): void;
/**
* Asserts that object has a property named by property.
*
* T Type of object.
* @param object Container object.
* @param property Potential contained property of object.
* @param message Message to display on error.
*/
notProperty<T>(object: T, property: string, /* keyof T */ message?: string): void;
/**
* Asserts that object has a property named by property, which can be a string
* using dot- and bracket-notation for deep reference.
*
* T Type of object.
* @param object Container object.
* @param property Potential contained property of object.
* @param message Message to display on error.
*/
deepProperty<T>(object: T, property: string, message?: string): void;
/**
* Asserts that object does not have a property named by property, which can be a
* string using dot- and bracket-notation for deep reference.
*
* T Type of object.
* @param object Container object.
* @param property Potential contained property of object.
* @param message Message to display on error.
*/
notDeepProperty<T>(object: T, property: string, message?: string): void;
/**
* Asserts that object has a property named by property with value given by value.
*
* T Type of object.
* V Type of value.
* @param object Container object.
* @param property Potential contained property of object.
* @param value Potential expected property value.
* @param message Message to display on error.
*/
propertyVal<T, V>(object: T, property: string, /* keyof T */ value: V, message?: string): void;
/**
* Asserts that object has a property named by property with value given by value.
*
* T Type of object.
* V Type of value.
* @param object Container object.
* @param property Potential contained property of object.
* @param value Potential expected property value.
* @param message Message to display on error.
*/
notPropertyVal<T, V>(object: T, property: string, /* keyof T */ value: V, message?: string): void;
/**
* Asserts that object has a property named by property, which can be a string
* using dot- and bracket-notation for deep reference.
*
* T Type of object.
* V Type of value.
* @param object Container object.
* @param property Potential contained property of object.
* @param value Potential expected property value.
* @param message Message to display on error.
*/
deepPropertyVal<T, V>(object: T, property: string, value: V, message?: string): void;
/**
* Asserts that object does not have a property named by property, which can be a
* string using dot- and bracket-notation for deep reference.
*
* T Type of object.
* V Type of value.
* @param object Container object.
* @param property Potential contained property of object.
* @param value Potential expected property value.
* @param message Message to display on error.
*/
notDeepPropertyVal<T, V>(object: T, property: string, value: V, message?: string): void;
/**
* Asserts that object has a length property with the expected value.
*
* T Type of object.
* @param object Container object.
* @param length Potential expected length of object.
* @param message Message to display on error.
*/
lengthOf<T extends { readonly length?: number | undefined }>(object: T, length: number, message?: string): void;
/**
* Asserts that fn will throw an error.
*
* @param fn Function that may throw.
* @param errMsgMatcher Expected error message matcher.
* @param ignored Ignored parameter.
* @param message Message to display on error.
*/
throw(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void;
/**
* Asserts that fn will throw an error.
*
* @param fn Function that may throw.
* @param errorLike Expected error constructor or error instance.
* @param errMsgMatcher Expected error message matcher.
* @param message Message to display on error.
*/
throw(
fn: () => void,
errorLike?: ErrorConstructor | Error | null,
errMsgMatcher?: RegExp | string | null,
message?: string,
): void;
/**
* Asserts that fn will throw an error.
*
* @param fn Function that may throw.
* @param errMsgMatcher Expected error message matcher.
* @param ignored Ignored parameter.
* @param message Message to display on error.
*/
throws(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void;
/**
* Asserts that fn will throw an error.
*
* @param fn Function that may throw.
* @param errorLike Expected error constructor or error instance.
* @param errMsgMatcher Expected error message matcher.
* @param message Message to display on error.
*/
throws(
fn: () => void,
errorLike?: ErrorConstructor | Error | null,
errMsgMatcher?: RegExp | string | null,
message?: string,
): void;
/**
* Asserts that fn will throw an error.
*
* @param fn Function that may throw.
* @param errMsgMatcher Expected error message matcher.
* @param ignored Ignored parameter.
* @param message Message to display on error.
*/
Throw(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void;
/**
* Asserts that fn will throw an error.
*
* @param fn Function that may throw.
* @param errorLike Expected error constructor or error instance.
* @param errMsgMatcher Expected error message matcher.
* @param message Message to display on error.
*/
Throw(
fn: () => void,
errorLike?: ErrorConstructor | Error | null,
errMsgMatcher?: RegExp | string | null,
message?: string,
): void;
/**
* Asserts that fn will not throw an error.
*
* @param fn Function that may throw.
* @param errMsgMatcher Expected error message matcher.
* @param ignored Ignored parameter.
* @param message Message to display on error.
*/
doesNotThrow(fn: () => void, errMsgMatcher?: RegExp | string, ignored?: any, message?: string): void;
/**
* Asserts that fn will not throw an error.
*
* @param fn Function that may throw.
* @param errorLike Expected error constructor or error instance.
* @param errMsgMatcher Expected error message matcher.
* @param message Message to display on error.
*/
doesNotThrow(
fn: () => void,
errorLike?: ErrorConstructor | Error | null,
errMsgMatcher?: RegExp | string | null,
message?: string,
): void;
/**
* Compares two values using operator.
*
* @param val1 Left value during comparison.
* @param operator Comparison operator.
* @param val2 Right value during comparison.
* @param message Message to display on error.
*/
operator(val1: OperatorComparable, operator: Operator, val2: OperatorComparable, message?: string): void;
/**
* Asserts that the target is equal to expected, to within a +/- delta range.
*
* @param actual Actual value
* @param expected Potential expected value.
* @param delta Maximum differenced between values.
* @param message Message to display on error.
*/
closeTo(actual: number, expected: number, delta: number, message?: string): void;
/**
* Asserts that the target is equal to expected, to within a +/- delta range.
*
* @param actual Actual value
* @param expected Potential expected value.
* @param delta Maximum differenced between values.
* @param message Message to display on error.
*/
approximately(act: number, exp: number, delta: number, message?: string): void;
/**
* Asserts that set1 and set2 have the same members. Order is not take into account.
*
* T Type of set values.
* @param set1 Actual set of values.
* @param set2 Potential expected set of values.
* @param message Message to display on error.
*/
sameMembers<T>(set1: T[], set2: T[], message?: string): void;
/**
* Asserts that set1 and set2 have the same members using deep equality checking.
* Order is not take into account.
*
* T Type of set values.
* @param set1 Actual set of values.
* @param set2 Potential expected set of values.
* @param message Message to display on error.
*/
sameDeepMembers<T>(set1: T[], set2: T[], message?: string): void;
/**
* Asserts that set1 and set2 have the same members in the same order.
* Uses a strict equality check (===).
*
* T Type of set values.
* @param set1 Actual set of values.
* @param set2 Potential expected set of values.
* @param message Message to display on error.
*/
sameOrderedMembers<T>(set1: T[], set2: T[], message?: string): void;
/**
* Asserts that set1 and set2 dont have the same members in the same order.
* Uses a strict equality check (===).
*
* T Type of set values.
* @param set1 Actual set of values.
* @param set2 Potential expected set of values.
* @param message Message to display on error.
*/
notSameOrderedMembers<T>(set1: T[], set2: T[], message?: string): void;
/**
* Asserts that set1 and set2 have the same members in the same order.
* Uses a deep equality check.
*
* T Type of set values.
* @param set1 Actual set of values.
* @param set2 Potential expected set of values.
* @param message Message to display on error.
*/
sameDeepOrderedMembers<T>(set1: T[], set2: T[], message?: string): void;
/**
* Asserts that set1 and set2 dont have the same members in the same order.
* Uses a deep equality check.
*
* T Type of set values.
* @param set1 Actual set of values.
* @param set2 Potential expected set of values.
* @param message Message to display on error.
*/
notSameDeepOrderedMembers<T>(set1: T[], set2: T[], message?: string): void;
/**
* Asserts that subset is included in superset in the same order beginning with the first element in superset.
* Uses a strict equality check (===).
*
* T Type of set values.
* @param superset Actual set of values.
* @param subset Potential contained set of values.
* @param message Message to display on error.
*/
includeOrderedMembers<T>(superset: T[], subset: T[], message?: string): void;
/**
* Asserts that subset isnt included in superset in the same order beginning with the first element in superset.
* Uses a strict equality check (===).
*
* T Type of set values.
* @param superset Actual set of values.
* @param subset Potential contained set of values.
* @param message Message to display on error.
*/
notIncludeOrderedMembers<T>(superset: T[], subset: T[], message?: string): void;
/**
* Asserts that subset is included in superset in the same order beginning with the first element in superset.
* Uses a deep equality check.
*
* T Type of set values.
* @param superset Actual set of values.
* @param subset Potential contained set of values.
* @param message Message to display on error.
*/
includeDeepOrderedMembers<T>(superset: T[], subset: T[], message?: string): void;
/**
* Asserts that subset isnt included in superset in the same order beginning with the first element in superset.
* Uses a deep equality check.
*
* T Type of set values.
* @param superset Actual set of values.
* @param subset Potential contained set of values.
* @param message Message to display on error.
*/
notIncludeDeepOrderedMembers<T>(superset: T[], subset: T[], message?: string): void;
/**
* Asserts that subset is included in superset. Order is not take into account.
*
* T Type of set values.
* @param superset Actual set of values.
* @param subset Potential contained set of values.
* @param message Message to display on error.
*/
includeMembers<T>(superset: T[], subset: T[], message?: string): void;
/**
* Asserts that subset isnt included in superset in any order.
* Uses a strict equality check (===). Duplicates are ignored.
*
* T Type of set values.
* @param superset Actual set of values.
* @param subset Potential not contained set of values.
* @param message Message to display on error.
*/
notIncludeMembers<T>(superset: T[], subset: T[], message?: string): void;
/**
* Asserts that subset is included in superset using deep equality checking.
* Order is not take into account.
*
* T Type of set values.
* @param superset Actual set of values.
* @param subset Potential contained set of values.
* @param message Message to display on error.
*/
includeDeepMembers<T>(superset: T[], subset: T[], message?: string): void;
/**
* Asserts that non-object, non-array value inList appears in the flat array list.
*
* T Type of list values.
* @param inList Value expected to be in the list.
* @param list List of values.
* @param message Message to display on error.
*/
oneOf<T>(inList: T, list: T[], message?: string): void;
/**
* Asserts that a function changes the value of a property.
*
* T Type of object.
* @param modifier Function to run.
* @param object Container object.
* @param property Property of object expected to be modified.
* @param message Message to display on error.
*/
changes<T>(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void;
/**
* Asserts that a function does not change the value of a property.
*
* T Type of object.
* @param modifier Function to run.
* @param object Container object.
* @param property Property of object expected not to be modified.
* @param message Message to display on error.
*/
doesNotChange<T>(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void;
/**
* Asserts that a function increases an object property.
*
* T Type of object.
* @param modifier Function to run.
* @param object Container object.
* @param property Property of object expected to be increased.
* @param message Message to display on error.
*/
increases<T>(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void;
/**
* Asserts that a function does not increase an object property.
*
* T Type of object.
* @param modifier Function to run.
* @param object Container object.
* @param property Property of object expected not to be increased.
* @param message Message to display on error.
*/
doesNotIncrease<T>(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void;
/**
* Asserts that a function decreases an object property.
*
* T Type of object.
* @param modifier Function to run.
* @param object Container object.
* @param property Property of object expected to be decreased.
* @param message Message to display on error.
*/
decreases<T>(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void;
/**
* Asserts that a function does not decrease an object property.
*
* T Type of object.
* @param modifier Function to run.
* @param object Container object.
* @param property Property of object expected not to be decreased.
* @param message Message to display on error.
*/
doesNotDecrease<T>(modifier: Function, object: T, property: string, /* keyof T */ message?: string): void;
/**
* Asserts if value is not a false value, and throws if it is a true value.
*
* T Type of object.
* @param object Actual value.
* @param message Message to display on error.
* @remarks This is added to allow for chai to be a drop-in replacement for
* Nodes assert class.
*/
ifError<T>(object: T, message?: string): void;
/**
* Asserts that object is extensible (can have new properties added to it).
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
isExtensible<T>(object: T, message?: string): void;
/**
* Asserts that object is extensible (can have new properties added to it).
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
extensible<T>(object: T, message?: string): void;
/**
* Asserts that object is not extensible.
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
isNotExtensible<T>(object: T, message?: string): void;
/**
* Asserts that object is not extensible.
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
notExtensible<T>(object: T, message?: string): void;
/**
* Asserts that object is sealed (can have new properties added to it
* and its existing properties cannot be removed).
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
isSealed<T>(object: T, message?: string): void;
/**
* Asserts that object is sealed (can have new properties added to it
* and its existing properties cannot be removed).
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
sealed<T>(object: T, message?: string): void;
/**
* Asserts that object is not sealed.
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
isNotSealed<T>(object: T, message?: string): void;
/**
* Asserts that object is not sealed.
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
notSealed<T>(object: T, message?: string): void;
/**
* Asserts that object is frozen (cannot have new properties added to it
* and its existing properties cannot be removed).
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
isFrozen<T>(object: T, message?: string): void;
/**
* Asserts that object is frozen (cannot have new properties added to it
* and its existing properties cannot be removed).
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
frozen<T>(object: T, message?: string): void;
/**
* Asserts that object is not frozen (cannot have new properties added to it
* and its existing properties cannot be removed).
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
isNotFrozen<T>(object: T, message?: string): void;
/**
* Asserts that object is not frozen (cannot have new properties added to it
* and its existing properties cannot be removed).
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
notFrozen<T>(object: T, message?: string): void;
/**
* Asserts that the target does not contain any values. For arrays and
* strings, it checks the length property. For Map and Set instances, it
* checks the size property. For non-function objects, it gets the count
* of own enumerable string keys.
*
* T Type of object
* @param object Actual value.
* @param message Message to display on error.
*/
isEmpty<T>(object: T, message?: string): void;
/**
* Asserts that the target contains values. For arrays and strings, it checks
* the length property. For Map and Set instances, it checks the size property.
* For non-function objects, it gets the count of own enumerable string keys.
*
* T Type of object.
* @param object Object to test.
* @param message Message to display on error.
*/
isNotEmpty<T>(object: T, message?: string): void;
/**
* Asserts that `object` has at least one of the `keys` provided.
* You can also provide a single object instead of a `keys` array and its keys
* will be used as the expected set of keys.
*
* T Type of object.
* @param object Object to test.
* @param keys Keys to check
* @param message Message to display on error.
*/
hasAnyKeys<T>(object: T, keys: Array<Object | string> | { [key: string]: any }, message?: string): void;
/**
* Asserts that `object` has all and only all of the `keys` provided.
* You can also provide a single object instead of a `keys` array and its keys
* will be used as the expected set of keys.
*
* T Type of object.
* @param object Object to test.
* @param keys Keys to check
* @param message Message to display on error.
*/
hasAllKeys<T>(object: T, keys: Array<Object | string> | { [key: string]: any }, message?: string): void;
/**
* Asserts that `object` has all of the `keys` provided but may have more keys not listed.
* You can also provide a single object instead of a `keys` array and its keys
* will be used as the expected set of keys.
*
* T Type of object.
* @param object Object to test.
* @param keys Keys to check
* @param message Message to display on error.
*/
containsAllKeys<T>(object: T, keys: Array<Object | string> | { [key: string]: any }, message?: string): void;
/**
* Asserts that `object` has none of the `keys` provided.
* You can also provide a single object instead of a `keys` array and its keys
* will be used as the expected set of keys.
*
* T Type of object.
* @param object Object to test.
* @param keys Keys to check
* @param message Message to display on error.
*/
doesNotHaveAnyKeys<T>(object: T, keys: Array<Object | string> | { [key: string]: any }, message?: string): void;
/**
* Asserts that `object` does not have at least one of the `keys` provided.
* You can also provide a single object instead of a `keys` array and its keys
* will be used as the expected set of keys.
*
* T Type of object.
* @param object Object to test.
* @param keys Keys to check
* @param message Message to display on error.
*/
doesNotHaveAllKeys<T>(object: T, keys: Array<Object | string> | { [key: string]: any }, message?: string): void;
/**
* Asserts that `object` has at least one of the `keys` provided.
* Since Sets and Maps can have objects as keys you can use this assertion to perform
* a deep comparison.
* You can also provide a single object instead of a `keys` array and its keys
* will be used as the expected set of keys.
*
* T Type of object.
* @param object Object to test.
* @param keys Keys to check
* @param message Message to display on error.
*/
hasAnyDeepKeys<T>(object: T, keys: Array<Object | string> | { [key: string]: any }, message?: string): void;
/**
* Asserts that `object` has all and only all of the `keys` provided.
* Since Sets and Maps can have objects as keys you can use this assertion to perform
* a deep comparison.
* You can also provide a single object instead of a `keys` array and its keys
* will be used as the expected set of keys.
*
* T Type of object.
* @param object Object to test.
* @param keys Keys to check
* @param message Message to display on error.
*/
hasAllDeepKeys<T>(object: T, keys: Array<Object | string> | { [key: string]: any }, message?: string): void;
/**
* Asserts that `object` contains all of the `keys` provided.
* Since Sets and Maps can have objects as keys you can use this assertion to perform
* a deep comparison.
* You can also provide a single object instead of a `keys` array and its keys
* will be used as the expected set of keys.
*
* T Type of object.
* @param object Object to test.
* @param keys Keys to check
* @param message Message to display on error.
*/
containsAllDeepKeys<T>(
object: T,
keys: Array<Object | string> | { [key: string]: any },
message?: string,
): void;
/**
* Asserts that `object` contains all of the `keys` provided.
* Since Sets and Maps can have objects as keys you can use this assertion to perform
* a deep comparison.
* You can also provide a single object instead of a `keys` array and its keys
* will be used as the expected set of keys.
*
* T Type of object.
* @param object Object to test.
* @param keys Keys to check
* @param message Message to display on error.
*/
doesNotHaveAnyDeepKeys<T>(
object: T,
keys: Array<Object | string> | { [key: string]: any },
message?: string,
): void;
/**
* Asserts that `object` contains all of the `keys` provided.
* Since Sets and Maps can have objects as keys you can use this assertion to perform
* a deep comparison.
* You can also provide a single object instead of a `keys` array and its keys
* will be used as the expected set of keys.
*
* T Type of object.
* @param object Object to test.
* @param keys Keys to check
* @param message Message to display on error.
*/
doesNotHaveAllDeepKeys<T>(
object: T,
keys: Array<Object | string> | { [key: string]: any },
message?: string,
): void;
/**
* Asserts that object has a direct or inherited property named by property,
* which can be a string using dot- and bracket-notation for nested reference.
*
* T Type of object.
* @param object Object to test.
* @param property Property to test.
* @param message Message to display on error.
*/
nestedProperty<T>(object: T, property: string, message?: string): void;
/**
* Asserts that object does not have a property named by property,
* which can be a string using dot- and bracket-notation for nested reference.
* The property cannot exist on the object nor anywhere in its prototype chain.
*
* T Type of object.
* @param object Object to test.
* @param property Property to test.
* @param message Message to display on error.
*/
notNestedProperty<T>(object: T, property: string, message?: string): void;
/**
* Asserts that object has a property named by property with value given by value.
* property can use dot- and bracket-notation for nested reference. Uses a strict equality check (===).
*
* T Type of object.
* @param object Object to test.
* @param property Property to test.
* @param value Value to test.
* @param message Message to display on error.
*/
nestedPropertyVal<T>(object: T, property: string, value: any, message?: string): void;
/**
* Asserts that object does not have a property named by property with value given by value.
* property can use dot- and bracket-notation for nested reference. Uses a strict equality check (===).
*
* T Type of object.
* @param object Object to test.
* @param property Property to test.
* @param value Value to test.
* @param message Message to display on error.
*/
notNestedPropertyVal<T>(object: T, property: string, value: any, message?: string): void;
/**
* Asserts that object has a property named by property with a value given by value.
* property can use dot- and bracket-notation for nested reference. Uses a deep equality check.
*
* T Type of object.
* @param object Object to test.
* @param property Property to test.
* @param value Value to test.
* @param message Message to display on error.
*/
deepNestedPropertyVal<T>(object: T, property: string, value: any, message?: string): void;
/**
* Asserts that object does not have a property named by property with value given by value.
* property can use dot- and bracket-notation for nested reference. Uses a deep equality check.
*
* T Type of object.
* @param object Object to test.
* @param property Property to test.
* @param value Value to test.
* @param message Message to display on error.
*/
notDeepNestedPropertyVal<T>(object: T, property: string, value: any, message?: string): void;
}
export interface Config {
/**
* Default: false
*/
includeStack: boolean;
/**
* Default: true
*/
showDiff: boolean;
/**
* Default: 40
*/
truncateThreshold: number;
/**
* Default: true
*/
useProxy: boolean;
/**
* Default: ['then', 'catch', 'inspect', 'toJSON']
*/
proxyExcludedKeys: string[];
}
export class AssertionError {
constructor(message: string, _props?: any, ssf?: Function);
name: string;
message: string;
showDiff: boolean;
stack: string;
}
}
declare const chai: Chai.ChaiStatic;
declare module "chai" {
export = chai;
}
// interface Object {
// should: Chai.Assertion;
// }
+258
View File
@@ -0,0 +1,258 @@
import * as _vitest_utils from '@vitest/utils';
import { stringify, Constructable } from '@vitest/utils';
export { setupColors } from '@vitest/utils';
import { diff } from '@vitest/utils/diff';
export { DiffOptions } from '@vitest/utils/diff';
type Formatter = (input: string | number | null | undefined) => string;
declare function getMatcherUtils(): {
EXPECTED_COLOR: _vitest_utils.ColorMethod;
RECEIVED_COLOR: _vitest_utils.ColorMethod;
INVERTED_COLOR: _vitest_utils.ColorMethod;
BOLD_WEIGHT: _vitest_utils.ColorMethod;
DIM_COLOR: _vitest_utils.ColorMethod;
matcherHint: (matcherName: string, received?: string, expected?: string, options?: MatcherHintOptions) => string;
printReceived: (object: unknown) => string;
printExpected: (value: unknown) => string;
};
declare function addCustomEqualityTesters(newTesters: Array<Tester>): void;
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
type ChaiPlugin = Chai.ChaiPlugin;
type Tester = (this: TesterContext, a: any, b: any, customTesters: Array<Tester>) => boolean | undefined;
interface TesterContext {
equals: (a: unknown, b: unknown, customTesters?: Array<Tester>, strictCheck?: boolean) => boolean;
}
interface MatcherHintOptions {
comment?: string;
expectedColor?: Formatter;
isDirectExpectCall?: boolean;
isNot?: boolean;
promise?: string;
receivedColor?: Formatter;
secondArgument?: string;
secondArgumentColor?: Formatter;
}
interface MatcherState {
customTesters: Array<Tester>;
assertionCalls: number;
currentTestName?: string;
dontThrow?: () => void;
error?: Error;
equals: (a: unknown, b: unknown, customTesters?: Array<Tester>, strictCheck?: boolean) => boolean;
expand?: boolean;
expectedAssertionsNumber?: number | null;
expectedAssertionsNumberErrorGen?: (() => Error) | null;
isExpectingAssertions?: boolean;
isExpectingAssertionsError?: Error | null;
isNot: boolean;
promise: string;
suppressedErrors: Array<Error>;
testPath?: string;
utils: ReturnType<typeof getMatcherUtils> & {
diff: typeof diff;
stringify: typeof stringify;
iterableEquality: Tester;
subsetEquality: Tester;
};
soft?: boolean;
}
interface SyncExpectationResult {
pass: boolean;
message: () => string;
actual?: any;
expected?: any;
}
type AsyncExpectationResult = Promise<SyncExpectationResult>;
type ExpectationResult = SyncExpectationResult | AsyncExpectationResult;
interface RawMatcherFn<T extends MatcherState = MatcherState> {
(this: T, received: any, expected: any, options?: any): ExpectationResult;
}
type MatchersObject<T extends MatcherState = MatcherState> = Record<string, RawMatcherFn<T>>;
interface ExpectStatic extends Chai.ExpectStatic, AsymmetricMatchersContaining {
<T>(actual: T, message?: string): Assertion<T>;
unreachable: (message?: string) => never;
soft: <T>(actual: T, message?: string) => Assertion<T>;
extend: (expects: MatchersObject) => void;
addEqualityTesters: (testers: Array<Tester>) => void;
assertions: (expected: number) => void;
hasAssertions: () => void;
anything: () => any;
any: (constructor: unknown) => any;
getState: () => MatcherState;
setState: (state: Partial<MatcherState>) => void;
not: AsymmetricMatchersContaining;
}
interface AsymmetricMatchersContaining {
stringContaining: (expected: string) => any;
objectContaining: <T = any>(expected: T) => any;
arrayContaining: <T = unknown>(expected: Array<T>) => any;
stringMatching: (expected: string | RegExp) => any;
closeTo: (expected: number, precision?: number) => any;
}
interface JestAssertion<T = any> extends jest.Matchers<void, T> {
toEqual: <E>(expected: E) => void;
toStrictEqual: <E>(expected: E) => void;
toBe: <E>(expected: E) => void;
toMatch: (expected: string | RegExp) => void;
toMatchObject: <E extends {} | any[]>(expected: E) => void;
toContain: <E>(item: E) => void;
toContainEqual: <E>(item: E) => void;
toBeTruthy: () => void;
toBeFalsy: () => void;
toBeGreaterThan: (num: number | bigint) => void;
toBeGreaterThanOrEqual: (num: number | bigint) => void;
toBeLessThan: (num: number | bigint) => void;
toBeLessThanOrEqual: (num: number | bigint) => void;
toBeNaN: () => void;
toBeUndefined: () => void;
toBeNull: () => void;
toBeDefined: () => void;
toBeInstanceOf: <E>(expected: E) => void;
toBeCalledTimes: (times: number) => void;
toHaveLength: (length: number) => void;
toHaveProperty: <E>(property: string | (string | number)[], value?: E) => void;
toBeCloseTo: (number: number, numDigits?: number) => void;
toHaveBeenCalledTimes: (times: number) => void;
toHaveBeenCalled: () => void;
toBeCalled: () => void;
toHaveBeenCalledWith: <E extends any[]>(...args: E) => void;
toBeCalledWith: <E extends any[]>(...args: E) => void;
toHaveBeenNthCalledWith: <E extends any[]>(n: number, ...args: E) => void;
nthCalledWith: <E extends any[]>(nthCall: number, ...args: E) => void;
toHaveBeenLastCalledWith: <E extends any[]>(...args: E) => void;
lastCalledWith: <E extends any[]>(...args: E) => void;
toThrow: (expected?: string | Constructable | RegExp | Error) => void;
toThrowError: (expected?: string | Constructable | RegExp | Error) => void;
toReturn: () => void;
toHaveReturned: () => void;
toReturnTimes: (times: number) => void;
toHaveReturnedTimes: (times: number) => void;
toReturnWith: <E>(value: E) => void;
toHaveReturnedWith: <E>(value: E) => void;
toHaveLastReturnedWith: <E>(value: E) => void;
lastReturnedWith: <E>(value: E) => void;
toHaveNthReturnedWith: <E>(nthCall: number, value: E) => void;
nthReturnedWith: <E>(nthCall: number, value: E) => void;
}
type VitestAssertion<A, T> = {
[K in keyof A]: A[K] extends Chai.Assertion ? Assertion<T> : A[K] extends (...args: any[]) => any ? A[K] : VitestAssertion<A[K], T>;
} & ((type: string, message?: string) => Assertion);
type Promisify<O> = {
[K in keyof O]: O[K] extends (...args: infer A) => infer R ? O extends R ? Promisify<O[K]> : (...args: A) => Promise<R> : O[K];
};
interface Assertion<T = any> extends VitestAssertion<Chai.Assertion, T>, JestAssertion<T> {
toBeTypeOf: (expected: 'bigint' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'undefined') => void;
toHaveBeenCalledOnce: () => void;
toSatisfy: <E>(matcher: (value: E) => boolean, message?: string) => void;
resolves: Promisify<Assertion<T>>;
rejects: Promisify<Assertion<T>>;
}
declare global {
namespace jest {
interface Matchers<R, T = {}> {
}
}
}
interface AsymmetricMatcherInterface {
asymmetricMatch: (other: unknown) => boolean;
toString: () => string;
getExpectedType?: () => string;
toAsymmetricMatcher?: () => string;
}
declare abstract class AsymmetricMatcher<T, State extends MatcherState = MatcherState> implements AsymmetricMatcherInterface {
protected sample: T;
protected inverse: boolean;
$$typeof: symbol;
constructor(sample: T, inverse?: boolean);
protected getMatcherContext(expect?: Chai.ExpectStatic): State;
abstract asymmetricMatch(other: unknown): boolean;
abstract toString(): string;
getExpectedType?(): string;
toAsymmetricMatcher?(): string;
}
declare class StringContaining extends AsymmetricMatcher<string> {
constructor(sample: string, inverse?: boolean);
asymmetricMatch(other: string): boolean;
toString(): string;
getExpectedType(): string;
}
declare class Anything extends AsymmetricMatcher<void> {
asymmetricMatch(other: unknown): boolean;
toString(): string;
toAsymmetricMatcher(): string;
}
declare class ObjectContaining extends AsymmetricMatcher<Record<string, unknown>> {
constructor(sample: Record<string, unknown>, inverse?: boolean);
getPrototype(obj: object): any;
hasProperty(obj: object | null, property: string): boolean;
asymmetricMatch(other: any): boolean;
toString(): string;
getExpectedType(): string;
}
declare class ArrayContaining<T = unknown> extends AsymmetricMatcher<Array<T>> {
constructor(sample: Array<T>, inverse?: boolean);
asymmetricMatch(other: Array<T>): boolean;
toString(): string;
getExpectedType(): string;
}
declare class Any extends AsymmetricMatcher<any> {
constructor(sample: unknown);
fnNameFor(func: Function): string;
asymmetricMatch(other: unknown): boolean;
toString(): string;
getExpectedType(): string;
toAsymmetricMatcher(): string;
}
declare class StringMatching extends AsymmetricMatcher<RegExp> {
constructor(sample: string | RegExp, inverse?: boolean);
asymmetricMatch(other: string): boolean;
toString(): string;
getExpectedType(): string;
}
declare const JestAsymmetricMatchers: ChaiPlugin;
declare function equals(a: unknown, b: unknown, customTesters?: Array<Tester>, strictCheck?: boolean): boolean;
declare function isAsymmetric(obj: any): boolean;
declare function hasAsymmetric(obj: any, seen?: Set<unknown>): boolean;
declare function isA(typeName: string, value: unknown): boolean;
declare function fnNameFor(func: Function): string;
declare function hasProperty(obj: object | null, property: string): boolean;
declare function isImmutableUnorderedKeyed(maybeKeyed: any): boolean;
declare function isImmutableUnorderedSet(maybeSet: any): boolean;
declare function iterableEquality(a: any, b: any, customTesters?: Array<Tester>, aStack?: Array<any>, bStack?: Array<any>): boolean | undefined;
declare function subsetEquality(object: unknown, subset: unknown, customTesters?: Array<Tester>): boolean | undefined;
declare function typeEquality(a: any, b: any): boolean | undefined;
declare function arrayBufferEquality(a: unknown, b: unknown): boolean | undefined;
declare function sparseArrayEquality(a: unknown, b: unknown, customTesters?: Array<Tester>): boolean | undefined;
declare function generateToBeMessage(deepEqualityName: string, expected?: string, actual?: string): string;
declare function pluralize(word: string, count: number): string;
declare function getObjectKeys(object: object): Array<string | symbol>;
declare function getObjectSubset(object: any, subset: any, customTesters?: Array<Tester>): {
subset: any;
stripped: number;
};
declare const MATCHERS_OBJECT: unique symbol;
declare const JEST_MATCHERS_OBJECT: unique symbol;
declare const GLOBAL_EXPECT: unique symbol;
declare const ASYMMETRIC_MATCHERS_OBJECT: unique symbol;
declare function getState<State extends MatcherState = MatcherState>(expect: ExpectStatic): State;
declare function setState<State extends MatcherState = MatcherState>(state: Partial<State>, expect: ExpectStatic): void;
declare const JestChaiExpect: ChaiPlugin;
declare const JestExtend: ChaiPlugin;
export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, type Assertion, AsymmetricMatcher, type AsymmetricMatcherInterface, type AsymmetricMatchersContaining, type AsyncExpectationResult, type ChaiPlugin, type ExpectStatic, type ExpectationResult, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, type JestAssertion, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, type MatcherHintOptions, type MatcherState, type MatchersObject, ObjectContaining, type RawMatcherFn, StringContaining, StringMatching, type SyncExpectationResult, type Tester, type TesterContext, addCustomEqualityTesters, arrayBufferEquality, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality };
+1639
View File
@@ -0,0 +1,1639 @@
import { getType, getColors, stringify, isObject, assertTypes } from '@vitest/utils';
export { setupColors } from '@vitest/utils';
import { diff } from '@vitest/utils/diff';
import { isMockFunction } from '@vitest/spy';
import { processError } from '@vitest/utils/error';
import { util } from 'chai';
const MATCHERS_OBJECT = Symbol.for("matchers-object");
const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
const GLOBAL_EXPECT = Symbol.for("expect-global");
const ASYMMETRIC_MATCHERS_OBJECT = Symbol.for("asymmetric-matchers-object");
if (!Object.prototype.hasOwnProperty.call(globalThis, MATCHERS_OBJECT)) {
const globalState = /* @__PURE__ */ new WeakMap();
const matchers = /* @__PURE__ */ Object.create(null);
const customEqualityTesters = [];
const assymetricMatchers = /* @__PURE__ */ Object.create(null);
Object.defineProperty(globalThis, MATCHERS_OBJECT, {
get: () => globalState
});
Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, {
configurable: true,
get: () => ({
state: globalState.get(globalThis[GLOBAL_EXPECT]),
matchers,
customEqualityTesters
})
});
Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, {
get: () => assymetricMatchers
});
}
function getState(expect) {
return globalThis[MATCHERS_OBJECT].get(expect);
}
function setState(state, expect) {
const map = globalThis[MATCHERS_OBJECT];
const current = map.get(expect) || {};
Object.assign(current, state);
map.set(expect, current);
}
function getMatcherUtils() {
const c = () => getColors();
const EXPECTED_COLOR = c().green;
const RECEIVED_COLOR = c().red;
const INVERTED_COLOR = c().inverse;
const BOLD_WEIGHT = c().bold;
const DIM_COLOR = c().dim;
function matcherHint(matcherName, received = "received", expected = "expected", options = {}) {
const {
comment = "",
isDirectExpectCall = false,
// seems redundant with received === ''
isNot = false,
promise = "",
secondArgument = "",
expectedColor = EXPECTED_COLOR,
receivedColor = RECEIVED_COLOR,
secondArgumentColor = EXPECTED_COLOR
} = options;
let hint = "";
let dimString = "expect";
if (!isDirectExpectCall && received !== "") {
hint += DIM_COLOR(`${dimString}(`) + receivedColor(received);
dimString = ")";
}
if (promise !== "") {
hint += DIM_COLOR(`${dimString}.`) + promise;
dimString = "";
}
if (isNot) {
hint += `${DIM_COLOR(`${dimString}.`)}not`;
dimString = "";
}
if (matcherName.includes(".")) {
dimString += matcherName;
} else {
hint += DIM_COLOR(`${dimString}.`) + matcherName;
dimString = "";
}
if (expected === "") {
dimString += "()";
} else {
hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected);
if (secondArgument)
hint += DIM_COLOR(", ") + secondArgumentColor(secondArgument);
dimString = ")";
}
if (comment !== "")
dimString += ` // ${comment}`;
if (dimString !== "")
hint += DIM_COLOR(dimString);
return hint;
}
const SPACE_SYMBOL = "\xB7";
const replaceTrailingSpaces = (text) => text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length));
const printReceived = (object) => RECEIVED_COLOR(replaceTrailingSpaces(stringify(object)));
const printExpected = (value) => EXPECTED_COLOR(replaceTrailingSpaces(stringify(value)));
return {
EXPECTED_COLOR,
RECEIVED_COLOR,
INVERTED_COLOR,
BOLD_WEIGHT,
DIM_COLOR,
matcherHint,
printReceived,
printExpected
};
}
function addCustomEqualityTesters(newTesters) {
if (!Array.isArray(newTesters)) {
throw new TypeError(
`expect.customEqualityTesters: Must be set to an array of Testers. Was given "${getType(
newTesters
)}"`
);
}
globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters.push(
...newTesters
);
}
function getCustomEqualityTesters() {
return globalThis[JEST_MATCHERS_OBJECT].customEqualityTesters;
}
function equals(a, b, customTesters, strictCheck) {
customTesters = customTesters || [];
return eq(a, b, [], [], customTesters, strictCheck ? hasKey : hasDefinedKey);
}
const functionToString = Function.prototype.toString;
function isAsymmetric(obj) {
return !!obj && typeof obj === "object" && "asymmetricMatch" in obj && isA("Function", obj.asymmetricMatch);
}
function hasAsymmetric(obj, seen = /* @__PURE__ */ new Set()) {
if (seen.has(obj))
return false;
seen.add(obj);
if (isAsymmetric(obj))
return true;
if (Array.isArray(obj))
return obj.some((i) => hasAsymmetric(i, seen));
if (obj instanceof Set)
return Array.from(obj).some((i) => hasAsymmetric(i, seen));
if (isObject(obj))
return Object.values(obj).some((v) => hasAsymmetric(v, seen));
return false;
}
function asymmetricMatch(a, b) {
const asymmetricA = isAsymmetric(a);
const asymmetricB = isAsymmetric(b);
if (asymmetricA && asymmetricB)
return void 0;
if (asymmetricA)
return a.asymmetricMatch(b);
if (asymmetricB)
return b.asymmetricMatch(a);
}
function eq(a, b, aStack, bStack, customTesters, hasKey2) {
let result = true;
const asymmetricResult = asymmetricMatch(a, b);
if (asymmetricResult !== void 0)
return asymmetricResult;
const testerContext = { equals };
for (let i = 0; i < customTesters.length; i++) {
const customTesterResult = customTesters[i].call(testerContext, a, b, customTesters);
if (customTesterResult !== void 0)
return customTesterResult;
}
if (a instanceof Error && b instanceof Error)
return a.message === b.message;
if (typeof URL === "function" && a instanceof URL && b instanceof URL)
return a.href === b.href;
if (Object.is(a, b))
return true;
if (a === null || b === null)
return a === b;
const className = Object.prototype.toString.call(a);
if (className !== Object.prototype.toString.call(b))
return false;
switch (className) {
case "[object Boolean]":
case "[object String]":
case "[object Number]":
if (typeof a !== typeof b) {
return false;
} else if (typeof a !== "object" && typeof b !== "object") {
return Object.is(a, b);
} else {
return Object.is(a.valueOf(), b.valueOf());
}
case "[object Date]": {
const numA = +a;
const numB = +b;
return numA === numB || Number.isNaN(numA) && Number.isNaN(numB);
}
case "[object RegExp]":
return a.source === b.source && a.flags === b.flags;
}
if (typeof a !== "object" || typeof b !== "object")
return false;
if (isDomNode(a) && isDomNode(b))
return a.isEqualNode(b);
let length = aStack.length;
while (length--) {
if (aStack[length] === a)
return bStack[length] === b;
else if (bStack[length] === b)
return false;
}
aStack.push(a);
bStack.push(b);
if (className === "[object Array]" && a.length !== b.length)
return false;
const aKeys = keys(a, hasKey2);
let key;
let size = aKeys.length;
if (keys(b, hasKey2).length !== size)
return false;
while (size--) {
key = aKeys[size];
result = hasKey2(b, key) && eq(a[key], b[key], aStack, bStack, customTesters, hasKey2);
if (!result)
return false;
}
aStack.pop();
bStack.pop();
return result;
}
function keys(obj, hasKey2) {
const keys2 = [];
for (const key in obj) {
if (hasKey2(obj, key))
keys2.push(key);
}
return keys2.concat(
Object.getOwnPropertySymbols(obj).filter(
(symbol) => Object.getOwnPropertyDescriptor(obj, symbol).enumerable
)
);
}
function hasDefinedKey(obj, key) {
return hasKey(obj, key) && obj[key] !== void 0;
}
function hasKey(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
}
function isA(typeName, value) {
return Object.prototype.toString.apply(value) === `[object ${typeName}]`;
}
function isDomNode(obj) {
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";
}
function fnNameFor(func) {
if (func.name)
return func.name;
const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*\*?\s*([\w$]+)\s*\(/);
return matches ? matches[1] : "<anonymous>";
}
function getPrototype(obj) {
if (Object.getPrototypeOf)
return Object.getPrototypeOf(obj);
if (obj.constructor.prototype === obj)
return null;
return obj.constructor.prototype;
}
function hasProperty(obj, property) {
if (!obj)
return false;
if (Object.prototype.hasOwnProperty.call(obj, property))
return true;
return hasProperty(getPrototype(obj), property);
}
const IS_KEYED_SENTINEL = "@@__IMMUTABLE_KEYED__@@";
const IS_SET_SENTINEL = "@@__IMMUTABLE_SET__@@";
const IS_ORDERED_SENTINEL = "@@__IMMUTABLE_ORDERED__@@";
function isImmutableUnorderedKeyed(maybeKeyed) {
return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL] && !maybeKeyed[IS_ORDERED_SENTINEL]);
}
function isImmutableUnorderedSet(maybeSet) {
return !!(maybeSet && maybeSet[IS_SET_SENTINEL] && !maybeSet[IS_ORDERED_SENTINEL]);
}
const IteratorSymbol = Symbol.iterator;
function hasIterator(object) {
return !!(object != null && object[IteratorSymbol]);
}
function iterableEquality(a, b, customTesters = [], aStack = [], bStack = []) {
if (typeof a !== "object" || typeof b !== "object" || Array.isArray(a) || Array.isArray(b) || !hasIterator(a) || !hasIterator(b))
return void 0;
if (a.constructor !== b.constructor)
return false;
let length = aStack.length;
while (length--) {
if (aStack[length] === a)
return bStack[length] === b;
}
aStack.push(a);
bStack.push(b);
const filteredCustomTesters = [
...customTesters.filter((t) => t !== iterableEquality),
iterableEqualityWithStack
];
function iterableEqualityWithStack(a2, b2) {
return iterableEquality(
a2,
b2,
[...customTesters],
[...aStack],
[...bStack]
);
}
if (a.size !== void 0) {
if (a.size !== b.size) {
return false;
} else if (isA("Set", a) || isImmutableUnorderedSet(a)) {
let allFound = true;
for (const aValue of a) {
if (!b.has(aValue)) {
let has = false;
for (const bValue of b) {
const isEqual = equals(aValue, bValue, filteredCustomTesters);
if (isEqual === true)
has = true;
}
if (has === false) {
allFound = false;
break;
}
}
}
aStack.pop();
bStack.pop();
return allFound;
} else if (isA("Map", a) || isImmutableUnorderedKeyed(a)) {
let allFound = true;
for (const aEntry of a) {
if (!b.has(aEntry[0]) || !equals(aEntry[1], b.get(aEntry[0]), filteredCustomTesters)) {
let has = false;
for (const bEntry of b) {
const matchedKey = equals(aEntry[0], bEntry[0], filteredCustomTesters);
let matchedValue = false;
if (matchedKey === true)
matchedValue = equals(aEntry[1], bEntry[1], filteredCustomTesters);
if (matchedValue === true)
has = true;
}
if (has === false) {
allFound = false;
break;
}
}
}
aStack.pop();
bStack.pop();
return allFound;
}
}
const bIterator = b[IteratorSymbol]();
for (const aValue of a) {
const nextB = bIterator.next();
if (nextB.done || !equals(aValue, nextB.value, filteredCustomTesters))
return false;
}
if (!bIterator.next().done)
return false;
const aEntries = Object.entries(a);
const bEntries = Object.entries(b);
if (!equals(aEntries, bEntries))
return false;
aStack.pop();
bStack.pop();
return true;
}
function hasPropertyInObject(object, key) {
const shouldTerminate = !object || typeof object !== "object" || object === Object.prototype;
if (shouldTerminate)
return false;
return Object.prototype.hasOwnProperty.call(object, key) || hasPropertyInObject(Object.getPrototypeOf(object), key);
}
function isObjectWithKeys(a) {
return isObject(a) && !(a instanceof Error) && !Array.isArray(a) && !(a instanceof Date);
}
function subsetEquality(object, subset, customTesters = []) {
const filteredCustomTesters = customTesters.filter((t) => t !== subsetEquality);
const subsetEqualityWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object2, subset2) => {
if (!isObjectWithKeys(subset2))
return void 0;
return Object.keys(subset2).every((key) => {
if (subset2[key] != null && typeof subset2[key] === "object") {
if (seenReferences.has(subset2[key]))
return equals(object2[key], subset2[key], filteredCustomTesters);
seenReferences.set(subset2[key], true);
}
const result = object2 != null && hasPropertyInObject(object2, key) && equals(object2[key], subset2[key], [
...filteredCustomTesters,
subsetEqualityWithContext(seenReferences)
]);
seenReferences.delete(subset2[key]);
return result;
});
};
return subsetEqualityWithContext()(object, subset);
}
function typeEquality(a, b) {
if (a == null || b == null || a.constructor === b.constructor)
return void 0;
return false;
}
function arrayBufferEquality(a, b) {
let dataViewA = a;
let dataViewB = b;
if (!(a instanceof DataView && b instanceof DataView)) {
if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer))
return void 0;
try {
dataViewA = new DataView(a);
dataViewB = new DataView(b);
} catch {
return void 0;
}
}
if (dataViewA.byteLength !== dataViewB.byteLength)
return false;
for (let i = 0; i < dataViewA.byteLength; i++) {
if (dataViewA.getUint8(i) !== dataViewB.getUint8(i))
return false;
}
return true;
}
function sparseArrayEquality(a, b, customTesters = []) {
if (!Array.isArray(a) || !Array.isArray(b))
return void 0;
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
const filteredCustomTesters = customTesters.filter((t) => t !== sparseArrayEquality);
return equals(a, b, filteredCustomTesters, true) && equals(aKeys, bKeys);
}
function generateToBeMessage(deepEqualityName, expected = "#{this}", actual = "#{exp}") {
const toBeMessage = `expected ${expected} to be ${actual} // Object.is equality`;
if (["toStrictEqual", "toEqual"].includes(deepEqualityName))
return `${toBeMessage}
If it should pass with deep equality, replace "toBe" with "${deepEqualityName}"
Expected: ${expected}
Received: serializes to the same string
`;
return toBeMessage;
}
function pluralize(word, count) {
return `${count} ${word}${count === 1 ? "" : "s"}`;
}
function getObjectKeys(object) {
return [
...Object.keys(object),
...Object.getOwnPropertySymbols(object).filter(
(s) => {
var _a;
return (_a = Object.getOwnPropertyDescriptor(object, s)) == null ? void 0 : _a.enumerable;
}
)
];
}
function getObjectSubset(object, subset, customTesters = []) {
let stripped = 0;
const getObjectSubsetWithContext = (seenReferences = /* @__PURE__ */ new WeakMap()) => (object2, subset2) => {
if (Array.isArray(object2)) {
if (Array.isArray(subset2) && subset2.length === object2.length) {
return subset2.map(
(sub, i) => getObjectSubsetWithContext(seenReferences)(object2[i], sub)
);
}
} else if (object2 instanceof Date) {
return object2;
} else if (isObject(object2) && isObject(subset2)) {
if (equals(object2, subset2, [
...customTesters,
iterableEquality,
subsetEquality
])) {
return subset2;
}
const trimmed = {};
seenReferences.set(object2, trimmed);
for (const key of getObjectKeys(object2)) {
if (hasPropertyInObject(subset2, key)) {
trimmed[key] = seenReferences.has(object2[key]) ? seenReferences.get(object2[key]) : getObjectSubsetWithContext(seenReferences)(object2[key], subset2[key]);
} else {
if (!seenReferences.has(object2[key])) {
stripped += 1;
if (isObject(object2[key]))
stripped += getObjectKeys(object2[key]).length;
getObjectSubsetWithContext(seenReferences)(object2[key], subset2[key]);
}
}
}
if (getObjectKeys(trimmed).length > 0)
return trimmed;
}
return object2;
};
return { subset: getObjectSubsetWithContext()(object, subset), stripped };
}
class AsymmetricMatcher {
constructor(sample, inverse = false) {
this.sample = sample;
this.inverse = inverse;
}
// should have "jest" to be compatible with its ecosystem
$$typeof = Symbol.for("jest.asymmetricMatcher");
getMatcherContext(expect) {
return {
...getState(expect || globalThis[GLOBAL_EXPECT]),
equals,
isNot: this.inverse,
customTesters: getCustomEqualityTesters(),
utils: {
...getMatcherUtils(),
diff,
stringify,
iterableEquality,
subsetEquality
}
};
}
// implement custom chai/loupe inspect for better AssertionError.message formatting
// https://github.com/chaijs/loupe/blob/9b8a6deabcd50adc056a64fb705896194710c5c6/src/index.ts#L29
[Symbol.for("chai/inspect")](options) {
const result = stringify(this, options.depth, { min: true });
if (result.length <= options.truncate)
return result;
return `${this.toString()}{\u2026}`;
}
}
class StringContaining extends AsymmetricMatcher {
constructor(sample, inverse = false) {
if (!isA("String", sample))
throw new Error("Expected is not a string");
super(sample, inverse);
}
asymmetricMatch(other) {
const result = isA("String", other) && other.includes(this.sample);
return this.inverse ? !result : result;
}
toString() {
return `String${this.inverse ? "Not" : ""}Containing`;
}
getExpectedType() {
return "string";
}
}
class Anything extends AsymmetricMatcher {
asymmetricMatch(other) {
return other != null;
}
toString() {
return "Anything";
}
toAsymmetricMatcher() {
return "Anything";
}
}
class ObjectContaining extends AsymmetricMatcher {
constructor(sample, inverse = false) {
super(sample, inverse);
}
getPrototype(obj) {
if (Object.getPrototypeOf)
return Object.getPrototypeOf(obj);
if (obj.constructor.prototype === obj)
return null;
return obj.constructor.prototype;
}
hasProperty(obj, property) {
if (!obj)
return false;
if (Object.prototype.hasOwnProperty.call(obj, property))
return true;
return this.hasProperty(this.getPrototype(obj), property);
}
asymmetricMatch(other) {
if (typeof this.sample !== "object") {
throw new TypeError(
`You must provide an object to ${this.toString()}, not '${typeof this.sample}'.`
);
}
let result = true;
const matcherContext = this.getMatcherContext();
for (const property in this.sample) {
if (!this.hasProperty(other, property) || !equals(this.sample[property], other[property], matcherContext.customTesters)) {
result = false;
break;
}
}
return this.inverse ? !result : result;
}
toString() {
return `Object${this.inverse ? "Not" : ""}Containing`;
}
getExpectedType() {
return "object";
}
}
class ArrayContaining extends AsymmetricMatcher {
constructor(sample, inverse = false) {
super(sample, inverse);
}
asymmetricMatch(other) {
if (!Array.isArray(this.sample)) {
throw new TypeError(
`You must provide an array to ${this.toString()}, not '${typeof this.sample}'.`
);
}
const matcherContext = this.getMatcherContext();
const result = this.sample.length === 0 || Array.isArray(other) && this.sample.every(
(item) => other.some((another) => equals(item, another, matcherContext.customTesters))
);
return this.inverse ? !result : result;
}
toString() {
return `Array${this.inverse ? "Not" : ""}Containing`;
}
getExpectedType() {
return "array";
}
}
class Any extends AsymmetricMatcher {
constructor(sample) {
if (typeof sample === "undefined") {
throw new TypeError(
"any() expects to be passed a constructor function. Please pass one or use anything() to match any object."
);
}
super(sample);
}
fnNameFor(func) {
if (func.name)
return func.name;
const functionToString = Function.prototype.toString;
const matches = functionToString.call(func).match(/^(?:async)?\s*function\s*\*?\s*([\w$]+)\s*\(/);
return matches ? matches[1] : "<anonymous>";
}
asymmetricMatch(other) {
if (this.sample === String)
return typeof other == "string" || other instanceof String;
if (this.sample === Number)
return typeof other == "number" || other instanceof Number;
if (this.sample === Function)
return typeof other == "function" || other instanceof Function;
if (this.sample === Boolean)
return typeof other == "boolean" || other instanceof Boolean;
if (this.sample === BigInt)
return typeof other == "bigint" || other instanceof BigInt;
if (this.sample === Symbol)
return typeof other == "symbol" || other instanceof Symbol;
if (this.sample === Object)
return typeof other == "object";
return other instanceof this.sample;
}
toString() {
return "Any";
}
getExpectedType() {
if (this.sample === String)
return "string";
if (this.sample === Number)
return "number";
if (this.sample === Function)
return "function";
if (this.sample === Object)
return "object";
if (this.sample === Boolean)
return "boolean";
return this.fnNameFor(this.sample);
}
toAsymmetricMatcher() {
return `Any<${this.fnNameFor(this.sample)}>`;
}
}
class StringMatching extends AsymmetricMatcher {
constructor(sample, inverse = false) {
if (!isA("String", sample) && !isA("RegExp", sample))
throw new Error("Expected is not a String or a RegExp");
super(new RegExp(sample), inverse);
}
asymmetricMatch(other) {
const result = isA("String", other) && this.sample.test(other);
return this.inverse ? !result : result;
}
toString() {
return `String${this.inverse ? "Not" : ""}Matching`;
}
getExpectedType() {
return "string";
}
}
class CloseTo extends AsymmetricMatcher {
precision;
constructor(sample, precision = 2, inverse = false) {
if (!isA("Number", sample))
throw new Error("Expected is not a Number");
if (!isA("Number", precision))
throw new Error("Precision is not a Number");
super(sample);
this.inverse = inverse;
this.precision = precision;
}
asymmetricMatch(other) {
if (!isA("Number", other))
return false;
let result = false;
if (other === Number.POSITIVE_INFINITY && this.sample === Number.POSITIVE_INFINITY) {
result = true;
} else if (other === Number.NEGATIVE_INFINITY && this.sample === Number.NEGATIVE_INFINITY) {
result = true;
} else {
result = Math.abs(this.sample - other) < 10 ** -this.precision / 2;
}
return this.inverse ? !result : result;
}
toString() {
return `Number${this.inverse ? "Not" : ""}CloseTo`;
}
getExpectedType() {
return "number";
}
toAsymmetricMatcher() {
return [
this.toString(),
this.sample,
`(${pluralize("digit", this.precision)})`
].join(" ");
}
}
const JestAsymmetricMatchers = (chai, utils) => {
utils.addMethod(
chai.expect,
"anything",
() => new Anything()
);
utils.addMethod(
chai.expect,
"any",
(expected) => new Any(expected)
);
utils.addMethod(
chai.expect,
"stringContaining",
(expected) => new StringContaining(expected)
);
utils.addMethod(
chai.expect,
"objectContaining",
(expected) => new ObjectContaining(expected)
);
utils.addMethod(
chai.expect,
"arrayContaining",
(expected) => new ArrayContaining(expected)
);
utils.addMethod(
chai.expect,
"stringMatching",
(expected) => new StringMatching(expected)
);
utils.addMethod(
chai.expect,
"closeTo",
(expected, precision) => new CloseTo(expected, precision)
);
chai.expect.not = {
stringContaining: (expected) => new StringContaining(expected, true),
objectContaining: (expected) => new ObjectContaining(expected, true),
arrayContaining: (expected) => new ArrayContaining(expected, true),
stringMatching: (expected) => new StringMatching(expected, true),
closeTo: (expected, precision) => new CloseTo(expected, precision, true)
};
};
function recordAsyncExpect(test, promise) {
if (test && promise instanceof Promise) {
promise = promise.finally(() => {
const index = test.promises.indexOf(promise);
if (index !== -1)
test.promises.splice(index, 1);
});
if (!test.promises)
test.promises = [];
test.promises.push(promise);
}
return promise;
}
function wrapSoft(utils, fn) {
return function(...args) {
var _a;
const test = utils.flag(this, "vitest-test");
const state = (test == null ? void 0 : test.context._local) ? test.context.expect.getState() : getState(globalThis[GLOBAL_EXPECT]);
if (!state.soft)
return fn.apply(this, args);
if (!test)
throw new Error("expect.soft() can only be used inside a test");
try {
return fn.apply(this, args);
} catch (err) {
test.result || (test.result = { state: "fail" });
test.result.state = "fail";
(_a = test.result).errors || (_a.errors = []);
test.result.errors.push(processError(err));
}
};
}
const JestChaiExpect = (chai, utils) => {
const { AssertionError } = chai;
const c = () => getColors();
const customTesters = getCustomEqualityTesters();
function def(name, fn) {
const addMethod = (n) => {
const softWrapper = wrapSoft(utils, fn);
utils.addMethod(chai.Assertion.prototype, n, softWrapper);
utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, n, softWrapper);
};
if (Array.isArray(name))
name.forEach((n) => addMethod(n));
else
addMethod(name);
}
["throw", "throws", "Throw"].forEach((m) => {
utils.overwriteMethod(chai.Assertion.prototype, m, (_super) => {
return function(...args) {
const promise = utils.flag(this, "promise");
const object = utils.flag(this, "object");
const isNot = utils.flag(this, "negate");
if (promise === "rejects") {
utils.flag(this, "object", () => {
throw object;
});
} else if (promise === "resolves" && typeof object !== "function") {
if (!isNot) {
const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't";
const error = {
showDiff: false
};
throw new AssertionError(message, error, utils.flag(this, "ssfi"));
} else {
return;
}
}
_super.apply(this, args);
};
});
});
def("withTest", function(test) {
utils.flag(this, "vitest-test", test);
return this;
});
def("toEqual", function(expected) {
const actual = utils.flag(this, "object");
const equal = equals(
actual,
expected,
[...customTesters, iterableEquality]
);
return this.assert(
equal,
"expected #{this} to deeply equal #{exp}",
"expected #{this} to not deeply equal #{exp}",
expected,
actual
);
});
def("toStrictEqual", function(expected) {
const obj = utils.flag(this, "object");
const equal = equals(
obj,
expected,
[
...customTesters,
iterableEquality,
typeEquality,
sparseArrayEquality,
arrayBufferEquality
],
true
);
return this.assert(
equal,
"expected #{this} to strictly equal #{exp}",
"expected #{this} to not strictly equal #{exp}",
expected,
obj
);
});
def("toBe", function(expected) {
const actual = this._obj;
const pass = Object.is(actual, expected);
let deepEqualityName = "";
if (!pass) {
const toStrictEqualPass = equals(
actual,
expected,
[
...customTesters,
iterableEquality,
typeEquality,
sparseArrayEquality,
arrayBufferEquality
],
true
);
if (toStrictEqualPass) {
deepEqualityName = "toStrictEqual";
} else {
const toEqualPass = equals(
actual,
expected,
[...customTesters, iterableEquality]
);
if (toEqualPass)
deepEqualityName = "toEqual";
}
}
return this.assert(
pass,
generateToBeMessage(deepEqualityName),
"expected #{this} not to be #{exp} // Object.is equality",
expected,
actual
);
});
def("toMatchObject", function(expected) {
const actual = this._obj;
const pass = equals(actual, expected, [...customTesters, iterableEquality, subsetEquality]);
const isNot = utils.flag(this, "negate");
const { subset: actualSubset, stripped } = getObjectSubset(actual, expected);
if (pass && isNot || !pass && !isNot) {
const msg = utils.getMessage(
this,
[
pass,
"expected #{this} to match object #{exp}",
"expected #{this} to not match object #{exp}",
expected,
actualSubset,
false
]
);
const message = stripped === 0 ? msg : `${msg}
(${stripped} matching ${stripped === 1 ? "property" : "properties"} omitted from actual)`;
throw new AssertionError(message, { showDiff: true, expected, actual: actualSubset });
}
});
def("toMatch", function(expected) {
const actual = this._obj;
if (typeof actual !== "string")
throw new TypeError(`.toMatch() expects to receive a string, but got ${typeof actual}`);
return this.assert(
typeof expected === "string" ? actual.includes(expected) : actual.match(expected),
`expected #{this} to match #{exp}`,
`expected #{this} not to match #{exp}`,
expected,
actual
);
});
def("toContain", function(item) {
const actual = this._obj;
if (typeof Node !== "undefined" && actual instanceof Node) {
if (!(item instanceof Node))
throw new TypeError(`toContain() expected a DOM node as the argument, but got ${typeof item}`);
return this.assert(
actual.contains(item),
"expected #{this} to contain element #{exp}",
"expected #{this} not to contain element #{exp}",
item,
actual
);
}
if (typeof DOMTokenList !== "undefined" && actual instanceof DOMTokenList) {
assertTypes(item, "class name", ["string"]);
const isNot = utils.flag(this, "negate");
const expectedClassList = isNot ? actual.value.replace(item, "").trim() : `${actual.value} ${item}`;
return this.assert(
actual.contains(item),
`expected "${actual.value}" to contain "${item}"`,
`expected "${actual.value}" not to contain "${item}"`,
expectedClassList,
actual.value
);
}
if (typeof actual === "string" && typeof item === "string") {
return this.assert(
actual.includes(item),
`expected #{this} to contain #{exp}`,
`expected #{this} not to contain #{exp}`,
item,
actual
);
}
if (actual != null && typeof actual !== "string")
utils.flag(this, "object", Array.from(actual));
return this.contain(item);
});
def("toContainEqual", function(expected) {
const obj = utils.flag(this, "object");
const index = Array.from(obj).findIndex((item) => {
return equals(item, expected, customTesters);
});
this.assert(
index !== -1,
"expected #{this} to deep equally contain #{exp}",
"expected #{this} to not deep equally contain #{exp}",
expected
);
});
def("toBeTruthy", function() {
const obj = utils.flag(this, "object");
this.assert(
Boolean(obj),
"expected #{this} to be truthy",
"expected #{this} to not be truthy",
obj,
false
);
});
def("toBeFalsy", function() {
const obj = utils.flag(this, "object");
this.assert(
!obj,
"expected #{this} to be falsy",
"expected #{this} to not be falsy",
obj,
false
);
});
def("toBeGreaterThan", function(expected) {
const actual = this._obj;
assertTypes(actual, "actual", ["number", "bigint"]);
assertTypes(expected, "expected", ["number", "bigint"]);
return this.assert(
actual > expected,
`expected ${actual} to be greater than ${expected}`,
`expected ${actual} to be not greater than ${expected}`,
actual,
expected,
false
);
});
def("toBeGreaterThanOrEqual", function(expected) {
const actual = this._obj;
assertTypes(actual, "actual", ["number", "bigint"]);
assertTypes(expected, "expected", ["number", "bigint"]);
return this.assert(
actual >= expected,
`expected ${actual} to be greater than or equal to ${expected}`,
`expected ${actual} to be not greater than or equal to ${expected}`,
actual,
expected,
false
);
});
def("toBeLessThan", function(expected) {
const actual = this._obj;
assertTypes(actual, "actual", ["number", "bigint"]);
assertTypes(expected, "expected", ["number", "bigint"]);
return this.assert(
actual < expected,
`expected ${actual} to be less than ${expected}`,
`expected ${actual} to be not less than ${expected}`,
actual,
expected,
false
);
});
def("toBeLessThanOrEqual", function(expected) {
const actual = this._obj;
assertTypes(actual, "actual", ["number", "bigint"]);
assertTypes(expected, "expected", ["number", "bigint"]);
return this.assert(
actual <= expected,
`expected ${actual} to be less than or equal to ${expected}`,
`expected ${actual} to be not less than or equal to ${expected}`,
actual,
expected,
false
);
});
def("toBeNaN", function() {
return this.be.NaN;
});
def("toBeUndefined", function() {
return this.be.undefined;
});
def("toBeNull", function() {
return this.be.null;
});
def("toBeDefined", function() {
const negate = utils.flag(this, "negate");
utils.flag(this, "negate", false);
if (negate)
return this.be.undefined;
return this.not.be.undefined;
});
def("toBeTypeOf", function(expected) {
const actual = typeof this._obj;
const equal = expected === actual;
return this.assert(
equal,
"expected #{this} to be type of #{exp}",
"expected #{this} not to be type of #{exp}",
expected,
actual
);
});
def("toBeInstanceOf", function(obj) {
return this.instanceOf(obj);
});
def("toHaveLength", function(length) {
return this.have.length(length);
});
def("toHaveProperty", function(...args) {
if (Array.isArray(args[0]))
args[0] = args[0].map((key) => String(key).replace(/([.[\]])/g, "\\$1")).join(".");
const actual = this._obj;
const [propertyName, expected] = args;
const getValue = () => {
const hasOwn = Object.prototype.hasOwnProperty.call(actual, propertyName);
if (hasOwn)
return { value: actual[propertyName], exists: true };
return utils.getPathInfo(actual, propertyName);
};
const { value, exists } = getValue();
const pass = exists && (args.length === 1 || equals(expected, value, customTesters));
const valueString = args.length === 1 ? "" : ` with value ${utils.objDisplay(expected)}`;
return this.assert(
pass,
`expected #{this} to have property "${propertyName}"${valueString}`,
`expected #{this} to not have property "${propertyName}"${valueString}`,
expected,
exists ? value : void 0
);
});
def("toBeCloseTo", function(received, precision = 2) {
const expected = this._obj;
let pass = false;
let expectedDiff = 0;
let receivedDiff = 0;
if (received === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) {
pass = true;
} else if (received === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) {
pass = true;
} else {
expectedDiff = 10 ** -precision / 2;
receivedDiff = Math.abs(expected - received);
pass = receivedDiff < expectedDiff;
}
return this.assert(
pass,
`expected #{this} to be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`,
`expected #{this} to not be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`,
received,
expected,
false
);
});
const assertIsMock = (assertion) => {
if (!isMockFunction(assertion._obj))
throw new TypeError(`${utils.inspect(assertion._obj)} is not a spy or a call to a spy!`);
};
const getSpy = (assertion) => {
assertIsMock(assertion);
return assertion._obj;
};
const ordinalOf = (i) => {
const j = i % 10;
const k = i % 100;
if (j === 1 && k !== 11)
return `${i}st`;
if (j === 2 && k !== 12)
return `${i}nd`;
if (j === 3 && k !== 13)
return `${i}rd`;
return `${i}th`;
};
const formatCalls = (spy, msg, actualCall) => {
if (spy.mock.calls) {
msg += c().gray(`
Received:
${spy.mock.calls.map((callArg, i) => {
let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call:
`);
if (actualCall)
methodCall += diff(actualCall, callArg, { omitAnnotationLines: true });
else
methodCall += stringify(callArg).split("\n").map((line) => ` ${line}`).join("\n");
methodCall += "\n";
return methodCall;
}).join("\n")}`);
}
msg += c().gray(`
Number of calls: ${c().bold(spy.mock.calls.length)}
`);
return msg;
};
const formatReturns = (spy, msg, actualReturn) => {
msg += c().gray(`
Received:
${spy.mock.results.map((callReturn, i) => {
let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:
`);
if (actualReturn)
methodCall += diff(actualReturn, callReturn.value, { omitAnnotationLines: true });
else
methodCall += stringify(callReturn).split("\n").map((line) => ` ${line}`).join("\n");
methodCall += "\n";
return methodCall;
}).join("\n")}`);
msg += c().gray(`
Number of calls: ${c().bold(spy.mock.calls.length)}
`);
return msg;
};
def(["toHaveBeenCalledTimes", "toBeCalledTimes"], function(number) {
const spy = getSpy(this);
const spyName = spy.getMockName();
const callCount = spy.mock.calls.length;
return this.assert(
callCount === number,
`expected "${spyName}" to be called #{exp} times, but got ${callCount} times`,
`expected "${spyName}" to not be called #{exp} times`,
number,
callCount,
false
);
});
def("toHaveBeenCalledOnce", function() {
const spy = getSpy(this);
const spyName = spy.getMockName();
const callCount = spy.mock.calls.length;
return this.assert(
callCount === 1,
`expected "${spyName}" to be called once, but got ${callCount} times`,
`expected "${spyName}" to not be called once`,
1,
callCount,
false
);
});
def(["toHaveBeenCalled", "toBeCalled"], function() {
const spy = getSpy(this);
const spyName = spy.getMockName();
const callCount = spy.mock.calls.length;
const called = callCount > 0;
const isNot = utils.flag(this, "negate");
let msg = utils.getMessage(
this,
[
called,
`expected "${spyName}" to be called at least once`,
`expected "${spyName}" to not be called at all, but actually been called ${callCount} times`,
true,
called
]
);
if (called && isNot)
msg = formatCalls(spy, msg);
if (called && isNot || !called && !isNot)
throw new AssertionError(msg);
});
def(["toHaveBeenCalledWith", "toBeCalledWith"], function(...args) {
const spy = getSpy(this);
const spyName = spy.getMockName();
const pass = spy.mock.calls.some((callArg) => equals(callArg, args, [...customTesters, iterableEquality]));
const isNot = utils.flag(this, "negate");
const msg = utils.getMessage(
this,
[
pass,
`expected "${spyName}" to be called with arguments: #{exp}`,
`expected "${spyName}" to not be called with arguments: #{exp}`,
args
]
);
if (pass && isNot || !pass && !isNot)
throw new AssertionError(formatCalls(spy, msg, args));
});
def(["toHaveBeenNthCalledWith", "nthCalledWith"], function(times, ...args) {
const spy = getSpy(this);
const spyName = spy.getMockName();
const nthCall = spy.mock.calls[times - 1];
const callCount = spy.mock.calls.length;
const isCalled = times <= callCount;
this.assert(
equals(nthCall, args, [...customTesters, iterableEquality]),
`expected ${ordinalOf(times)} "${spyName}" call to have been called with #{exp}${isCalled ? `` : `, but called only ${callCount} times`}`,
`expected ${ordinalOf(times)} "${spyName}" call to not have been called with #{exp}`,
args,
nthCall,
isCalled
);
});
def(["toHaveBeenLastCalledWith", "lastCalledWith"], function(...args) {
const spy = getSpy(this);
const spyName = spy.getMockName();
const lastCall = spy.mock.calls[spy.mock.calls.length - 1];
this.assert(
equals(lastCall, args, [...customTesters, iterableEquality]),
`expected last "${spyName}" call to have been called with #{exp}`,
`expected last "${spyName}" call to not have been called with #{exp}`,
args,
lastCall
);
});
def(["toThrow", "toThrowError"], function(expected) {
if (typeof expected === "string" || typeof expected === "undefined" || expected instanceof RegExp)
return this.throws(expected);
const obj = this._obj;
const promise = utils.flag(this, "promise");
const isNot = utils.flag(this, "negate");
let thrown = null;
if (promise === "rejects") {
thrown = obj;
} else if (promise === "resolves" && typeof obj !== "function") {
if (!isNot) {
const message = utils.flag(this, "message") || "expected promise to throw an error, but it didn't";
const error = {
showDiff: false
};
throw new AssertionError(message, error, utils.flag(this, "ssfi"));
} else {
return;
}
} else {
let isThrow = false;
try {
obj();
} catch (err) {
isThrow = true;
thrown = err;
}
if (!isThrow && !isNot) {
const message = utils.flag(this, "message") || "expected function to throw an error, but it didn't";
const error = {
showDiff: false
};
throw new AssertionError(message, error, utils.flag(this, "ssfi"));
}
}
if (typeof expected === "function") {
const name = expected.name || expected.prototype.constructor.name;
return this.assert(
thrown && thrown instanceof expected,
`expected error to be instance of ${name}`,
`expected error not to be instance of ${name}`,
expected,
thrown
);
}
if (expected instanceof Error) {
return this.assert(
thrown && expected.message === thrown.message,
`expected error to have message: ${expected.message}`,
`expected error not to have message: ${expected.message}`,
expected.message,
thrown && thrown.message
);
}
if (typeof expected === "object" && "asymmetricMatch" in expected && typeof expected.asymmetricMatch === "function") {
const matcher = expected;
return this.assert(
thrown && matcher.asymmetricMatch(thrown),
"expected error to match asymmetric matcher",
"expected error not to match asymmetric matcher",
matcher,
thrown
);
}
throw new Error(`"toThrow" expects string, RegExp, function, Error instance or asymmetric matcher, got "${typeof expected}"`);
});
def(["toHaveReturned", "toReturn"], function() {
const spy = getSpy(this);
const spyName = spy.getMockName();
const calledAndNotThrew = spy.mock.calls.length > 0 && spy.mock.results.some(({ type }) => type !== "throw");
this.assert(
calledAndNotThrew,
`expected "${spyName}" to be successfully called at least once`,
`expected "${spyName}" to not be successfully called`,
calledAndNotThrew,
!calledAndNotThrew,
false
);
});
def(["toHaveReturnedTimes", "toReturnTimes"], function(times) {
const spy = getSpy(this);
const spyName = spy.getMockName();
const successfulReturns = spy.mock.results.reduce((success, { type }) => type === "throw" ? success : ++success, 0);
this.assert(
successfulReturns === times,
`expected "${spyName}" to be successfully called ${times} times`,
`expected "${spyName}" to not be successfully called ${times} times`,
`expected number of returns: ${times}`,
`received number of returns: ${successfulReturns}`,
false
);
});
def(["toHaveReturnedWith", "toReturnWith"], function(value) {
const spy = getSpy(this);
const spyName = spy.getMockName();
const pass = spy.mock.results.some(({ type, value: result }) => type === "return" && equals(value, result));
const isNot = utils.flag(this, "negate");
const msg = utils.getMessage(
this,
[
pass,
`expected "${spyName}" to return with: #{exp} at least once`,
`expected "${spyName}" to not return with: #{exp}`,
value
]
);
if (pass && isNot || !pass && !isNot)
throw new AssertionError(formatReturns(spy, msg, value));
});
def(["toHaveLastReturnedWith", "lastReturnedWith"], function(value) {
const spy = getSpy(this);
const spyName = spy.getMockName();
const { value: lastResult } = spy.mock.results[spy.mock.results.length - 1];
const pass = equals(lastResult, value);
this.assert(
pass,
`expected last "${spyName}" call to return #{exp}`,
`expected last "${spyName}" call to not return #{exp}`,
value,
lastResult
);
});
def(["toHaveNthReturnedWith", "nthReturnedWith"], function(nthCall, value) {
const spy = getSpy(this);
const spyName = spy.getMockName();
const isNot = utils.flag(this, "negate");
const { type: callType, value: callResult } = spy.mock.results[nthCall - 1];
const ordinalCall = `${ordinalOf(nthCall)} call`;
if (!isNot && callType === "throw")
chai.assert.fail(`expected ${ordinalCall} to return #{exp}, but instead it threw an error`);
const nthCallReturn = equals(callResult, value);
this.assert(
nthCallReturn,
`expected ${ordinalCall} "${spyName}" call to return #{exp}`,
`expected ${ordinalCall} "${spyName}" call to not return #{exp}`,
value,
callResult
);
});
def("toSatisfy", function(matcher, message) {
return this.be.satisfy(matcher, message);
});
utils.addProperty(chai.Assertion.prototype, "resolves", function __VITEST_RESOLVES__() {
const error = new Error("resolves");
utils.flag(this, "promise", "resolves");
utils.flag(this, "error", error);
const test = utils.flag(this, "vitest-test");
const obj = utils.flag(this, "object");
if (typeof (obj == null ? void 0 : obj.then) !== "function")
throw new TypeError(`You must provide a Promise to expect() when using .resolves, not '${typeof obj}'.`);
const proxy = new Proxy(this, {
get: (target, key, receiver) => {
const result = Reflect.get(target, key, receiver);
if (typeof result !== "function")
return result instanceof chai.Assertion ? proxy : result;
return async (...args) => {
const promise = obj.then(
(value) => {
utils.flag(this, "object", value);
return result.call(this, ...args);
},
(err) => {
const _error = new AssertionError(
`promise rejected "${utils.inspect(err)}" instead of resolving`,
{ showDiff: false }
);
_error.cause = err;
_error.stack = error.stack.replace(error.message, _error.message);
throw _error;
}
);
return recordAsyncExpect(test, promise);
};
}
});
return proxy;
});
utils.addProperty(chai.Assertion.prototype, "rejects", function __VITEST_REJECTS__() {
const error = new Error("rejects");
utils.flag(this, "promise", "rejects");
utils.flag(this, "error", error);
const test = utils.flag(this, "vitest-test");
const obj = utils.flag(this, "object");
const wrapper = typeof obj === "function" ? obj() : obj;
if (typeof (wrapper == null ? void 0 : wrapper.then) !== "function")
throw new TypeError(`You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`);
const proxy = new Proxy(this, {
get: (target, key, receiver) => {
const result = Reflect.get(target, key, receiver);
if (typeof result !== "function")
return result instanceof chai.Assertion ? proxy : result;
return async (...args) => {
const promise = wrapper.then(
(value) => {
const _error = new AssertionError(
`promise resolved "${utils.inspect(value)}" instead of rejecting`,
{ showDiff: true, expected: new Error("rejected promise"), actual: value }
);
_error.stack = error.stack.replace(error.message, _error.message);
throw _error;
},
(err) => {
utils.flag(this, "object", err);
return result.call(this, ...args);
}
);
return recordAsyncExpect(test, promise);
};
}
});
return proxy;
});
};
function getMatcherState(assertion, expect) {
const obj = assertion._obj;
const isNot = util.flag(assertion, "negate");
const promise = util.flag(assertion, "promise") || "";
const jestUtils = {
...getMatcherUtils(),
diff,
stringify,
iterableEquality,
subsetEquality
};
const matcherState = {
...getState(expect),
customTesters: getCustomEqualityTesters(),
isNot,
utils: jestUtils,
promise,
equals,
// needed for built-in jest-snapshots, but we don't use it
suppressedErrors: []
};
return {
state: matcherState,
isNot,
obj
};
}
class JestExtendError extends Error {
constructor(message, actual, expected) {
super(message);
this.actual = actual;
this.expected = expected;
}
}
function JestExtendPlugin(expect, matchers) {
return (c, utils) => {
Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => {
function expectWrapper(...args) {
const { state, isNot, obj } = getMatcherState(this, expect);
const result = expectAssertion.call(state, obj, ...args);
if (result && typeof result === "object" && result instanceof Promise) {
return result.then(({ pass: pass2, message: message2, actual: actual2, expected: expected2 }) => {
if (pass2 && isNot || !pass2 && !isNot)
throw new JestExtendError(message2(), actual2, expected2);
});
}
const { pass, message, actual, expected } = result;
if (pass && isNot || !pass && !isNot)
throw new JestExtendError(message(), actual, expected);
}
const softWrapper = wrapSoft(utils, expectWrapper);
utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, softWrapper);
utils.addMethod(c.Assertion.prototype, expectAssertionName, softWrapper);
class CustomMatcher extends AsymmetricMatcher {
constructor(inverse = false, ...sample) {
super(sample, inverse);
}
asymmetricMatch(other) {
const { pass } = expectAssertion.call(
this.getMatcherContext(expect),
other,
...this.sample
);
return this.inverse ? !pass : pass;
}
toString() {
return `${this.inverse ? "not." : ""}${expectAssertionName}`;
}
getExpectedType() {
return "any";
}
toAsymmetricMatcher() {
return `${this.toString()}<${this.sample.map(String).join(", ")}>`;
}
}
const customMatcher = (...sample) => new CustomMatcher(false, ...sample);
Object.defineProperty(expect, expectAssertionName, {
configurable: true,
enumerable: true,
value: customMatcher,
writable: true
});
Object.defineProperty(expect.not, expectAssertionName, {
configurable: true,
enumerable: true,
value: (...sample) => new CustomMatcher(true, ...sample),
writable: true
});
Object.defineProperty(globalThis[ASYMMETRIC_MATCHERS_OBJECT], expectAssertionName, {
configurable: true,
enumerable: true,
value: customMatcher,
writable: true
});
});
};
}
const JestExtend = (chai, utils) => {
utils.addMethod(chai.expect, "extend", (expect, expects) => {
chai.use(JestExtendPlugin(expect, expects));
});
};
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 };
+3
View File
@@ -0,0 +1,3 @@
import './dist/chai.cjs'
export * from './dist/index.js'
+47
View File
@@ -0,0 +1,47 @@
{
"name": "@vitest/expect",
"type": "module",
"version": "1.6.1",
"description": "Jest's expect matchers as a Chai plugin",
"license": "MIT",
"funding": "https://opencollective.com/vitest",
"homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/expect#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/vitest-dev/vitest.git",
"directory": "packages/expect"
},
"bugs": {
"url": "https://github.com/vitest-dev/vitest/issues"
},
"sideEffects": false,
"exports": {
".": {
"types": "./index.d.ts",
"default": "./dist/index.js"
},
"./*": "./*"
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./index.d.ts",
"files": [
"*.d.ts",
"dist"
],
"dependencies": {
"chai": "^4.3.10",
"@vitest/utils": "1.6.1",
"@vitest/spy": "1.6.1"
},
"devDependencies": {
"@types/chai": "4.3.6",
"picocolors": "^1.0.0",
"rollup-plugin-copy": "^3.5.0",
"@vitest/runner": "1.6.1"
},
"scripts": {
"build": "rimraf dist && rollup -c",
"dev": "rollup -c --watch"
}
}