Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 12, 2025

Problem

When using expect.soft() assertions, error diffs were generated using default options instead of respecting the user's custom diff configuration from vitest.config.ts. This meant that options like test.diff.printBasicPrototype were ignored for soft assertion failures, while regular assertions correctly applied these settings.

For example, with this configuration:

// vitest.config.ts
export default defineConfig({
  test: {
    diff: {
      printBasicPrototype: true,
    },
  },
})

Regular assertions would show diffs with Object { and Array [ prefixes, but soft assertions would not.

Root Cause

In packages/expect/src/utils.ts, the handleTestError function was calling processError(err) without passing the diffOptions parameter. This caused soft assertion errors to be processed with default diff settings regardless of the user's configuration.

Solution

This PR makes two minimal changes:

  1. Export getRunner from @vitest/runner - Makes the runner instance accessible to other packages that need to access runtime configuration.

  2. Pass diffOptions when processing soft assertion errors - The handleTestError function now retrieves the runner's config and passes diffOptions to processError(), ensuring soft assertions respect the user's diff configuration.

Testing

  • Added a new test case specifically for soft assertions with custom diff config
  • Updated existing test snapshots to reflect the correct behavior
  • Verified all existing tests pass (custom diff config tests, soft assertion tests, etc.)
  • Confirmed linting and type checking pass

This fix ensures consistent diff formatting across all assertion types (regular and soft), providing a better developer experience when viewing test failures in any reporter or IDE integration.

Closes #XXXX

Original prompt

This section details on the original issue you should resolve

<issue_title>[Reporter] IntelliJ diff view ignores Vitest config options – shows default diff (e.g. test.diff.printBasicPrototype)</issue_title>
<issue_description>### Describe the bug

1. What the problem actually is

When a test fails, Intellij Vitest Plugin shows an “AssertionError” that contains a link called “”. In the IntelliJ (possibly the VS Code extension) clicking that link opens a diff view that is built from the
err.expected and err.actual values which are set here https://github.com/vitest-dev/vitest/blob/main/packages/utils/src/error.ts#L31-L36

The diff view is rendered by pretty‑format (see packages/pretty-format/src/index.ts#L521).
That function receives a set of diff options (DiffOptions) that come from the user’s
vitest.config.ts.
In the current implementation of processError (see packages/utils/src/error.ts) those options
are never forwarded to the stringifier:

if ('expected' in err && typeof err.expected !== 'string') {
  err.expected = stringify(err.expected, 10)   // ← no diffOptions
}
if ('actual' in err && typeof err.actual !== 'string') {
  err.actual = stringify(err.actual, 10)       // ← no diffOptions
}

Because the options are omitted, pretty‑format falls back to its default diff behaviour
(maxDepth: 10, showDiff: true …).
That means the diff that IntelliJ shows ignores any configuration you set in
vitest.config.ts (e.g. maxDepth, showDiff, truncateThreshold, etc.)


2. Where the same pattern shows up elsewhere

File Location What it does Why it matters
packages/utils/src/error.ts lines 31‑36 (current code) Builds a stringified representation of expected/actual for the error message. Diff options are not passed, so defaults win.
packages/pretty-format/src/index.ts line 521 The default stringifier that is used when stringify() is called without options. It uses hard‑coded defaults (maxDepth: 10, showDiff: true).
packages/utils/src/error.ts (issue #5353) lines 41‑48 in the PR that fixed snapshot diffs err.actual = getObjectSubset(replacedActual, replacedExpected); followed by diff(...) with { ...diffOptions, ...err.diffOptions }. Shows the correct pattern: merge user‑defined diffOptions with any per‑error overrides.
packages/utils/src/error.ts (issue #5073) large‑diff handling Uses the same stringify(err.expected, 10) pattern. Demonstrates that this omission is not isolated to one file.

The PR for #5353 (see the comment “After patching the processError function”) is a perfect
reference for how to merge the configuration:

err.diff = printDiffOrStringify(err.actual, err.expected, {
  ...diffOptions,
  ...err.diffOptions as DiffOptions,
})

3. Proposed fix

// packages/utils/src/error.ts

export function processError(
  _err: any,
  diffOptions?: DiffOptions,
  seen: WeakSet<WeakKey> = new WeakSet(),
): any {
  if (!_err || typeof _err !== 'object') {
    return { message: String(_err) }
  }

  const err = _err as TestError

  // Build the diff string once we know we need it
  if (
    err.showDiff ||
    (err.showDiff === undefined &&
      err.expected !== undefined &&
      err.actual !== undefined)
  ) {
    err.diff = printDiffOrStringify(err.actual, err.expected, {
      ...diffOptions,
      ...err.diffOptions as DiffOptions,
    })
  }

  // *** NEW: pass diffOptions to stringify ***
  if ('expected' in err && typeof err.expected !== 'string') {
    // The stringify call now receives the same options that were used for the diff
    err.expected = stringify(err.expected, 10, diffOptions)
  }
  if ('actual' in err && typeof err.actual !== 'string') {
    err.actual = stringify(err.actual, 10, diffOptions)
  }

  // … rest of the function unchanged …
}

Why this works

  • stringify(value, depth, options?) accepts a third argument – the same
    DiffOptions that pretty‑format uses for diffs.
  • By forwarding the user’s configuration, IntelliJ will now render the diff exactly
    as configured in vitest.config.ts.
  • The change is backwards‑compatible: if no options are supplied, the default
    behaviour remains unchanged.

4. Quick‑start test

Add a unit test in packages/utils/test/error.test.ts:

import { processError } from '../src/error'
import type { DiffOptions } from '../src/diff'

test('processError respects diffOptions', () => {
  const err = {
    expected: { a: 1, b: 2 },
    actual:   { a: 1, b: 3 },
    showDiff: true,
  }

  const diffOptions: DiffOptions = { maxDepth: 1, showDiff: true }
  const processed = processError(err as any, diffOptions)

  // The stringified values should now be truncated to depth 1
  expect(processed.expected).toBe('{ a: 1, b: … }')
  expect(p...

</details>

Fixes vitest-dev/vitest#8691

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.

@netlify
Copy link

netlify bot commented Oct 12, 2025

Deploy Preview for vitest-dev ready!

Name Link
🔨 Latest commit 20c94f9
🔍 Latest deploy log https://app.netlify.com/projects/vitest-dev/deploys/68eb906c7e0b3c0008a15a0a
😎 Deploy Preview https://deploy-preview-8696--vitest-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

- Export getRunner from @vitest/runner to make it accessible
- Import getRunner in expect package utils
- Pass runner.config.diffOptions to processError in handleTestError
- Add test for soft assertions with custom diff config
- Update snapshots to reflect the fix

Co-authored-by: sheremet-va <[email protected]>
Copilot AI changed the title [WIP] Fix IntelliJ diff view to respect Vitest config options fix: respect diff config options in soft assertions Oct 12, 2025
Copilot AI requested a review from sheremet-va October 12, 2025 11:46
Copilot finished work on behalf of sheremet-va October 12, 2025 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants