Skip to content

feat(testing/unstable): add assertInlineSnapshot() #6530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
May 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _tools/lint_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ export default {
if (url.href.includes("/testing/mock.ts")) return {};
if (url.href.includes("/testing/unstable_stub.ts")) return {};
if (url.href.includes("/testing/snapshot.ts")) return {};
if (url.href.includes("/testing/unstable_snapshot.ts")) return {};

// exports from private utils don't need to follow this rule
if (url.href.includes("/_")) return {};
Expand Down
104 changes: 104 additions & 0 deletions testing/_snapshot_utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// 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;

Check warning on line 85 in testing/_snapshot_utils.ts

View check run for this annotation

Codecov / codecov/patch

testing/_snapshot_utils.ts#L85

Added line #L85 was not covered by tests
}

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.");
1 change: 1 addition & 0 deletions testing/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"./time": "./time.ts",
"./types": "./types.ts",
"./unstable-bdd": "./unstable_bdd.ts",
"./unstable-snapshot": "./unstable_snapshot.ts",
"./unstable-stub": "./unstable_stub.ts",
"./unstable-types": "./unstable_types.ts"
}
Expand Down
Loading
Loading