-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Incomplete diff of toMatchSnapshot(properties) mismatch error #9985
Description
Describe the bug
(not sure how to describe, so 🤖's best shot. repro is mine though.)
When toMatchSnapshot(properties) fails, the diff misleadingly shows fields like x as additions, as if they shouldn't be there. But x is a valid part of the object — the only actual problem is that y changed from 5 to 10. The diff should focus on the mismatched values, not imply that extra fields are wrong.
- repro.test.ts
import { expect, test } from 'vitest';
test('example', () => {
// initially snapshot created with
// { x: 'hello', y: 5 }
expect({ x: 'world', y: 10 }).toMatchSnapshot({ y: 5 });
});Test run:
FAIL test/repro.test.ts > example
Error: Snapshot properties mismatched
- Expected
+ Received
{
- "y": 5,
+ "x": "world",
+ "y": 10,
}
❯ test/repro.test.ts:6:33
4| // initially snapshot created with
5| // { x: 'hello', y: 5 }
6| expect({ x: 'world', y: 10 }).toMatchSnapshot({ y: 5 });
| ^
7| });
8|
❯ new Promise ../../../blitz.4c73681d.js:31:30606🤖 Root cause and suggestions
In packages/snapshot/src/client.ts, the properties mismatch error passes received and properties as actual/expected:
if (!propertiesPass) {
return {
pass: false,
message: () => 'Snapshot properties mismatched',
actual: received, // full object
expected: properties, // subset — missing fields show as additions
}
}The diff is generated downstream by processError (packages/utils/src/error.ts), which just calls printDiffOrStringify(err.actual, err.expected). It has no knowledge of snapshot semantics — it faithfully diffs the two values it's given. So the fix needs to happen at the source, not in the diff renderer.
This is inherently tricky because the properties check is a subset equality — the user intentionally provides fewer keys than the full object. There's no "correct full expected" available at this point (the previous snapshot isn't loaded yet since snapshotState.match() hasn't been called).
Possible approaches:
- Filter
actualto only the keys inproperties— diff becomes{ length: 11 }vs{ length: 6 }. Clean and focused on what the user cares about, but loses context of the full object. - Load the previous snapshot first to construct a full expected value — more accurate but adds complexity and couples the properties check to snapshot state.
Reproduction
https://stackblitz.com/edit/vitest-dev-vitest-xnjrwzha?file=test%2Frepro.test.ts
System Info
System:
OS: Linux 5.0 undefined
CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 0 Bytes / 0 Bytes
Shell: 1.0 - /bin/jsh
Binaries:
Node: 22.22.0 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 10.8.2 - /usr/local/bin/npm
pnpm: 8.15.6 - /usr/local/bin/pnpm
npmPackages:
@vitest/ui: latest => 4.1.2
vite: latest => 8.0.3
vitest: latest => 4.1.2Used Package Manager
npm
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.