Skip to content

Expand selection and mesh IO coverage#226

Merged
fernandotonon merged 5 commits into
masterfrom
codex/coverage-push-5
Mar 27, 2026
Merged

Expand selection and mesh IO coverage#226
fernandotonon merged 5 commits into
masterfrom
codex/coverage-push-5

Conversation

@fernandotonon
Copy link
Copy Markdown
Owner

@fernandotonon fernandotonon commented Mar 27, 2026

Summary\n- expand SelectionSet coverage for resolved-entity and aggregate-selection paths\n- expand MeshImporterExporter coverage for node-only scene export/import and direct exporter/configureCamera paths\n- keep entity-dependent tests CI-safe by following the existing render-window capability checks\n\n## Verification\n- cmake --build build_covpush5 --target UnitTests -j2\n- xvfb-run -a ./build_covpush5/bin/UnitTests --gtest_filter='SelectionSetTests.:MeshImporterExporterTest.:MeshImporterExporterStandaloneTest.:SceneSaveLoadTest.'

Summary by CodeRabbit

  • Tests

    • Expanded mesh import/export tests: OBJ + material export, scene round-trip for empty nodes, mixed-scene export and texture-progress counting, and camera-configuration checks.
    • New widget tests covering rendering callbacks, resize/zoom behavior, mouse/wheel/focus interactions, cursor changes, and viewport visibility.
    • Broadened selection tests: entity resolution from node selections, scale/orientation aggregation, selection center, and removal of non-existent entries.
  • Chores

    • Cleaned up test coverage instrumentation markers.

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 27, 2026

📝 Walkthrough

Walkthrough

Adds multiple unit tests (MeshImporterExporter, SelectionSet, OgreWidget) and a small test-only public wrapper configureCameraForTesting in MeshImporterExporter.h; also removes LCOV coverage markers from OgreWidget.cpp. Tests cover export/import, OBJ export, camera config, selection aggregation, and widget interactions.

Changes

Cohort / File(s) Summary
MeshImporterExporter Tests
src/MeshImporterExporter_test.cpp
Added tests for exporter behavior with node-only scenes, mixed scenes, OBJ export (writes .obj and .material), progress reporting for texture export, and camera-configuration positioning checks.
SelectionSet Tests
src/SelectionSet_test.cpp
Added test helper createNodeWithEntity(...) and tests for resolved-entity semantics, selection scale/orientation averaging, selection center/sub-entity regression, and removal of non-existent entities/sub-entities; many tests skip when entity creation is unsupported.
OgreWidget & Tests
src/OgreWidget.cpp, src/OgreWidget_test.cpp
Removed LCOV exclusion markers from OgreWidget.cpp. Added OgreWidget_test.cpp with a fixture exercising widget lifecycle, event handlers, frame callbacks, resizing, mouse/wheel/focus interactions, and viewport visibility mask behavior.
Public API (test wrapper)
src/MeshImporterExporter.h
Exposed static void configureCameraForTesting(const Ogre::Entity *en); as a public inline wrapper forwarding to the existing private configureCamera for test use.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 I hopped through code and tests tonight,

OBJ files glinting in the moonlight,
Nodes alone and nodes with friends,
Cameras set and scenes that send,
A little thump — the tests took flight!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the primary changes: expanded test coverage for selection and mesh IO functionality.
Description check ✅ Passed The description covers the main areas of change and includes verification steps, though it lacks explicit feature/bugfix categorization per the template structure.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/coverage-push-5

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/MeshImporterExporter_test.cpp (1)

16-18: Consider using a friend declaration or test accessor instead of #define private public.

This preprocessor hack is undefined behavior in C++ and can break with certain compilers or when standard library headers are inadvertently affected. A cleaner approach is adding a friend class declaration in MeshImporterExporter.h for the test class, or providing explicit test accessors.

That said, this pattern is commonly used in test code and works reliably in practice.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/MeshImporterExporter_test.cpp` around lines 16 - 18, Replace the
preprocessor hack in MeshImporterExporter_test.cpp that temporarily redefines
access specifiers with a safer test access mechanism: add a friend declaration
in MeshImporterExporter.h (e.g., friend class MeshImporterExporterTest) or
expose explicit test accessor methods on the MeshImporterExporter class so the
test can access internals without using `#define private public`; update
MeshImporterExporter_test.cpp to remove the define/undef and use the new friend
class name or accessors (look for MeshImporterExporter_test.cpp and
MeshImporterExporter.h and the MeshImporterExporter class to make the change).
🤖 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/MeshImporterExporter_test.cpp`:
- Around line 16-18: Replace the preprocessor hack in
MeshImporterExporter_test.cpp that temporarily redefines access specifiers with
a safer test access mechanism: add a friend declaration in
MeshImporterExporter.h (e.g., friend class MeshImporterExporterTest) or expose
explicit test accessor methods on the MeshImporterExporter class so the test can
access internals without using `#define private public`; update
MeshImporterExporter_test.cpp to remove the define/undef and use the new friend
class name or accessors (look for MeshImporterExporter_test.cpp and
MeshImporterExporter.h and the MeshImporterExporter class to make the change).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c9f9368d-4736-4415-ac88-009156f966ad

📥 Commits

Reviewing files that changed from the base of the PR and between 2d1c04b and 9558b71.

📒 Files selected for processing (2)
  • src/MeshImporterExporter_test.cpp
  • src/SelectionSet_test.cpp

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
src/MeshImporterExporter_test.cpp (2)

392-416: Tighten texture-progress assertions to reduce false positives.

The Not(Contains("Exporting textures (2/3)...")) check is very specific. Consider asserting the count of "Exporting textures (" messages is exactly 1, then keep the explicit "(1/1)" assertion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/MeshImporterExporter_test.cpp` around lines 392 - 416, Replace the
fragile negative assertion with an exact-count check: after calling
MeshImporterExporter::sceneExporter and populating progressMessages, assert that
progressMessages contains the explicit "Exporting textures (1/1)..." message
(already present) and also assert that the number of entries in progressMessages
that contain the substring "Exporting textures (" is exactly 1 (operate on the
progressMessages QStringList and count occurrences), instead of using
::testing::Not(::testing::Contains(...)); reference progressMessages and
MeshImporterExporter::sceneExporter to locate the test logic to update.

753-779: Consider asserting camera distance magnitude, not only sign.

Current checks verify direction (z < 0) but not the actual sizing math. Adding an EXPECT_NEAR for -size / (2*tan(fov/2)) would harden this regression test.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/MeshImporterExporter_test.cpp` around lines 753 - 779, The test only
asserts the camera is placed on the negative Z axis but not at the expected
distance; after calling MeshImporterExporter::configureCameraForTesting(entity)
compute the expected distance using the entity’s size (e.g., bounding box
half-size or bounding radius derived from the mesh/entity) and the camera FOV
(use camera->getFOVy()), then add an EXPECT_NEAR comparing
camera->getParentSceneNode()->getPosition().z to -size/(2*tan(fov/2)) with a
small tolerance (e.g., 1e-3) so the test verifies the magnitude as well as the
sign.
src/MeshImporterExporter.h (1)

51-51: Gate test-only camera wrapper to test builds using existing BUILD_TESTS flag.

configureCameraForTesting at line 51 is used only in src/MeshImporterExporter_test.cpp:773 but declared as a public method, unnecessarily broadening the production API surface. The repository already has a BUILD_TESTS CMake flag that can gate this method to test builds only (similar to other test-specific infrastructure in the codebase). Wrap this declaration with #ifdef BUILD_TESTS or move it to a test-specific accessor file.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/MeshImporterExporter.h` at line 51, The public test-only wrapper method
configureCameraForTesting currently exposes test-only API; restrict it to test
builds by wrapping its declaration in an `#ifdef` BUILD_TESTS (or alternatively
move it into a test-only header/source) so it is only compiled when BUILD_TESTS
is enabled; locate the static method configureCameraForTesting (which calls
configureCamera) in MeshImporterExporter.h and gate that declaration with the
BUILD_TESTS macro mirroring the project's other test-only guards.
🤖 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/MeshImporterExporter_test.cpp`:
- Around line 392-416: Replace the fragile negative assertion with an
exact-count check: after calling MeshImporterExporter::sceneExporter and
populating progressMessages, assert that progressMessages contains the explicit
"Exporting textures (1/1)..." message (already present) and also assert that the
number of entries in progressMessages that contain the substring "Exporting
textures (" is exactly 1 (operate on the progressMessages QStringList and count
occurrences), instead of using ::testing::Not(::testing::Contains(...));
reference progressMessages and MeshImporterExporter::sceneExporter to locate the
test logic to update.
- Around line 753-779: The test only asserts the camera is placed on the
negative Z axis but not at the expected distance; after calling
MeshImporterExporter::configureCameraForTesting(entity) compute the expected
distance using the entity’s size (e.g., bounding box half-size or bounding
radius derived from the mesh/entity) and the camera FOV (use camera->getFOVy()),
then add an EXPECT_NEAR comparing camera->getParentSceneNode()->getPosition().z
to -size/(2*tan(fov/2)) with a small tolerance (e.g., 1e-3) so the test verifies
the magnitude as well as the sign.

In `@src/MeshImporterExporter.h`:
- Line 51: The public test-only wrapper method configureCameraForTesting
currently exposes test-only API; restrict it to test builds by wrapping its
declaration in an `#ifdef` BUILD_TESTS (or alternatively move it into a test-only
header/source) so it is only compiled when BUILD_TESTS is enabled; locate the
static method configureCameraForTesting (which calls configureCamera) in
MeshImporterExporter.h and gate that declaration with the BUILD_TESTS macro
mirroring the project's other test-only guards.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d834d173-924f-411f-8172-722a44caa657

📥 Commits

Reviewing files that changed from the base of the PR and between 9558b71 and 05625eb.

📒 Files selected for processing (3)
  • src/MeshImporterExporter.h
  • src/MeshImporterExporter_test.cpp
  • src/SelectionSet_test.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/SelectionSet_test.cpp

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/OgreWidget_test.cpp (1)

33-33: Prefer event flushing over fixed msleep(50) delays in tests.

Fixed sleeps make tests slower and timing-sensitive. A bounded event-processing helper is usually more deterministic.

Also applies to: 62-62

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/OgreWidget_test.cpp` at line 33, Replace the fixed QThread::msleep(50)
calls with a bounded event-processing helper that flushes the Qt event loop
until the expected condition or a short timeout is reached; specifically, remove
QThread::msleep(50) and instead call a helper (e.g.,
processEventsUntil(condition, timeoutMs) or a small loop using
QCoreApplication::processEvents(QEventLoop::AllEvents) + QElapsedTimer) in the
test containing the QThread::msleep(50) occurrences (both the one at the shown
location and the similar call at the other occurrence), ensuring the loop checks
the test condition and exits on timeout to keep tests deterministic and fast.
🤖 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/OgreWidget_test.cpp`:
- Around line 35-46: The test currently hard-fails with ASSERT_NE when render
setup is unavailable; change the creation of EditorViewport and retrieval of the
Ogre widget to follow the same skip pattern as MainWindow: after attempting
viewport = new EditorViewport(mainWindow, 7) and widget =
viewport->getOgreWidget(), if either construction throws or returns nullptr then
call GTEST_SKIP() with a clear message (e.g., "Skipping: render context
unavailable") instead of ASSERT_NE; update references in this block (MainWindow,
EditorViewport, getOgreWidget, viewport, widget) so the test gracefully skips
under Xvfb/headless environments.

---

Nitpick comments:
In `@src/OgreWidget_test.cpp`:
- Line 33: Replace the fixed QThread::msleep(50) calls with a bounded
event-processing helper that flushes the Qt event loop until the expected
condition or a short timeout is reached; specifically, remove
QThread::msleep(50) and instead call a helper (e.g.,
processEventsUntil(condition, timeoutMs) or a small loop using
QCoreApplication::processEvents(QEventLoop::AllEvents) + QElapsedTimer) in the
test containing the QThread::msleep(50) occurrences (both the one at the shown
location and the similar call at the other occurrence), ensuring the loop checks
the test condition and exits on timeout to keep tests deterministic and fast.
🪄 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: 10702224-2240-4d10-b9f1-9cb86d23008b

📥 Commits

Reviewing files that changed from the base of the PR and between 05625eb and 20d5628.

📒 Files selected for processing (2)
  • src/OgreWidget.cpp
  • src/OgreWidget_test.cpp
💤 Files with no reviewable changes (1)
  • src/OgreWidget.cpp

Comment thread src/OgreWidget_test.cpp
Comment on lines +35 to +46
try {
mainWindow = new MainWindow();
} catch (...) {
GTEST_SKIP() << "Skipping: MainWindow creation failed";
}
ASSERT_NE(mainWindow, nullptr);

viewport = new EditorViewport(mainWindow, 7);
ASSERT_NE(viewport, nullptr);

widget = viewport->getOgreWidget();
ASSERT_NE(widget, nullptr);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Skip render-dependent tests when Ogre context is unavailable.

ASSERT_NE on viewport/widget hard-fails in environments where render setup is unavailable; this should follow the same skip strategy used for MainWindow creation so Xvfb runs remain stable.

Proposed change
-        try {
-            mainWindow = new MainWindow();
-        } catch (...) {
-            GTEST_SKIP() << "Skipping: MainWindow creation failed";
-        }
-        ASSERT_NE(mainWindow, nullptr);
-
-        viewport = new EditorViewport(mainWindow, 7);
-        ASSERT_NE(viewport, nullptr);
-
-        widget = viewport->getOgreWidget();
-        ASSERT_NE(widget, nullptr);
+        try {
+            mainWindow = new MainWindow();
+            viewport = new EditorViewport(mainWindow, 7);
+            widget = viewport ? viewport->getOgreWidget() : nullptr;
+        } catch (...) {
+            GTEST_SKIP() << "Skipping: render setup failed in this environment";
+        }
+
+        if (mainWindow == nullptr || viewport == nullptr || widget == nullptr || widget->getSpaceCamera() == nullptr)
+            GTEST_SKIP() << "Skipping: Ogre render context unavailable under current backend";

As per coding guidelines, src/**/*_test.cpp: "Tests must work under Xvfb (headless X11) — avoid assumptions about a real display".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/OgreWidget_test.cpp` around lines 35 - 46, The test currently hard-fails
with ASSERT_NE when render setup is unavailable; change the creation of
EditorViewport and retrieval of the Ogre widget to follow the same skip pattern
as MainWindow: after attempting viewport = new EditorViewport(mainWindow, 7) and
widget = viewport->getOgreWidget(), if either construction throws or returns
nullptr then call GTEST_SKIP() with a clear message (e.g., "Skipping: render
context unavailable") instead of ASSERT_NE; update references in this block
(MainWindow, EditorViewport, getOgreWidget, viewport, widget) so the test
gracefully skips under Xvfb/headless environments.

@sonarqubecloud
Copy link
Copy Markdown

@fernandotonon fernandotonon merged commit 36d40f4 into master Mar 27, 2026
18 checks passed
@fernandotonon fernandotonon deleted the codex/coverage-push-5 branch March 27, 2026 15:36
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.

1 participant