Skip to content

test(bone-drag): cover entity tick + needUpdate between drags - #393

Merged
fernandotonon merged 1 commit into
masterfrom
test/bone-drag-tick-coverage
May 5, 2026
Merged

test(bone-drag): cover entity tick + needUpdate between drags#393
fernandotonon merged 1 commit into
masterfrom
test/bone-drag-tick-coverage

Conversation

@fernandotonon

@fernandotonon fernandotonon commented May 5, 2026

Copy link
Copy Markdown
Owner

Summary

Two new BoneDragRelease tests covering the setUpdate-sequence gap not exercised by the existing accumulation tests:

  • EntityTickBetweenDragsDoesNotAccumulate — drives entity->_updateAnimation() + skeleton->_updateTransforms() between two drags. If the revert path didn't fully restore TRS before clearing manualControlled, the tick would re-apply the curve on top of leaked state and the second drag would start from a shifted pose.

  • NeedUpdateBetweenDragsDoesNotAccumulate — forces a derived-transform recompute via bone->needUpdate(true) + bone->_update(true, true) between drags so any cached transform state is flushed mid-sequence.

These complement the existing AutoKeyOffTwoDragsDoNotAccumulate, YThenXDragsDoNotLeakYIntoX, and SetDerivedPositionDragRevertsCleanly tests by adding the "frame tick happens between drags" path that the user-visible bug report alludes to.

Test-only change — no production code modifications.

Test plan

  • cmake --build build_local --target QtMeshEditor succeeds
  • Linux CI runs ./build_local/bin/UnitTests --gtest_filter="BoneDragReleaseTest.*" (auto-globbed)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Added two regression tests ensuring bone drag with auto-key off does not accumulate transform/curve state across consecutive drags.
    • Verifies correct pose reversion and prevents derived-position drift when intermediate animation or transform updates occur between drags.

@coderabbitai

coderabbitai Bot commented May 5, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds two regression tests ensuring bone drag state does not accumulate across consecutive drags with auto-key disabled, covering an intermediate entity animation tick + skeleton transform update and a forced bone cache/transform recompute between drags.

Changes

Regression Tests for Bone Drag State

Layer / File(s) Summary
Test Cases / New
src/BoneDragRelease_test.cpp
Adds two tests: EntityTickBetweenDragsDoesNotAccumulate and NeedUpdateBetweenDragsDoesNotAccumulate.
Behavior Exercised — drag/revert flow
src/BoneDragRelease_test.cpp
Both tests perform an initial bone drag and expect BoneDragRelease::apply to return Revert.
Intermediate State Changes
src/BoneDragRelease_test.cpp
First test performs entity->_updateAnimation() and entity->getSkeleton()->_updateTransforms() between drags; second test calls bone->needUpdate(true) and bone->_update(true, true) to force recompute.
Assertions / Regression Checks
src/BoneDragRelease_test.cpp
Both tests assert the bone's local position equals the original pre-drag pose after the second drag and that derived-position drift is negligible.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • fernandotonon/QtMeshEditor#384: Tests verify that auto-key off behavior prevents state leakage across drags, which directly relates to auto-key wiring and keyframe capture changes in the referenced PR.

Poem

🐰 I hopped through tests with careful paws,
Dragged a bone, then checked the laws,
Tick and flush, then one more try,
No creeping drift — hips still high,
Hooray for stable poses! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and specifically describes the main change: adding test coverage for bone drag behavior when entity ticks and needUpdate occur between drags.
Description check ✅ Passed The description fully covers both required template sections with clear technical details about the two new test cases and their purpose, supplemented with test plan items.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 test/bone-drag-tick-coverage

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@src/BoneDragRelease_test.cpp`:
- Around line 246-250: Replace the conditional check around the animation setup
with an explicit test assertion so the test fails if the animation is missing:
call ASSERT_TRUE(entity->hasAnimationState("TestAnim")) before retrieving the
state, then proceed to call entity->getAnimationState("TestAnim"),
state->setEnabled(true), and state->setTimePosition(0.0f) as before; this
ensures hasAnimationState, getAnimationState, setEnabled, and setTimePosition
are exercised only when the precondition is guaranteed.
🪄 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: ed827f0e-72ee-4752-a5f0-04ab41deafa2

📥 Commits

Reviewing files that changed from the base of the PR and between d59eb7f and 7488f07.

📒 Files selected for processing (1)
  • src/BoneDragRelease_test.cpp

Comment on lines +246 to +250
if (entity->hasAnimationState("TestAnim")) {
auto* state = entity->getAnimationState("TestAnim");
state->setEnabled(true);
state->setTimePosition(0.0f);
}

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 | 🟡 Minor | ⚡ Quick win

Make the animation precondition explicit to avoid vacuous passes.

Using if (entity->hasAnimationState("TestAnim")) can let this regression pass without exercising the tick path if the fixture/asset changes. Prefer an assertion (ASSERT_TRUE(...)) before enabling/resetting the state so the test fails when its core precondition is missing.

🤖 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 `@src/BoneDragRelease_test.cpp` around lines 246 - 250, Replace the conditional
check around the animation setup with an explicit test assertion so the test
fails if the animation is missing: call
ASSERT_TRUE(entity->hasAnimationState("TestAnim")) before retrieving the state,
then proceed to call entity->getAnimationState("TestAnim"),
state->setEnabled(true), and state->setTimePosition(0.0f) as before; this
ensures hasAnimationState, getAnimationState, setEnabled, and setTimePosition
are exercised only when the precondition is guaranteed.

…drags

Two new BoneDragRelease tests targeting the setUpdate-sequence gap:

- EntityTickBetweenDragsDoesNotAccumulate: simulates an animation
  frame tick (entity->_updateAnimation + skeleton->_updateTransforms)
  between two drags. If the revert path doesn't fully restore TRS
  before clearing manualControlled, the tick re-applies the curve on
  top of leaked state.

- NeedUpdateBetweenDragsDoesNotAccumulate: forces a derived-transform
  recompute via bone->needUpdate(true) + bone->_update(true,true)
  between drags so any cached state is flushed mid-sequence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fernandotonon
fernandotonon force-pushed the test/bone-drag-tick-coverage branch from 7488f07 to 243a930 Compare May 5, 2026 13:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/BoneDragRelease_test.cpp (1)

246-250: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Make the animation precondition explicit to prevent vacuous passes.

At Line 246, the conditional can silently skip the core tick path if "TestAnim" disappears from fixtures. Assert the precondition and proceed unconditionally with state setup.

Suggested patch
-    if (entity->hasAnimationState("TestAnim")) {
-        auto* state = entity->getAnimationState("TestAnim");
-        state->setEnabled(true);
-        state->setTimePosition(0.0f);
-    }
+    ASSERT_TRUE(entity->hasAnimationState("TestAnim"));
+    auto* state = entity->getAnimationState("TestAnim");
+    ASSERT_NE(state, nullptr);
+    state->setEnabled(true);
+    state->setTimePosition(0.0f);
🤖 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 `@src/BoneDragRelease_test.cpp` around lines 246 - 250, The test currently
guards setup with entity->hasAnimationState("TestAnim") which can silently skip
the tick path; replace that silent conditional with an explicit precondition
assertion (e.g., assert or EXPECT_TRUE) that "TestAnim" exists, then
unconditionally obtain the state via entity->getAnimationState("TestAnim") and
call state->setEnabled(true) and state->setTimePosition(0.0f) so the test always
performs the intended setup and fails loudly if the animation is missing.
🤖 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.

Duplicate comments:
In `@src/BoneDragRelease_test.cpp`:
- Around line 246-250: The test currently guards setup with
entity->hasAnimationState("TestAnim") which can silently skip the tick path;
replace that silent conditional with an explicit precondition assertion (e.g.,
assert or EXPECT_TRUE) that "TestAnim" exists, then unconditionally obtain the
state via entity->getAnimationState("TestAnim") and call state->setEnabled(true)
and state->setTimePosition(0.0f) so the test always performs the intended setup
and fails loudly if the animation is missing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 450ae6bc-c55f-4beb-b0d0-ac38625f0fb9

📥 Commits

Reviewing files that changed from the base of the PR and between 7488f07 and 243a930.

📒 Files selected for processing (1)
  • src/BoneDragRelease_test.cpp

@sonarqubecloud

sonarqubecloud Bot commented May 5, 2026

Copy link
Copy Markdown

@fernandotonon
fernandotonon merged commit df6bd70 into master May 5, 2026
19 checks passed
@fernandotonon
fernandotonon deleted the test/bone-drag-tick-coverage branch May 5, 2026 15:25
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