diff --git a/expect/_serializer.ts b/expect/_serializer.ts new file mode 100644 index 000000000000..bcccdce65b6d --- /dev/null +++ b/expect/_serializer.ts @@ -0,0 +1,15 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import type { SnapshotPlugin } from "./_types.ts"; + +const INTERNAL_PLUGINS: SnapshotPlugin[] = [ + // TODO(eryue0220): support internal snapshot serializer plugins +]; + +export function addSerializer(plugin: SnapshotPlugin) { + INTERNAL_PLUGINS.unshift(plugin); +} + +export function getSerializer() { + return INTERNAL_PLUGINS; +} diff --git a/expect/_serializer_test.ts b/expect/_serializer_test.ts new file mode 100644 index 000000000000..129e7b51902d --- /dev/null +++ b/expect/_serializer_test.ts @@ -0,0 +1,23 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { expect } from "./expect.ts"; +import { addSerializer, getSerializer } from "./_serializer.ts"; +import type { SnapshotPlugin } from "./_types.ts"; + +const foo: SnapshotPlugin = { + serialize() { + return "foot"; + }, + test() { + return false; + }, +}; + +Deno.test("initial serializer", () => { + expect(getSerializer()).toHaveLength(0); +}); + +Deno.test("add serializer", () => { + addSerializer(foo); + expect(getSerializer()).toHaveLength(1); +}); diff --git a/expect/_types.ts b/expect/_types.ts index 9dcefc120c3d..726ec6a8346e 100644 --- a/expect/_types.ts +++ b/expect/_types.ts @@ -915,3 +915,5 @@ export interface OldSnapshotPlugin { ) => string; test: Test; } + +export type SnapshotPlugin = NewSnapshotPlugin | OldSnapshotPlugin; diff --git a/expect/expect.ts b/expect/expect.ts index 9e9e72cc0928..e68224aeb505 100644 --- a/expect/expect.ts +++ b/expect/expect.ts @@ -59,9 +59,10 @@ import { toStrictEqual, toThrow, } from "./_matchers.ts"; +import { addSerializer } from "./_serializer.ts"; import { isPromiseLike } from "./_utils.ts"; import * as asymmetricMatchers from "./_asymmetric_matchers.ts"; -import type { Tester } from "./_types.ts"; +import type { SnapshotPlugin, Tester } from "./_types.ts"; export type { AnyConstructor, Async, Expected } from "./_types.ts"; @@ -599,3 +600,21 @@ expect.not = { stringContaining: asymmetricMatchers.stringNotContaining, stringMatching: asymmetricMatchers.stringNotMatching, }; +/** + * `expect.addSnapshotSerializer` adds a module that formats application-specific data structures. + * + * For an individual test file, an added module precedes any modules from snapshotSerializers configuration, + * which precede the default snapshot serializers for built-in JavaScript types. + * The last module added is the first module tested. + * + * @example + * ```ts no-eval + * import { expect } from "@std/expect"; + * import serializerAnsi from "npm:jest-snapshot-serializer-ansi"; + * + * expect.addSnapshotSerializer(serializerAnsi); + * ``` + */ +expect.addSnapshotSerializer = addSerializer as ( + plugin: SnapshotPlugin, +) => void; diff --git a/expect/mod.ts b/expect/mod.ts index 14db8df92f35..4293027ba5af 100644 --- a/expect/mod.ts +++ b/expect/mod.ts @@ -63,6 +63,7 @@ * - {@linkcode expect.stringMatching} * - {@linkcode expect.not.stringMatching} * - Utilities: + * - {@linkcode expect.addSnapshotSerializer} * - {@linkcode expect.assertions} * - {@linkcode expect.addEqualityTester} * - {@linkcode expect.extend} @@ -74,8 +75,6 @@ * - `toMatchInlineSnapshot` * - `toThrowErrorMatchingSnapshot` * - `toThrowErrorMatchingInlineSnapshot` - * - Utilities: - * - `expect.addSnapshotSerializer` * * The tracking issue to add support for unsupported parts of the API is * {@link https://github.com/denoland/std/issues/3964}.