diff --git a/expect/_build_message.ts b/expect/_build_message.ts index 4678a46eb106..059b30de6a2b 100644 --- a/expect/_build_message.ts +++ b/expect/_build_message.ts @@ -6,10 +6,19 @@ import { diffStr } from "@std/internal/diff-str"; import { format } from "@std/internal/format"; import type { EqualOptions } from "./_types.ts"; -type EqualErrorMessageOptions = Pick< - EqualOptions, - "formatter" | "msg" ->; +type EqualErrorMessageOptions = + & Pick< + EqualOptions, + "formatter" | "msg" + > + & { + /** + * Overrides the default "Values are not equal." headline. Set by matchers + * (such as toMatchObject) that don't actually test for equality and would + * otherwise mislead the reader. + */ + summary?: string; + }; function isString(value: unknown): value is string { return typeof value === "string"; @@ -20,12 +29,13 @@ export function buildEqualErrorMessage( expected: T, options: EqualErrorMessageOptions = {}, ): string { - const { formatter = format, msg } = options; + const { formatter = format, msg, summary = "Values are not equal." } = + options; const msgPrefix = msg ? `${msg}: ` : ""; const actualString = formatter(actual); const expectedString = formatter(expected); - let message = `${msgPrefix}Values are not equal.`; + let message = `${msgPrefix}${summary}`; const stringDiff = isString(actual) && isString(expected); const diffResult = stringDiff diff --git a/expect/_matchers.ts b/expect/_matchers.ts index 3c74bf0b7047..f53244ee0065 100644 --- a/expect/_matchers.ts +++ b/expect/_matchers.ts @@ -603,7 +603,12 @@ export function toMatchObject( ); } else { const subset = getObjectSubset(received, expected, context.customTesters); - const defaultMessage = buildEqualErrorMessage(subset, expected); + // toMatchObject is a subset check, not equality. Override the default + // "Values are not equal." headline so the failure message describes + // what actually went wrong (see #6999). + const defaultMessage = buildEqualErrorMessage(subset, expected, { + summary: "Object does not match the expected pattern.", + }); throw new AssertionError( context.customMessage ? `${context.customMessage}: ${defaultMessage}` diff --git a/expect/_to_match_object_test.ts b/expect/_to_match_object_test.ts index 8b58b360a21f..0cbc55ddceb9 100644 --- a/expect/_to_match_object_test.ts +++ b/expect/_to_match_object_test.ts @@ -299,3 +299,19 @@ Deno.test("expect().toMatchObject() displays a diff", async (t) => { assertMatch(e.message, /999/); }); }); + +Deno.test( + "expect().toMatchObject() failure headline describes a subset match, not equality (#6999)", + () => { + const e = assertThrows( + () => + expect({ position: { x: 0, y: "string" } }) + .toMatchObject({ position: { x: 0, y: 0 } }), + AssertionError, + ); + // The headline must not claim equality, because toMatchObject is a + // subset check. The diff body is still produced by the same helper. + assertMatch(e.message, /Object does not match the expected pattern\./); + assertNotMatch(e.message, /Values are not equal\./); + }, +);