Skip to content
Open
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
15 changes: 15 additions & 0 deletions assert/equals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,20 @@ export function assertEquals<T>(
const diffMsg = buildMessage(diffResult, { stringDiff }, arguments[3])
.join("\n");
message = `${message}\n${diffMsg}`;
// #6878: if the diff shows no removed/added lines, the values stringify
// identically but were still deemed unequal — typically because at least
// one nested property is a function (or Promise / Request / Blob / etc.)
// that gets compared by reference. The empty diff is confusing, so append
// a hint pointing at the likely cause.
if (
!stringDiff &&
diffResult.every((r) => r.type !== "added" && r.type !== "removed")
) {
message = `${message}\n` +
" Note: values stringify identically but are not structurally equal. " +
"Functions, Promises, Requests, Blobs, and other built-ins are compared by " +
"reference, so two distinct instances are never equal even when their " +
"representations match.";
}
throw new AssertionError(message);
}
49 changes: 48 additions & 1 deletion assert/equals_test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
// Copyright 2018-2026 the Deno authors. MIT license.
import { assertEquals, AssertionError, assertThrows } from "./mod.ts";
import {
assertEquals,
AssertionError,
assertStringIncludes,
assertThrows,
} from "./mod.ts";
import {
bold,
gray,
Expand Down Expand Up @@ -207,6 +212,48 @@ Deno.test({
},
});

Deno.test({
name:
"assertEquals() hints at reference-equality when objects with function props stringify identically (#6878)",
fn() {
let caught: AssertionError | undefined;
try {
assertEquals(
{ x: 1, y: () => 2 },
{ x: 1, y: () => 2 },
);
} catch (e) {
caught = e as AssertionError;
}
if (!caught) throw new Error("Expected assertEquals to throw");
assertStringIncludes(caught.message, "Values are not equal");
assertStringIncludes(
caught.message,
"stringify identically but are not structurally equal",
);
assertStringIncludes(caught.message, "compared by reference");
},
});

Deno.test({
name:
"assertEquals() does not append reference-equality hint when there is a real textual diff",
fn() {
let caught: AssertionError | undefined;
try {
assertEquals({ x: 1 }, { x: 2 });
} catch (e) {
caught = e as AssertionError;
}
if (!caught) throw new Error("Expected assertEquals to throw");
assertEquals(
caught.message.includes("stringify identically"),
false,
"Hint should only fire when the diff is empty",
);
},
});

Deno.test({
name: "assertEquals() matches same Set with object keys",
fn() {
Expand Down
Loading