Skip to content

fix(test): preserve string-literal tabs in convertTabsToSpaces#1559

Merged
fengmk2 merged 3 commits into
mainfrom
fix/inline-snapshot-tab-indent
May 12, 2026
Merged

fix(test): preserve string-literal tabs in convertTabsToSpaces#1559
fengmk2 merged 3 commits into
mainfrom
fix/inline-snapshot-tab-indent

Conversation

@fengmk2
Copy link
Copy Markdown
Member

@fengmk2 fengmk2 commented May 12, 2026

Summary

  • convertTabsToSpaces() in packages/test/build.ts did a blanket \t → 2-space rewrite over every dist .js file. Upstream @vitest/snapshot decides multi-line inline snapshot indentation with indent.includes("\t") where the "\t" is a literal tab byte in the bundled source. The blanket replace turned that into indent.includes(" "), so any 2+ space indent matched and the tab-appending branch always ran — producing tab-indented snapshots inside 2-space-indented test files.
  • Restrict the replacement to leading tabs only via /^\t+/gm. Indentation is still normalized (downstream patches that rely on space indent keep working), but tabs inside string and template literals are now preserved.

Root cause (byte-level)

Upstream @vitest/snapshot/dist/index.js:369:

\t const indentNext = indent.includes("<TAB>") ? `${indent}\t` : `${indent}  `;

The <TAB> inside the includes(...) string is a real 0x09 byte. The \t in the template literal is the 2-char escape sequence (\ + t).

Before the fix, convertTabsToSpaces rewrote both the leading tab AND the literal tab byte inside the string to two spaces. The escape sequence was untouched. Result at runtime:

  • indent.includes(" ") is true for any 2+ space indent
  • Snapshot lines get appended with ${indent}\t → a real tab byte

After the fix only leading tabs are rewritten; the string-literal tab survives.

Test plan

  • Unit regression test in packages/test/__tests__/build-artifacts.spec.ts asserts the bundled snapshot file preserves indent.includes("\t") with a literal tab byte (passes after fix, fails before).
  • Snap test in packages/cli/snap-tests/test-inline-snapshot-indent/ reproduces the issue's exact reproduction steps (vp test run -u on a 2-space-indented file) and captures the rewritten file content. Verified that reverting the fix produces a snap.txt containing real tabs (<4 spaces><TAB>"alpha) while the fixed build produces 6-space indentation.
  • All 6 packages/test unit tests pass.
  • vp check --fix is clean.

Closes #1553


Note

Medium Risk
Touches the test package build post-processing (convertTabsToSpaces) which rewrites generated dist artifacts; a regex mistake could subtly change bundled code semantics beyond formatting, but the change is narrowly scoped and covered by new regression tests.

Overview
Fixes a dist-build formatting step so it only converts leading tab indentation to spaces, instead of rewriting all tab bytes and accidentally altering string/template literal contents.

Adds regression coverage for inline snapshot indentation: a new build-artifact assertion ensures @vitest/snapshot still contains indent.includes("\t"), and a new CLI snap-test reproduces vp test run -u updating an inline snapshot in a 2-space-indented file to verify the written snapshot stays space-indented (not tab-indented).

Reviewed by Cursor Bugbot for commit 4eb4ed1. Configure here.

@fengmk2 fengmk2 self-assigned this May 12, 2026
@netlify
Copy link
Copy Markdown

netlify Bot commented May 12, 2026

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit 8395fe0
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a02ea5dbf5e3d0008c158d9

@fengmk2 fengmk2 requested a review from Brooooooklyn May 12, 2026 08:12
@fengmk2
Copy link
Copy Markdown
Member Author

fengmk2 commented May 12, 2026

@cursor review

@fengmk2 fengmk2 marked this pull request as ready for review May 12, 2026 08:12
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 4eb4ed1. Configure here.

fengmk2 added 3 commits May 12, 2026 16:50
The build step `convertTabsToSpaces()` did a blanket `\t` → 2-space
rewrite over every dist .js file. Upstream `@vitest/snapshot` decides
multi-line inline snapshot indentation via `indent.includes("\t")`,
where the `"\t"` is a literal tab byte in the bundled source. The
blanket replace turned that into `indent.includes("  ")`, so every
2-space indent matched and the tab-appending branch always ran —
producing tab-indented snapshots in 2-space files.

Restrict the replacement to leading tabs only via `/^\t+/gm`.
Indentation is still normalized (downstream patches that rely on
space indent keep working), but tabs inside string and template
literals are now preserved.

Adds two regression tests:
- `packages/test/__tests__/build-artifacts.spec.ts` asserts the
  bundled snapshot file keeps the literal tab inside
  `indent.includes("\t")`.
- `packages/cli/snap-tests/test-inline-snapshot-indent/` reproduces
  the issue's exact `vp test --update` flow on a 2-space indented
  file and captures the rewritten content.

Closes #1553
The pre-check `if (!/^\t/m.test(content)) continue` in convertTabsToSpaces
duplicates the work that `replace()` already performs, and the subsequent
`if (converted !== content)` guard already short-circuits no-op writes.
Drop the pre-check.

The inline comment inside the #1553 regression test restated the same
reasoning as the describe-level JSDoc — drop the inline copy.
@fengmk2 fengmk2 force-pushed the fix/inline-snapshot-tab-indent branch from 3fbf672 to 8395fe0 Compare May 12, 2026 08:52
@fengmk2 fengmk2 merged commit bed0936 into main May 12, 2026
76 checks passed
@fengmk2 fengmk2 deleted the fix/inline-snapshot-tab-indent branch May 12, 2026 12:14
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.

bug: inline snapshots are tab-indented in vite-plus/test

2 participants