-
Notifications
You must be signed in to change notification settings - Fork 676
fix(assert): hint at reference-equality when assertEquals diff is empty (#6878) #7158
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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."; | ||
|
Comment on lines
+76
to
+80
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: the |
||
| } | ||
| throw new AssertionError(message); | ||
| } | ||
| 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, | ||
|
|
@@ -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"); | ||
| }, | ||
|
Comment on lines
+219
to
+235
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style nit: this file already imports const error = assertThrows(
() => assertEquals({ x: 1, y: () => 2 }, { x: 1, y: () => 2 }),
AssertionError,
);
assertStringIncludes(error.message, "Values are not equal");
assertStringIncludes(error.message, "stringify identically but are not structurally equal");
assertStringIncludes(error.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", | ||
| ); | ||
|
Comment on lines
+242
to
+253
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same |
||
| }, | ||
| }); | ||
|
|
||
| Deno.test({ | ||
| name: "assertEquals() matches same Set with object keys", | ||
| fn() { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DiffResult.typeis"added" | "removed" | "common", so this reads more directly asdiffResult.every((r) => r.type === "common").