Skip to content

refactor(ts-plugin): split go-to-definition e2e tests into per-behavior cases#378

Merged
mizdra merged 1 commit into
mainfrom
refactor/e2e-test-go-to-definition
May 3, 2026
Merged

refactor(ts-plugin): split go-to-definition e2e tests into per-behavior cases#378
mizdra merged 1 commit into
mainfrom
refactor/e2e-test-go-to-definition

Conversation

@mizdra
Copy link
Copy Markdown
Owner

@mizdra mizdra commented May 2, 2026

Summary

Refactor packages/ts-plugin/e2e-test/feature/go-to-definition.test.ts so that each test block owns a minimal fixture and asserts a single behavior, organized by the .d.ts/mapping pattern under test. The previous structure shared one large fixture (5 files, 8+ tokens) across 17 cases inside a single test.each, which made it brittle to add new behaviors.

This is the first PR of a multi-PR series. Subsequent PRs will apply the same approach to the other e2e-test/ files (find-all-references, rename-symbol, completion, etc.).

What's new

  • packages/ts-plugin/e2e-test/test-util/fixture.ts: adds
    • setupFixture(files) — mirrors createIFF's shape; callers pass files directly (including tsconfig.json), so each test can place its config wherever it likes.
    • getLoc(file, search, index?) — 1-based line/offset of the first character of search in file. Throws if search is ambiguous and index is omitted.
    • getRange(file, search, index?){ start, end } range with end exclusive (matches tsserver's convention).
  • packages/ts-plugin/test/builder.ts (new): code-fragment builders for fixture files
    • buildTSConfigJSON({ compilerOptions?, cmkOptions? }) — defaults cmkOptions.enabled to true.
    • buildStylesImport(specifier, { namedExports }) — builds default / namespace styles import statements at call sites.
  • packages/ts-plugin/e2e-test/feature/go-to-definition.test.ts: rewritten as 14 behavior-focused tests, each with its own minimal fixture, organized into 4 describe blocks. Each fixture uses contiguous token / filename numbering (e.g. a.module.css + b.module.css, .a-1, b_1) so it only references the files and tokens the test actually needs.

Test structure

Each describe corresponds to a distinct .d.ts/mapping pattern produced by dts-generator.ts:

namedExports: $namedExports
├── jumps to the top of a CSS module file (5 tests)
│   ├── from the styles binding in the import statement
│   ├── from the import specifier string
│   ├── from the @import specifier string
│   ├── from the @value ... from specifier string
│   └── from inside the @import url(...) parenthesis
├── jumps to a local token declaration (3 tests)
│   ├── from styles.<token> access
│   ├── from styles[<kebab-case token>] access
│   └── returns all declarations when the same class is declared multiple times
├── transitively resolves a re-export to its source declaration (3 tests)
│   ├── class re-exported via @import
│   ├── value re-exported via @value ... from
│   └── aliased value re-exported via @value ... from
└── jumps from a CSS-side @value ... from binding to its source declaration (3 tests)
    ├── from the import binding
    ├── from the alias name in \`name as alias\`
    └── from the source name in \`name as alias\`

Total: 14 tests × 2 variants (namedExports: false / true) = 28 tests.

Per-syntax parser coverage (e.g. .foo, @value foo: red;, @keyframes foo) lives in dts-generator.test.ts; here we only cover one representative for each .d.ts/mapping pattern.

Test plan

  • vp test --project e2e packages/ts-plugin/e2e-test/feature/go-to-definition.test.ts — 28 passed
  • vp test --project e2e (full e2e suite) — no regressions
  • vp check (format + lint + type) — pass

@mizdra mizdra added the Type: Refactoring A code change that neither fixes a bug nor adds a feature label May 2, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 2, 2026

⚠️ No Changeset found

Latest commit: d32bf36

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@mizdra mizdra marked this pull request as draft May 2, 2026 10:21
@mizdra mizdra force-pushed the refactor/e2e-test-go-to-definition branch 2 times, most recently from 27be195 to 2ae09aa Compare May 2, 2026 16:39
…or cases

Each test now owns a minimal fixture and asserts a single behavior, organized
by the .d.ts/mapping pattern under test. The previous structure shared one
large fixture (5 files, 8+ tokens) across 17 cases inside a single test.each
block, which made it brittle to add new behaviors.

The new structure has 14 tests grouped into 4 describe blocks:
- jumps to the top of a CSS module file (5 tests)
- jumps to a local token declaration (3 tests)
- transitively resolves a re-export to its source declaration (3 tests)
- jumps from a CSS-side @value ... from binding to its source declaration (3 tests)

Adds:
- setupFixture / getLoc / getRange in e2e-test/test-util/fixture.ts. The API
  mirrors createIFF and accepts files directly (including tsconfig.json), so
  each test controls its own config placement.
- buildStylesImport / buildTSConfigJSON in packages/ts-plugin/test/builder.ts
  for building default / namespace import statements and tsconfig.json fixture
  content. cmkOptions.enabled defaults to true so callers only specify the
  options that matter for the test.
@mizdra mizdra force-pushed the refactor/e2e-test-go-to-definition branch from 2ae09aa to d32bf36 Compare May 3, 2026 05:50
@mizdra mizdra added Type: Testing Adding missing tests or correcting existing tests and removed Type: Refactoring A code change that neither fixes a bug nor adds a feature labels May 3, 2026
@mizdra mizdra marked this pull request as ready for review May 3, 2026 06:48
@mizdra mizdra merged commit a24fc8b into main May 3, 2026
20 checks passed
@mizdra mizdra deleted the refactor/e2e-test-go-to-definition branch May 3, 2026 06:49
mizdra added a commit that referenced this pull request May 3, 2026
…s into per-behavior cases (#379)

* test(ts-plugin): split find-all-references and rename-symbol e2e tests into per-behavior cases

Continue the e2e test refactor started in #378. Each test now owns a minimal
fixture and asserts a single behavior, organized by the .d.ts/mapping pattern
under test. Also revisit go-to-definition.test.ts so all three feature test
files share the same describe structure.

This is the second PR of a multi-PR series (see #378 for the first PR).

Shared describe structure (group 1 differs by feature, groups 2-5 are common):

- Group 1: feature-specific Volar.js auto-mapping
  - go-to-definition: jumps to the top of a CSS module file (5 tests)
  - find-all-references: finds all references to the styles binding (1 test)
  - rename-symbol: (none — module specifier rename is sendGetEditsForFileRename
    territory and styles binding rename is core TS behavior, not ts-plugin's)
- Group 2: <feature> a local token (TS-side trigger, 3 tests)
- Group 3: transitively resolves a re-export to its source declaration (3 tests)
- Group 4: <feature> from a CSS-side class declaration (1 test, newly added)
- Group 5: <feature> from a CSS-side @value ... from binding (3 tests)

Per-file totals:
- go-to-definition: 15 tests x 2 namedExports variants = 30
- find-all-references: 11 tests x 2 namedExports variants = 22
  (was 17 cases sharing one fixture inside a single test.each)
- rename-symbol: 10 tests x 2 namedExports variants = 20
  (was 13 cases inside a single test.each, only namedExports: false)

rename-symbol now also covers namedExports: true via describe.each.

* refactor(ts-plugin): move test/builder.ts under src/test/ to match other packages

* test(ts-plugin): rename multi-declaration test to a scenario qualifier

Other test names in the same describe blocks describe a trigger position
or fixture shape (e.g. "from styles.<token> access"), but this one was
phrased as a result ("returns all declarations ..."). Drop the verb so
the name reads as a scenario qualifier on the parent describe and stays
consistent across all three feature files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
mizdra added a commit that referenced this pull request May 4, 2026
…avior cases (#380)

* test(ts-plugin): split completion and code-fix e2e tests into per-behavior cases

Refactor both test files so each `test` block owns a minimal fixture and
asserts a single behavior, organized by the .d.ts/mapping pattern under
test. Follows the structure established in #378 and #379.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(ts-plugin): drop unused JSX compilerOptions from styles priority test

The fixture only contains `styles;` and never renders any JSX, so the
`jsx` and `types` compilerOptions are not needed for that test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(ts-plugin): cover named token suppression when prioritizeNamedImports is false

Add the negative-side cases for the `namedExports: true && !prioritizeNamedImports`
branches so that both the positive (current `prioritizeNamedImports: true`)
and negative behaviors of the suppression logic are pinned:

- completion: named tokens are filtered out of suggestions
- code-fix: named import code fixes are excluded

Reorganize the existing `prioritizeNamedImports (namedExports: true)` describe
into two parallel `prioritizeNamedImports: false / true` blocks under a single
parent so the on/off pair is visually adjacent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(ts-plugin): drop redundant (default) suffix from describe names

`prioritizeNamedImports: false` already conveys the configured value;
the `(default)` annotation is redundant and risks going stale if the
default changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(ts-plugin): cover generated-file exclusion and multi-import fixMissingCSSRule

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(ts-plugin): cover both PROPERTY_DOES_NOT_EXIST diagnostics in fixMissingCSSRule

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
mizdra added a commit that referenced this pull request May 5, 2026
)

* test(ts-plugin): split refactor / rename-file / disabled / invalid-syntax / pure-css-file / ignore-generated-files e2e tests into per-behavior cases

Each test now owns a minimal fixture and asserts a single behavior, completing the
multi-PR series started in #378. Hard-coded line/offset literals are replaced with
getRange / getLoc, and the inline diagnostic snapshot in ignore-generated-files is
replaced with a structural toStrictEqual.

Also adds a missing case to refactor.test.ts: the Create CSS Module file refactor is
suppressed when the paired *.module.css already exists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(ts-plugin): rename ignore-generated-files test to focus on the .d.ts exclusion behavior

The previous name described the observable diagnostic; the new name foregrounds
the actual invariant under test: ts-plugin removes generated .d.ts files from
the module resolution path even when their directory is listed in rootDirs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Testing Adding missing tests or correcting existing tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant