[codex] increase coverage for cli scan and import pipelines - #276
Conversation
📝 WalkthroughWalkthroughAdds many unit tests across multiple modules: bone/material processing, CLI pipeline, mesh import/export, scan engine, and transform operator pivot behavior; no public API changes. Changes
Sequence Diagram(s)(omitted — changes are test additions and do not introduce new multi-component runtime control flow) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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.
Actionable comments posted: 4
🧹 Nitpick comments (2)
website/src/data/content.js (1)
61-82: Note: 5 use cases in a 4-column grid will wrap unevenly.The
useCasesarray has 5 items rendered in a 4-column grid (.useCaseGrid). This results in 4 cards on the first row and 1 orphan card on the second row, which may look visually unbalanced.This is a minor visual concern — consider whether 4 or 6 items would provide a cleaner layout, or adjust the grid to 5 columns if intentional.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/src/data/content.js` around lines 61 - 82, The useCases array contains 5 items which renders awkwardly in the 4-column .useCaseGrid causing a single orphan card; update the UI by either adding or removing an item in the useCases array to make it 4 or 6 entries, or change the grid layout to accommodate 5 columns (adjust the .useCaseGrid CSS) so cards align evenly; locate and edit the useCases export in content.js or the .useCaseGrid rules in your stylesheet to implement the chosen fix.website/src/App.jsx (1)
374-381: Consider simplifying the tag assignment logic.The current
includes()checks work but are fragile — they depend on specific substrings appearing in titles. If a future feature title contains "AI" or "MCP" unintentionally, it would get the wrong tag.♻️ Consider adding a `tag` property directly to highlightFeatures data
In
content.js, add the tag to each feature object:export const highlightFeatures = [ { title: 'Scene save/load', body: '...', tag: 'Feature' }, { title: 'Material tools', body: '...', tag: 'Feature' }, { title: 'REST API', body: '...', tag: 'Feature' }, { title: 'MCP / AI agent integration', body: '...', tag: 'Advanced' } ];Then in
App.jsx:- tag={feature.title.includes('AI') || feature.title.includes('MCP') ? 'Advanced' : 'Feature'} + tag={feature.tag}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/src/App.jsx` around lines 374 - 381, The tag assignment is fragile; update the highlightFeatures data (e.g., in content.js) to include an explicit tag property for each feature (e.g., tag: 'Advanced' or 'Feature'), then modify App.jsx where highlightFeatures is mapped to pass feature.tag into the FeatureCard (replace the title.includes('AI')/includes('MCP') logic with feature.tag). Ensure FeatureCard continues to accept a tag prop and provide a sensible default if a feature lacks tag.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/CLIPipeline_test.cpp`:
- Around line 1797-1814: The tests CLIPipelineCmdPoseError::NonexistentFile and
CLIPipelineCmdScanError::MissingConfigFile use hardcoded POSIX paths (e.g.
"/tmp/qtmesh_pose_missing_12345.fbx") which breaks Windows portability; update
these tests (locations referencing TestArgv and calls to CLIPipeline::cmdPose
and CLIPipeline::cmdScan) to construct missing-file paths using a
platform-neutral temp location (e.g. QDir::tempPath() or create a QTemporaryDir
and use a child filename) so the path semantics work on Windows, Linux, and
macOS and the tests still point to a non-existent file.
In `@src/ScanEngine_test.cpp`:
- Around line 1298-1303: Replace the hard assertion that the animated fixture
exists with a skip so the test doesn't fail on missing test data: for the
filePath computed from testDataDir() replace
ASSERT_TRUE(QFile::exists(filePath)) << ... with a conditional that calls
GTEST_SKIP() << "Animated fixture missing: " << filePath.toStdString(); (use
QFile::exists(filePath) on the same filePath variable before calling
ScanEngine::inspectAsset) so the test is skipped instead of failing when the
fixture is unavailable.
- Around line 304-311: The test EnumerateFiles_NonexistentRootReturnsEmpty
hardcodes a POSIX path (/tmp/...), making it non-portable; modify the test to
construct a guaranteed-nonexistent path using Qt APIs (e.g., create a
QTemporaryDir or use QDir::tempPath() and append a unique random/nonexistent
child name, then remove it if created) and pass that path into
ScanEngine::enumerateFiles so the test works on Windows, Linux, and macOS while
still asserting files.isEmpty().
- Around line 250-254: The test currently treats camelCase as a no-op which
prevents verifying/fixing camelCase conversion; update the expectation in
TEST(ScanEngineTest, ConvertNameToCase_LowercaseAndUnknown) to assert that
ScanEngine::convertNameToCase("PlayerModel.fbx", "camelCase") returns
"playerModel.fbx" (or remove the camelCase assertion until implementation
exists) so the unit test reflects the intended supported convention; reference
ScanEngine::convertNameToCase and the ConvertNameToCase_LowercaseAndUnknown test
when making the change.
---
Nitpick comments:
In `@website/src/App.jsx`:
- Around line 374-381: The tag assignment is fragile; update the
highlightFeatures data (e.g., in content.js) to include an explicit tag property
for each feature (e.g., tag: 'Advanced' or 'Feature'), then modify App.jsx where
highlightFeatures is mapped to pass feature.tag into the FeatureCard (replace
the title.includes('AI')/includes('MCP') logic with feature.tag). Ensure
FeatureCard continues to accept a tag prop and provide a sensible default if a
feature lacks tag.
In `@website/src/data/content.js`:
- Around line 61-82: The useCases array contains 5 items which renders awkwardly
in the 4-column .useCaseGrid causing a single orphan card; update the UI by
either adding or removing an item in the useCases array to make it 4 or 6
entries, or change the grid layout to accommodate 5 columns (adjust the
.useCaseGrid CSS) so cards align evenly; locate and edit the useCases export in
content.js or the .useCaseGrid rules in your stylesheet to implement the chosen
fix.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ba957993-4570-402c-868f-fad2937d7384
📒 Files selected for processing (10)
src/Assimp/BoneProcessor_test.cppsrc/Assimp/MaterialProcessor_test.cppsrc/CLIPipeline_test.cppsrc/MeshImporterExporter_test.cppsrc/ScanEngine_test.cppsrc/TransformOperator_test.cppwebsite/index.htmlwebsite/src/App.jsxwebsite/src/App.module.csswebsite/src/data/content.js
| TEST(ScanEngineTest, InspectAsset_AnimatedFixtureCollectsAnimationMetadata) | ||
| { | ||
| const QString filePath = testDataDir() + "/Twist Dance.fbx"; | ||
| ASSERT_TRUE(QFile::exists(filePath)) << "Animated fixture missing: " << filePath.toStdString(); | ||
|
|
||
| const AssetInfo info = ScanEngine::inspectAsset(filePath, QFileInfo(filePath).absolutePath()); |
There was a problem hiding this comment.
Skip when the animated fixture cannot be resolved.
testDataDir() is heuristic, so this hard assertion can turn a layout difference into a false-negative. Other fixture-based tests already skip when media is unavailable; this one should do the same.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/ScanEngine_test.cpp` around lines 1298 - 1303, Replace the hard assertion
that the animated fixture exists with a skip so the test doesn't fail on missing
test data: for the filePath computed from testDataDir() replace
ASSERT_TRUE(QFile::exists(filePath)) << ... with a conditional that calls
GTEST_SKIP() << "Animated fixture missing: " << filePath.toStdString(); (use
QFile::exists(filePath) on the same filePath variable before calling
ScanEngine::inspectAsset) so the test is skipped instead of failing when the
fixture is unavailable.
21d00bb to
ca4b3b1
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/CLIPipeline_test.cpp (1)
1892-1940: Consider parsing report/SARIF as JSON instead of substring checks.Current
contains(...)checks can pass even if output is malformed but still includes those tokens. Parsing makes this assertion stricter and less brittle.♻️ Suggested assertion hardening
- const QString reportContent = QString::fromUtf8(reportFile.readAll()); - EXPECT_TRUE(reportContent.contains("\"summary\"")); - EXPECT_TRUE(reportContent.contains("\"assets\"")); + const QByteArray reportBytes = reportFile.readAll(); + QJsonParseError reportErr{}; + const QJsonDocument reportDoc = QJsonDocument::fromJson(reportBytes, &reportErr); + ASSERT_EQ(reportErr.error, QJsonParseError::NoError); + ASSERT_TRUE(reportDoc.isObject()); + const QJsonObject reportObj = reportDoc.object(); + EXPECT_TRUE(reportObj.contains("summary")); + EXPECT_TRUE(reportObj.contains("assets")); QFile sarifFile(sarifPath); ASSERT_TRUE(sarifFile.open(QIODevice::ReadOnly | QIODevice::Text)); - const QString sarifContent = QString::fromUtf8(sarifFile.readAll()); - EXPECT_TRUE(sarifContent.contains("\"runs\"")); - EXPECT_TRUE(sarifContent.contains("qtmesh scan")); + const QByteArray sarifBytes = sarifFile.readAll(); + QJsonParseError sarifErr{}; + const QJsonDocument sarifDoc = QJsonDocument::fromJson(sarifBytes, &sarifErr); + ASSERT_EQ(sarifErr.error, QJsonParseError::NoError); + ASSERT_TRUE(sarifDoc.isObject()); + const QJsonObject sarifObj = sarifDoc.object(); + EXPECT_TRUE(sarifObj.contains("runs"));🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/CLIPipeline_test.cpp` around lines 1892 - 1940, The test TEST(CLIPipelineCmdScan, WritesJsonAndSarifReports) currently asserts report/sarif output via substring checks; instead, open and parse reportPath and sarifPath as JSON (e.g., using QJsonDocument::fromJson) and assert parsing succeeded (no parse errors), then validate the expected structure: for the report JSON ensure there is a top-level object containing "summary" and "assets" keys with the expected types (object/array), and for the SARIF JSON ensure it parses to an object with a "runs" array and that runs[0].tool.driver.name (or runs[0].tool.driver.fullName) contains "qtmesh scan"; update assertions in this test and keep using CLIPipeline::cmdScan(args.argc(), args.argv()) as the command under test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/CLIPipeline_test.cpp`:
- Around line 1892-1940: The test TEST(CLIPipelineCmdScan,
WritesJsonAndSarifReports) currently asserts report/sarif output via substring
checks; instead, open and parse reportPath and sarifPath as JSON (e.g., using
QJsonDocument::fromJson) and assert parsing succeeded (no parse errors), then
validate the expected structure: for the report JSON ensure there is a top-level
object containing "summary" and "assets" keys with the expected types
(object/array), and for the SARIF JSON ensure it parses to an object with a
"runs" array and that runs[0].tool.driver.name (or runs[0].tool.driver.fullName)
contains "qtmesh scan"; update assertions in this test and keep using
CLIPipeline::cmdScan(args.argc(), args.argv()) as the command under test.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e900899e-265a-4975-acfd-9729c69d2df6
📒 Files selected for processing (2)
src/CLIPipeline_test.cppsrc/ScanEngine_test.cpp
✅ Files skipped from review due to trivial changes (1)
- src/ScanEngine_test.cpp
|



Summary
Increase test coverage for CLI scan/import flows, scan-engine rule handling, and Assimp/transform edge cases.
Technical Details
src/Assimp/BoneProcessor_test.cppsrc/Assimp/MaterialProcessor_test.cppsrc/CLIPipeline_test.cppsrc/MeshImporterExporter_test.cppsrc/ScanEngine_test.cppsrc/TransformOperator_test.cpp/tmp).✨ Features
poseandscancommand validation/report paths.🐛 Bugfixes
ScanEnginetests.Validation
cmake --build build_cov_local -j$(nproc) --target UnitTestsQT_QPA_PLATFORM=offscreen ./build_cov_local/debug/UnitTests --gtest_filter='BoneProcessorTest.*:MaterialProcessorTest.*:CLIPipelineCmdPoseError.*:CLIPipelineCmdScan*.*:ScanEngineTest.*:ScanConfigTest.*:TransformOperatorTests.Pivot*:MeshImporterExporterStandaloneTest.FormatFileURI_HumanReadableUnknownFormatDoesNotAppend:MeshImporterExporterStandaloneTest.FormatFileURI_ShortAliasUppercaseIsAppendedAsGiven'Summary by CodeRabbit