Repository navigation
test(cli): pin behavior for malformed .svelte files in both passes - #116
Conversation
Adds characterization tests that lock in the current asymmetric handling of syntactically invalid .svelte files: collectComponentFacts() swallows parse failures and returns empty facts for the broken file only, while the route path (resolveRoute/collectRoutes) has no try/catch and propagates the parse error out to run()'s top-level catch, aborting the whole analysis with exit 2. Also excludes the two new intentionally-invalid fixture projects from Prettier's check (prettier-plugin-svelte can't format syntactically broken Svelte source), mirroring the existing eslint ignore for test/fixtures.
📝 WalkthroughWalkthroughThis PR adds two fixture Svelte projects (component and route paths) containing intentionally malformed, unclosed template syntax, updates .prettierignore to exclude these fixtures from formatting, and introduces a Vitest suite validating that parsing failures are handled gracefully without crashing. ChangesMalformed Svelte fixtures and parser-failure tests
Estimated code review effort: 2 (Simple) | ~12 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/cli/test/malformed-svelte.test.ts (1)
38-50: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueOptional: extract the shared "empty facts" fixture.
The expected empty-facts object is duplicated verbatim between the two tests. A small shared constant would reduce duplication and keep both assertions in sync if the shape in
components.tschanges.♻️ Proposed consolidation
+const EMPTY_FACTS = { + eachBlocks: [], + effects: [], + htmlTags: [], + javascriptUrls: [], + loc: 0, + propCount: 0, + imports: [], + namespaceImports: [], + constableStates: [], + suppressions: [] +}; + describe('collectComponentFacts: malformed .svelte files (component path)', () => { ... - expect(broken).toEqual({ - file: 'src/lib/Broken.svelte', - eachBlocks: [], - ... - }); + expect(broken).toEqual({ file: 'src/lib/Broken.svelte', ...EMPTY_FACTS });Also applies to: 94-106
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/cli/test/malformed-svelte.test.ts` around lines 38 - 50, The empty-facts expectation is duplicated across the malformed Svelte tests, so extract it into a shared fixture constant and reuse it in both assertions. Update the tests around the broken/empty facts checks to reference the shared object instead of inlining the same shape, keeping the fixture aligned with the expected structure from components.ts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/cli/test/malformed-svelte.test.ts`:
- Around line 38-50: The empty-facts expectation is duplicated across the
malformed Svelte tests, so extract it into a shared fixture constant and reuse
it in both assertions. Update the tests around the broken/empty facts checks to
reference the shared object instead of inlining the same shape, keeping the
fixture aligned with the expected structure from components.ts.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 00d77c0c-0965-45c6-8522-b4d4bb1979c5
📒 Files selected for processing (7)
.prettierignorepackages/cli/test/fixtures/malformed-component-project/package.jsonpackages/cli/test/fixtures/malformed-component-project/src/lib/Broken.sveltepackages/cli/test/fixtures/malformed-component-project/src/routes/+page.sveltepackages/cli/test/fixtures/malformed-route-project/package.jsonpackages/cli/test/fixtures/malformed-route-project/src/routes/+page.sveltepackages/cli/test/malformed-svelte.test.ts
Summary
Characterization tests only — no behavior change. svelte-vitals handles syntactically broken
.sveltefiles asymmetrically across its two passes, and neither behavior was pinned by a test:collectComponentFacts): a parse/read failure is swallowed and the file contributes empty facts — analysis continues for the rest of the project.resolveRoute): no try/catch — one broken+page.svelte/+layout.svelteaborts the entire analysis with exit 2.This PR pins both behaviors (including the asymmetry) as an intentional contract, so future refactors — notably the planned per-run parse cache — cannot change them unnoticed, and so the hand-maintained empty-facts fallback shape is caught by a strict
toEqualwhenComponentFactsgains a field.Tests added (
packages/cli/test/malformed-svelte.test.ts)$libcomponent yields exact empty facts while the well-formed sibling route file is still parsed normallyrun()on a project with a broken component completes with exit 0/1 — never 2readFilerejects) takes the same fallback, exercised via an in-memoryRuntimerun()exit 2 with asvelte-vitals:error — commented as a known, currently-intentional asymmetry that must be updated deliberately, not silencedTwo new fixtures:
malformed-component-project/,malformed-route-project/.Note
The intentionally-invalid fixtures had to be added to
.prettierignore(prettier-plugin-svelte cannot parse them), mirroring the existing eslint fixture exclusion.Verification
pnpm typecheck/pnpm lint— cleanpnpm test— 719 tests pass across all packages (cli 288 incl. the 4 new)🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests