Enhanced expect assertion library with Jest's snapshot testing matchers for comprehensive test assertions
npx @tessl/cli install tessl/npm-jest--expect@30.1.0@jest/expect extends the core expect assertion library with Jest's powerful snapshot testing capabilities. It provides a drop-in replacement for the standard expect function that includes all core functionality plus specialized snapshot matchers for testing complex data structures and error outputs.
npm install @jest/expectimport { jestExpect } from "@jest/expect";For CommonJS:
const { jestExpect } = require("@jest/expect");Type imports:
import type {
JestExpect,
AsymmetricMatchers,
Matchers,
MatcherContext,
MatcherFunction,
MatcherFunctionWithContext,
MatcherState,
MatcherUtils
} from "@jest/expect";import { jestExpect } from "@jest/expect";
// Use as drop-in replacement for expect
const user = { name: "Alice", age: 25, settings: { theme: "dark" } };
// Standard expect functionality works
jestExpect(user.name).toBe("Alice");
jestExpect(user.age).toBeGreaterThan(18);
// Snapshot testing for complex objects
jestExpect(user).toMatchSnapshot();
// Inline snapshots
jestExpect(user.settings).toMatchInlineSnapshot(`
{
"theme": "dark"
}
`);
// Error snapshot testing
const throwingFunction = () => {
throw new Error("Something went wrong");
};
jestExpect(throwingFunction).toThrowErrorMatchingSnapshot();@jest/expect is built as a lightweight bridge between two core Jest libraries:
expect assertion library that provides all standard matchers, asymmetric matchers, and core assertion functionalityjest-snapshot to add specialized snapshot testing matchers and serialization capabilitiesjestExpect function that combines both libraries into one cohesive APIaddSnapshotSerializer method for formatting specific data typesThe package acts as an enhanced drop-in replacement for the standard expect function, maintaining full compatibility while adding Jest's powerful snapshot testing features.
Enhanced expect function with full compatibility with standard expect plus snapshot testing capabilities.
/**
* Enhanced expect function with snapshot testing capabilities
* @param actual - The value to make assertions against
* @returns Matcher object with all standard and snapshot matchers
*/
function jestExpect<T = unknown>(
actual: T
): JestMatchers<void, T> &
Inverse<JestMatchers<void, T>> &
PromiseMatchers<T>;Compare received value against stored snapshot file.
/**
* Compare value against stored snapshot
* @param hint - Optional hint for snapshot name
* @returns Matcher result
*/
toMatchSnapshot(hint?: string): void;
/**
* Compare value against stored snapshot with property matchers
* @param propertyMatchers - Matchers for specific object properties
* @param hint - Optional hint for snapshot name
* @returns Matcher result
*/
toMatchSnapshot<U extends Record<keyof T, unknown>>(
propertyMatchers: Partial<U>,
hint?: string
): void;Compare received value against inline snapshot in source code.
/**
* Compare value against inline snapshot in source code
* @param snapshot - Optional inline snapshot string
* @returns Matcher result
*/
toMatchInlineSnapshot(snapshot?: string): void;
/**
* Compare value against inline snapshot with property matchers
* @param propertyMatchers - Matchers for specific object properties
* @param snapshot - Optional inline snapshot string
* @returns Matcher result
*/
toMatchInlineSnapshot<U extends Record<keyof T, unknown>>(
propertyMatchers: Partial<U>,
snapshot?: string
): void;Test that functions throw errors matching stored or inline snapshots.
/**
* Test that function throws error matching stored snapshot
* @param hint - Optional hint for snapshot name
* @returns Matcher result
*/
toThrowErrorMatchingSnapshot(hint?: string): void;
/**
* Test that function throws error matching inline snapshot
* @param snapshot - Optional inline snapshot string
* @returns Matcher result
*/
toThrowErrorMatchingInlineSnapshot(snapshot?: string): void;Enhanced promise testing with snapshot support.
interface PromiseMatchers<T = unknown> {
/**
* Unwraps the reason of a rejected promise so any other matcher can be chained.
* If the promise is fulfilled the assertion fails.
*/
rejects: JestMatchers<Promise<void>, T> & Inverse<JestMatchers<Promise<void>, T>>;
/**
* Unwraps the value of a fulfilled promise so any other matcher can be chained.
* If the promise is rejected the assertion fails.
*/
resolves: JestMatchers<Promise<void>, T> & Inverse<JestMatchers<Promise<void>, T>>;
}Usage Examples:
// Test rejected promise with snapshot
await jestExpect(Promise.reject(new Error("Failed")))
.rejects.toThrowErrorMatchingSnapshot();
// Test resolved promise value
await jestExpect(Promise.resolve({ success: true }))
.resolves.toMatchSnapshot();Add custom serializers for snapshot formatting.
/**
* Add custom snapshot serializer for specific data types
* @param plugin - Pretty format plugin (NewPlugin or OldPlugin)
*/
jestExpect.addSnapshotSerializer(plugin: Plugin): void;
/**
* Pretty format plugin interface - modern format
*/
interface NewPlugin {
/** Test if serializer should handle this value */
test(val: any): boolean;
/** Serialize the value to string representation */
serialize(
val: any,
config: Config,
indentation: string,
depth: number,
refs: Refs,
printer: Printer
): string;
}
/**
* Pretty format plugin interface - legacy format
*/
interface OldPlugin {
/** Test if serializer should handle this value */
test(val: any): boolean;
/** Print the value using legacy format */
print(
val: unknown,
print: Print,
indent: Indent,
options: PluginOptions,
colors: Colors
): string;
}
/**
* Plugin can be either modern or legacy format
*/
type Plugin = NewPlugin | OldPlugin;Usage Examples:
// Add custom serializer for Date objects (NewPlugin format)
jestExpect.addSnapshotSerializer({
test: (val) => val instanceof Date,
serialize: (val, config, indentation, depth, refs, printer) =>
`Date("${val.toISOString()}")`,
});
// Or using legacy format (OldPlugin)
jestExpect.addSnapshotSerializer({
test: (val) => val instanceof Date,
print: (val, print, indent, options, colors) =>
`Date("${val.toISOString()}")`,
});
// Now Date objects will be formatted consistently in snapshots
jestExpect(new Date('2023-01-01')).toMatchSnapshot();/**
* Main JestExpect interface extending BaseExpect with snapshot capabilities
*/
type JestExpect = {
<T = unknown>(
actual: T,
): JestMatchers<void, T> &
Inverse<JestMatchers<void, T>> &
PromiseMatchers<T>;
addSnapshotSerializer: typeof addSerializer;
} & BaseExpect &
AsymmetricMatchers &
Inverse<Omit<AsymmetricMatchers, 'any' | 'anything'>>;
/**
* Combined matchers including core expect matchers and snapshot matchers
*/
type JestMatchers<R extends void | Promise<void>, T> = Matchers<R, T> & SnapshotMatchers<R, T>;
/**
* Asymmetric matcher utilities from expect
*/
interface AsymmetricMatchers {
any(sample: unknown): AsymmetricMatcher<unknown>;
anything(): AsymmetricMatcher<unknown>;
arrayContaining<E = unknown>(sample: readonly E[]): AsymmetricMatcher<unknown>;
objectContaining<E = {}>(sample: E): AsymmetricMatcher<unknown>;
stringContaining(sample: string): AsymmetricMatcher<unknown>;
stringMatching(sample: string | RegExp): AsymmetricMatcher<unknown>;
}
/**
* Core matcher context provided to matcher functions
*/
interface MatcherContext {
dontThrow?(): void;
isNot: boolean;
promise: string;
}
/**
* State object containing matcher execution information
*/
interface MatcherState {
assertionCalls: number;
currentTestName?: string;
expand?: boolean;
expectedAssertionsNumber?: number | null;
expectedAssertionsNumberError?: Error;
isExpectingAssertions?: boolean;
isExpectingAssertionsError?: Error;
isNot: boolean;
promise: string;
suppressedErrors: Error[];
testPath?: string;
snapshotState: SnapshotState;
testFailing?: boolean;
}
/**
* Utility functions available to matcher implementations
*/
interface MatcherUtils {
customTesters: Array<any>;
dontThrow(): void;
equals(a: unknown, b: unknown): boolean;
utils: {
diff(a: unknown, b: unknown): string | null;
ensureNoExpected(expected: unknown, matcherName: string): void;
ensureNumbers(actual: unknown, expected: unknown, matcherName: string): void;
matcherErrorMessage(hint: string, generic: string, specific: string): string;
matcherHint(matcherName: string, received?: string, expected?: string): string;
pluralize(word: string, count: number): string;
printExpected(value: unknown): string;
printReceived(value: unknown): string;
printWithType(name: string, value: unknown, print: (value: unknown) => string): string;
stringify(object: unknown): string;
EXPECTED_COLOR(text: string): string;
RECEIVED_COLOR(text: string): string;
};
}
/**
* Base matcher function signature
*/
type MatcherFunction<State extends MatcherState = MatcherState> = (
this: MatcherContext & MatcherUtils & State,
received: unknown,
expected: unknown,
...args: unknown[]
) => any;
/**
* Matcher function that explicitly receives context
*/
type MatcherFunctionWithContext<
State extends MatcherState = MatcherState,
Context extends MatcherContext = MatcherContext
> = (
this: MatcherUtils & State,
context: Context,
received: unknown,
expected: unknown,
...args: unknown[]
) => any;
/**
* Supporting types for plugin system
*/
type Refs = Array<unknown>;
type Print = (arg: unknown) => string;
type Indent = (arg: string) => string;
type Printer = (
val: unknown,
config: Config,
indentation: string,
depth: number,
refs: Refs,
hasCalledToJSON?: boolean
) => string;
interface Config {
callToJSON: boolean;
colors: Colors;
escapeRegex: boolean;
escapeString: boolean;
indent: string;
maxDepth: number;
maxWidth: number;
min: boolean;
plugins: Plugin[];
printFunctionName: boolean;
spacingInner: string;
spacingOuter: string;
}
interface Colors {
comment: { close: string; open: string };
content: { close: string; open: string };
prop: { close: string; open: string };
tag: { close: string; open: string };
value: { close: string; open: string };
}
interface PluginOptions {
edgeSpacing: string;
min: boolean;
spacing: string;
}