// Copyright 2018-2025 the Deno authors. MIT license.
import type { SnapshotMode, SnapshotOptions } from "./snapshot.ts";
import { diff } from "@std/internal/diff";
import { diffStr } from "@std/internal/diff-str";
import { buildMessage } from "@std/internal/build-message";
export function getErrorMessage(message: string, options: SnapshotOptions) {
return typeof options.msg === "string" ? options.msg : message;
}
/**
* Default serializer for `assertSnapshot`.
*
* @example Usage
* ```ts
* import { serialize } from "@std/testing/snapshot";
* import { assertEquals } from "@std/assert";
*
* assertEquals(serialize({ foo: 42 }), "{\n foo: 42,\n}")
* ```
*
* @param actual The value to serialize
* @returns The serialized string
*/
export function serialize(actual: unknown): string {
return Deno.inspect(actual, {
depth: Infinity,
sorted: true,
trailingComma: true,
compact: false,
iterableLimit: Infinity,
strAbbreviateSize: Infinity,
breakLength: Infinity,
escapeSequences: false,
}).replaceAll("\r", "\\r");
}
/**
* Converts a string to a valid JavaScript string which can be wrapped in backticks.
*
* @example
*
* "special characters (\ ` $) will be escaped" -> "special characters (\\ \` \$) will be escaped"
*/
export function escapeStringForJs(str: string) {
return str
.replace(/\\/g, "\\\\")
.replace(/`/g, "\\`")
.replace(/\$/g, "\\$");
}
let _mode: SnapshotMode;
/**
* Get the snapshot mode.
*/
export function getMode(options: SnapshotOptions) {
if (options.mode) {
return options.mode;
} else if (_mode) {
return _mode;
} else {
_mode = Deno.args.some((arg) => arg === "--update" || arg === "-u")
? "update"
: "assert";
return _mode;
}
}
/**
* Return `true` when snapshot mode is `update`.
*/
export function getIsUpdate(options: SnapshotOptions) {
return getMode(options) === "update";
}
export function getOptions<T>(
msgOrOpts?: string | T,
): T {
if (msgOrOpts === undefined) return {} as T;
if (typeof msgOrOpts === "object" && msgOrOpts !== null) {
return msgOrOpts;
}
return { msg: msgOrOpts } as T;
}
export function getSnapshotNotMatchMessage(
actualSnapshot: string,
expectedSnapshot: string,
options: SnapshotOptions,
) {
const stringDiff = !actualSnapshot.includes("\n");
const diffResult = stringDiff
? diffStr(actualSnapshot, expectedSnapshot)
: diff(actualSnapshot.split("\n"), expectedSnapshot.split("\n"));
const diffMsg = buildMessage(diffResult, { stringDiff }).join("\n");
const message =
`Snapshot does not match:\n${diffMsg}\nTo update snapshots, run\n deno test --allow-read --allow-write [files]... -- --update\n`;
return getErrorMessage(message, options);
}
// TODO (WWRS): Remove this when we drop support for Deno 1.x
export const LINT_SUPPORTED = !Deno.version.deno.startsWith("1.");
|