vitest-dev / vitest-dev/vitest

Incomplete diff of `toMatchSnapshot(properties)` mismatch error

Open
#9,985 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

pending triage
Dominant language
TypeScript
Stars
17.1k
Forks
2k
Avg merge
1d 21h
Merged PRs (30d)
92

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 actual to only the keys in properties — 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.2
Used Package Manager

npm

Validations

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with test/repro.test.ts, then inspect the properties mismatch path in packages/snapshot/src/client.ts and how packages/utils/src/error.ts renders actual and expected. Determine the intended subset-property diff behavior and add coverage so a valid x field is not shown as an addition while the changed y value remains highlighted.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.