Conversation
WalkthroughThree new files are introduced: a utility class Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@omnidoc/readExamples.spec.ts`:
- Around line 1-3: Move the spec into the test suite and align its name:
relocate the current omnidoc/readExamples.spec.ts to the test directory (e.g.,
test/omnidoc/readExamples.spec.tsx), rename the file to use the .spec.tsx
suffix, and update the import for ExampleReader in the moved file to the correct
relative path; ensure any test runner config picks up the new location and that
the test name follows existing conventions.
In `@omnidoc/readExamples.ts`:
- Around line 96-105: When following an import specifier
(Node.isImportSpecifier) you currently call
this.processExampleMap(moduleSpecifier, examplesName) which passes the local
alias and causes aliased imports to fail; change it to resolve and pass the
original exported name by using declaration.getName() (same approach as
processApiExamplesIndex) so call this.processExampleMap(moduleSpecifier,
declaration.getName()) when handling importDecl/moduleSpecifier in
processExampleMap.
- Around line 274-306: The checkAttributes function misses JSX spread
attributes; update it to iterate node.getAttributes() and handle
Node.isJsxSpreadAttribute(attr) cases: for each spread attribute call
attr.getExpression() and if Node.isObjectLiteralExpression(expression) inspect
expression.getProperties() for a property matching propName, and if expression
is an Identifier resolve its declarations via identifier.getDefinitions() or
identifier.getSymbol()?.getDeclarations(), find VariableDeclaration(s) and
inspect their getInitializer() (treat object literal initializers like above) to
detect the prop; keep existing direct-attribute logic
(node.getAttribute(propName)) and children handling intact and return true when
any spread or direct attribute indicates usage.
In `@omnidoc/verifyExamples.spec.ts`:
- Around line 1-4: The spec file is placed outside the test suite and uses the
wrong extension; move and rename the file to the test suite (e.g.,
test/omnidoc/verifyExamples.spec.tsx) and update any module imports so they
resolve from the new location (update imports of ProjectDocReader and
ExampleReader accordingly), ensuring test runner discovers it and naming follows
the *.spec.tsx convention.
🧹 Nitpick comments (1)
omnidoc/readExamples.ts (1)
47-71: Add explicit return types to non‑trivial ExampleReader methods.
initialize,buildUrlMap, and other helpers rely on inferredvoid. Please add explicit return types for these non‑trivial methods (and apply similarly to the otherprocess*/is*methods). As per coding guidelines, please add explicit return types.♻️ Example pattern
- private initialize() { + private initialize(): void { @@ - private buildUrlMap() { + private buildUrlMap(): void {
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
omnidoc/readExamples.spec.tsomnidoc/readExamples.tsomnidoc/verifyExamples.spec.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.{ts,tsx}: Never useanytype (implicit or explicit) in TypeScript code
Preferunknownoveranyand refine the type in TypeScript
Type function parameters and return values explicitly in TypeScript, do not rely on implicit any or inference; exceptions are React components and trivial functions
Do not useastype assertions in TypeScript; the only exception isas constAll imports from
rechartsmust use the public API entry point (e.g.,import { TooltipIndex } from 'recharts'). Imports from internal paths likerecharts/types/*orrecharts/src/*are not allowed and will fail the linter.
Files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.tsomnidoc/readExamples.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Ensure code lints by running
npm run lintand follows Airbnb's Style Guide
Files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.tsomnidoc/readExamples.ts
**/*.spec.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
When running unit tests, prefer to run a single test file using
npm run test -- path/to/TestFile.spec.tsxrather than running all tests withnpm testUnit tests should be placed in the
testdirectory, with some tests also allowed inwww/test. Test files follow the naming convention*.spec.tsx.
Files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to **/*.spec.{ts,tsx} : Unit tests should be placed in the `test` directory, with some tests also allowed in `www/test`. Test files follow the naming convention `*.spec.tsx`.
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to **/*.stories.{ts,tsx} : When adding new Storybook stories, prioritize high-fidelity examples that you want published on the website and in the Storybook UI. Use low-fidelity tests in unit tests or visual regression tests instead to avoid exceeding the Chromatic open source plan limits.
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6783
File: test/util/ChartUtils.spec.tsx:15-16
Timestamp: 2025-12-16T08:12:13.355Z
Learning: In the recharts codebase, files in the `test` folder are allowed to import from internal paths (e.g., `../../src/state/cartesianAxisSlice`) and do not need to use the public API entry point (`src/index.ts`). The public API import restriction applies only to non-test code.
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Prefer to use the `createSelectorTestCase` helper function when writing or modifying tests
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to storybook/stories/**/*.stories.tsx : Update Storybook stories when APIs have been changed to ensure they work as expected
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to test/component/**/*.spec.tsx : Use React Testing Library for testing component interactions and behavior upon rendering
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to test-vr/**/*.spec.ts : Visual regression tests should follow the naming convention `*.spec.ts` and be placed in the `test-vr` directory. When updating snapshots, new files created in `test-vr/__snapshots__` should be committed to the repository.
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Use the `expectLastCalledWith` helper function instead of `expect(spy).toHaveBeenLastCalledWith(...)` for better typing and autocompletion
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Verify the number of selector calls using the spy object from `createSelectorTestCase` to spot unnecessary re-renders and improve performance
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to storybook/stories/**/*.stories.tsx : Use Storybook for smoke tests and add play functions with assertions for actual tests
📚 Learning: 2025-12-26T15:59:11.254Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to test-vr/**/*.spec.ts : Visual regression tests should follow the naming convention `*.spec.ts` and be placed in the `test-vr` directory. When updating snapshots, new files created in `test-vr/__snapshots__` should be committed to the repository.
Applied to files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.ts
📚 Learning: 2025-12-26T15:59:11.254Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to **/*.spec.{ts,tsx} : Unit tests should be placed in the `test` directory, with some tests also allowed in `www/test`. Test files follow the naming convention `*.spec.tsx`.
Applied to files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.ts
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to test/**/*.spec.{ts,tsx} : Aim for 100% unit test code coverage when writing new code
Applied to files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.ts
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Verify the number of selector calls using the spy object from `createSelectorTestCase` to spot unnecessary re-renders and improve performance
Applied to files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.ts
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Aim for 100% unit test code coverage when writing new code
Applied to files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.ts
📚 Learning: 2025-12-26T15:59:11.254Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to **/*.stories.{ts,tsx} : When adding new Storybook stories, prioritize high-fidelity examples that you want published on the website and in the Storybook UI. Use low-fidelity tests in unit tests or visual regression tests instead to avoid exceeding the Chromatic open source plan limits.
Applied to files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.ts
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Use the `expectLastCalledWith` helper function instead of `expect(spy).toHaveBeenLastCalledWith(...)` for better typing and autocompletion
Applied to files:
omnidoc/verifyExamples.spec.ts
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Prefer to use the `createSelectorTestCase` helper function when writing or modifying tests
Applied to files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.ts
📚 Learning: 2025-12-16T08:12:13.355Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6783
File: test/util/ChartUtils.spec.tsx:15-16
Timestamp: 2025-12-16T08:12:13.355Z
Learning: In the recharts codebase, files in the `test` folder are allowed to import from internal paths (e.g., `../../src/state/cartesianAxisSlice`) and do not need to use the public API entry point (`src/index.ts`). The public API import restriction applies only to non-test code.
Applied to files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.ts
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to storybook/stories/**/*.stories.tsx : Use Storybook for smoke tests and add play functions with assertions for actual tests
Applied to files:
omnidoc/verifyExamples.spec.tsomnidoc/readExamples.spec.ts
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Mock `getBoundingClientRect` in tests using the helper function provided in `test/helper/MockGetBoundingClientRect.ts`
Applied to files:
omnidoc/readExamples.spec.ts
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Add tests when adding new functionality or changing existing functionality; prefer unit tests for helper functions or RTL tests for rendering
Applied to files:
omnidoc/readExamples.spec.ts
🧬 Code graph analysis (2)
omnidoc/verifyExamples.spec.ts (2)
omnidoc/readProject.ts (1)
ProjectDocReader(72-878)omnidoc/readExamples.ts (1)
ExampleReader(3-317)
omnidoc/readExamples.spec.ts (1)
omnidoc/readExamples.ts (1)
ExampleReader(3-317)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build, Test, Pack
- GitHub Check: Analyze (javascript-typescript)
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| import { describe, it, expect } from 'vitest'; | ||
| import { ExampleReader } from './readExamples'; | ||
|
|
There was a problem hiding this comment.
Move this spec into the test suite and align naming.
Specs are expected under test/ (or www/test) and follow *.spec.tsx. Keeping this under omnidoc/ with .spec.ts risks the test not running. Please move/rename (e.g., test/omnidoc/readExamples.spec.tsx) and update imports as needed. As per coding guidelines.
🤖 Prompt for AI Agents
In `@omnidoc/readExamples.spec.ts` around lines 1 - 3, Move the spec into the test
suite and align its name: relocate the current omnidoc/readExamples.spec.ts to
the test directory (e.g., test/omnidoc/readExamples.spec.tsx), rename the file
to use the .spec.tsx suffix, and update the import for ExampleReader in the
moved file to the correct relative path; ensure any test runner config picks up
the new location and that the test name follows existing conventions.
| if (declSourceFile !== sourceFile && Node.isVariableDeclaration(declaration)) { | ||
| // It is defined in another file, process it there | ||
| this.processExampleMap(declSourceFile, declaration.getName()); | ||
| } else if (Node.isImportSpecifier(declaration)) { | ||
| // Sometimes it points to the import specifier | ||
| const importDecl = declaration.getImportDeclaration(); | ||
| const moduleSpecifier = importDecl.getModuleSpecifierSourceFile(); | ||
| if (moduleSpecifier) { | ||
| this.processExampleMap(moduleSpecifier, examplesName); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's locate and examine the file structure
find . -type f -name "readExamples.ts" | head -5Repository: recharts/recharts
Length of output: 86
🏁 Script executed:
# Find the omnidoc directory
find . -type d -name "omnidoc" | head -5Repository: recharts/recharts
Length of output: 70
🏁 Script executed:
# Read the relevant section of the file
cat -n ./omnidoc/readExamples.ts | head -120Repository: recharts/recharts
Length of output: 5497
🏁 Script executed:
# Also check the processExampleMap method signature
rg -A 5 "processExampleMap\(" ./omnidoc/readExamples.ts | head -30Repository: recharts/recharts
Length of output: 956
🏁 Script executed:
# Check for aliased imports in the exampleComponents index file
rg -n "import\s+\{[^}]*\bas\b" www/src/docs/exampleComponents/index.tsRepository: recharts/recharts
Length of output: 227
🏁 Script executed:
# Let's also check the full structure of the exampleComponents index to understand the pattern
cat www/src/docs/exampleComponents/index.ts | head -80Repository: recharts/recharts
Length of output: 2179
🏁 Script executed:
# Let's verify what declaration.getName() returns for an ImportSpecifier
# Check the ts-morph documentation or see how ImportSpecifier works
cd ./omnidoc && cat readExamples.ts | grep -A 20 "Node.isImportSpecifier"Repository: recharts/recharts
Length of output: 3240
🏁 Script executed:
# Let's also check if there's an imported name property we can understand
rg -n "getImportDeclaration\|getName" ./omnidoc/readExamples.ts | head -20Repository: recharts/recharts
Length of output: 43
🏁 Script executed:
# Check the Legend.ts file to confirm the actual export name
cat www/src/docs/exampleComponents/Legend.ts | head -30Repository: recharts/recharts
Length of output: 133
🏁 Script executed:
# Find the Legend file
find www/src/docs/exampleComponents -name "Legend*"Repository: recharts/recharts
Length of output: 160
🏁 Script executed:
# Let's check what the correct pattern is by looking at line 153 more carefully
sed -n '140,160p' ./omnidoc/readExamples.tsRepository: recharts/recharts
Length of output: 879
🏁 Script executed:
# Let's check the Legend index file to see what's exported
cat www/src/docs/exampleComponents/Legend/index.ts 2>/dev/null || cat www/src/docs/exampleComponents/Legend.ts 2>/dev/nullRepository: recharts/recharts
Length of output: 394
🏁 Script executed:
# Let's find the actual Legend index
find www/src/docs/exampleComponents/Legend -name "index.ts"Repository: recharts/recharts
Length of output: 107
🏁 Script executed:
# Let's look at the processApiExampleArray method to see how it handles imports
sed -n '150,170p' ./omnidoc/readExamples.tsRepository: recharts/recharts
Length of output: 720
🏁 Script executed:
# Let's check what declaration.getName() would return for an ImportSpecifier
# by looking at ts-morph's behavior. Let's search for how getName is used with ImportSpecifier elsewhere
rg -B 3 -A 3 "ImportSpecifier.*getName\|getName.*ImportSpecifier" .Repository: recharts/recharts
Length of output: 43
🏁 Script executed:
# Let's verify the issue by understanding what happens:
# For: import { legendExamples as LegendExamples }
# - examplesName (getText) = "LegendExamples"
# - declaration.getName() should = "legendExamples"
# Let's check processApiExampleArray which uses declaration.getName() to confirm the pattern
sed -n '178,190p' ./omnidoc/readExamples.tsRepository: recharts/recharts
Length of output: 895
Use the imported name when resolving aliased example-map imports.
Aliased imports like import { legendExamples as LegendExamples } exist in the codebase. When following an import specifier to its module, the code at line 104 uses examplesName (the local alias), but processExampleMap needs the original exported name to find the variable in the source file. This causes aliased imports to silently fail. The pattern at line 189 in processApiExamplesIndex correctly uses declaration.getName() in the same scenario.
Fix
- this.processExampleMap(moduleSpecifier, examplesName);
+ this.processExampleMap(moduleSpecifier, declaration.getName());🤖 Prompt for AI Agents
In `@omnidoc/readExamples.ts` around lines 96 - 105, When following an import
specifier (Node.isImportSpecifier) you currently call
this.processExampleMap(moduleSpecifier, examplesName) which passes the local
alias and causes aliased imports to fail; change it to resolve and pass the
original exported name by using declaration.getName() (same approach as
processApiExamplesIndex) so call this.processExampleMap(moduleSpecifier,
declaration.getName()) when handling importDecl/moduleSpecifier in
processExampleMap.
| const jsxElements = sourceFile.getDescendantsOfKind(SyntaxKind.JsxOpeningElement); | ||
| const jsxSelfClosingElements = sourceFile.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement); | ||
|
|
||
| const checkAttributes = (node: JsxOpeningElement | JsxSelfClosingElement) => { | ||
| if (node.getTagNameNode().getText() === localName) { | ||
| // Special handling for children | ||
| if (propName === 'children') { | ||
| // Check if it's an attribute (rare but possible) | ||
| if (node.getAttribute('children')) return true; | ||
|
|
||
| // If it's an opening element, check if the parent JsxElement has children | ||
| if (Node.isJsxOpeningElement(node)) { | ||
| const jsxElement = node.getParentIfKind(SyntaxKind.JsxElement); | ||
| if (jsxElement) { | ||
| const children = jsxElement.getJsxChildren(); | ||
| // Filter out empty text nodes (whitespace) | ||
| const hasRealChildren = children.some(child => { | ||
| if (Node.isJsxText(child)) { | ||
| return child.getText().trim().length > 0; | ||
| } | ||
| return true; | ||
| }); | ||
| if (hasRealChildren) return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| const attr = node.getAttribute(propName); | ||
| return !!attr; | ||
| } | ||
| return false; | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "readExamples.ts" -type fRepository: recharts/recharts
Length of output: 86
🏁 Script executed:
find . -type d -name "www" | head -5Repository: recharts/recharts
Length of output: 120
🏁 Script executed:
wc -l ./omnidoc/readExamples.tsRepository: recharts/recharts
Length of output: 90
🏁 Script executed:
sed -n '274,306p' ./omnidoc/readExamples.tsRepository: recharts/recharts
Length of output: 1398
🏁 Script executed:
rg -n "<[^>]*\{\.\.\." www/src/docs --max-count=20Repository: recharts/recharts
Length of output: 1822
🏁 Script executed:
sed -n '1,50p' ./omnidoc/readExamples.tsRepository: recharts/recharts
Length of output: 1619
🏁 Script executed:
sed -n '150,200p' ./omnidoc/readExamples.tsRepository: recharts/recharts
Length of output: 2062
🏁 Script executed:
sed -n '250,275p' ./omnidoc/readExamples.tsRepository: recharts/recharts
Length of output: 954
🏁 Script executed:
rg "isPropUsed" ./omnidoc/readExamples.ts -B 2 -A 2Repository: recharts/recharts
Length of output: 569
🏁 Script executed:
grep -A 5 "ts-morph" package.jsonRepository: recharts/recharts
Length of output: 243
🏁 Script executed:
rg "JsxSpreadAttribute|getAttributes" --max-count=10Repository: recharts/recharts
Length of output: 43
🌐 Web query:
ts-morph 27.0.2 JSX spread attribute API documentation
💡 Result:
The ts-morph 27.0.2 API for JSX spread attributes is exposed as the JsxSpreadAttribute node/class. Key methods include: getStructure(), set(structure: Partial), remove(), getParent(), and getParentOrThrow(). See the API reference for full details. (jsdocs.io)
Citations:
🏁 Script executed:
npm list ts-morph | head -5Repository: recharts/recharts
Length of output: 107
🏁 Script executed:
cat package-lock.json | grep -A 5 '"ts-morph"' | head -20Repository: recharts/recharts
Length of output: 267
🌐 Web query:
ts-morph JsxSpreadAttribute getAttributes filter Node.isJsxSpreadAttribute
💡 Result:
Use getAttributes() then filter out spread attributes with Node.isJsxSpreadAttribute. Example:
- import Node from ts-morph (or use the Node static on any node)
- Filter:
const attrs = jsxElement.getAttributes().filter(a => !Node.isJsxSpreadAttribute(a));
// attrs now contains only JsxAttribute (not JsxSpreadAttribute)
Or positive test to get only spreads:
const spreads = jsxElement.getAttributes().filter(a => Node.isJsxSpreadAttribute(a));
This is supported by ts-morph’s JsxSpreadAttribute/Node helpers. [1][2]
Sources:
[1] ts-morph API docs — JsxSpreadAttribute / isJsxSpreadAttribute.
[2] ts-morph documentation — navigating AST / getAttributes usage.
isPropUsed misses JSX spread props, which can hide real usage.
The current check only inspects direct attributes, so <Comp {...props} /> or <Comp {...{ width: 10 }} /> won't count toward prop coverage. This produces false negatives for the prop‑coverage test. Spread props are actively used in the documentation (e.g., {...rest}, {...labelProps}, {...props} patterns appear in 11+ example files).
The proposed fix correctly handles this by:
- Filtering JSX attributes to identify spread attributes using
Node.isJsxSpreadAttribute() - Checking object literals within spreads for the target property
- Resolving identifier spreads to their variable declarations and inspecting their initializers
These ts-morph methods are available in the project's version (27.0.2) and the fix approach is sound.
🐛 Proposed fix (handle common spread cases)
const checkAttributes = (node: JsxOpeningElement | JsxSelfClosingElement) => {
if (node.getTagNameNode().getText() === localName) {
@@
- const attr = node.getAttribute(propName);
+ const spreadAttrs = node.getAttributes().filter(Node.isJsxSpreadAttribute);
+ for (const spreadAttr of spreadAttrs) {
+ const expr = spreadAttr.getExpression();
+ if (Node.isObjectLiteralExpression(expr)) {
+ if (expr.getProperty(propName)) return true;
+ } else if (Node.isIdentifier(expr)) {
+ const decl = expr.getDefinitions()[0]?.getDeclarationNode();
+ if (decl && Node.isVariableDeclaration(decl)) {
+ const init = decl.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
+ if (init?.getProperty(propName)) return true;
+ }
+ }
+ }
+ const attr = node.getAttribute(propName);
return !!attr;
}
return false;
};🤖 Prompt for AI Agents
In `@omnidoc/readExamples.ts` around lines 274 - 306, The checkAttributes function
misses JSX spread attributes; update it to iterate node.getAttributes() and
handle Node.isJsxSpreadAttribute(attr) cases: for each spread attribute call
attr.getExpression() and if Node.isObjectLiteralExpression(expression) inspect
expression.getProperties() for a property matching propName, and if expression
is an Identifier resolve its declarations via identifier.getDefinitions() or
identifier.getSymbol()?.getDeclarations(), find VariableDeclaration(s) and
inspect their getInitializer() (treat object literal initializers like above) to
detect the prop; keep existing direct-attribute logic
(node.getAttribute(propName)) and children handling intact and return true when
any spread or direct attribute indicates usage.
| import { describe, test, expect } from 'vitest'; | ||
| import { ProjectDocReader } from './readProject'; | ||
| import { ExampleReader } from './readExamples'; | ||
|
|
There was a problem hiding this comment.
Move this spec into the test suite and align naming.
Specs are expected under test/ (or www/test) and follow *.spec.tsx. Keeping this under omnidoc/ with .spec.ts risks the test not running. Please move/rename (e.g., test/omnidoc/verifyExamples.spec.tsx) and update paths accordingly. As per coding guidelines.
🤖 Prompt for AI Agents
In `@omnidoc/verifyExamples.spec.ts` around lines 1 - 4, The spec file is placed
outside the test suite and uses the wrong extension; move and rename the file to
the test suite (e.g., test/omnidoc/verifyExamples.spec.tsx) and update any
module imports so they resolve from the new location (update imports of
ProjectDocReader and ExampleReader accordingly), ensuring test runner discovers
it and naming follows the *.spec.tsx convention.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6897 +/- ##
=======================================
Coverage 94.27% 94.27%
=======================================
Files 565 565
Lines 53858 53858
Branches 5178 5178
=======================================
Hits 50777 50777
Misses 3072 3072
Partials 9 9 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Staging Deployment Details
These deployments will remain available for 30 days. To update snapshots: Comment |
Bundle ReportBundle size has no change ✅ |
Description
I want to use this test to verify that we have all of those props and types used at least once so that I know if we are introducing a breaking change or not. The website is the closest we have to production.
Related Issue
#6645
Summary by CodeRabbit
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.