test(assembly): expand drag solve test coverage — multi-step, combined joints, orientation tracking #339
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The drag solve test suite has insufficient coverage, which allowed the planar half-space drag flip bug (#338) and its five preceding fix attempts to pass all tests while the bug persisted in interactive use. Every iteration of the fix passed the existing tests — meaning the tests don't exercise the code paths that actually break.
This issue tracks the gaps and proposes specific test scenarios to close them.
Current test landscape
Solver tests (
mods/solver/tests/) — 17 filestest_preference.pynewton_solve()onlytest_joints.pytest_solver.pytest_newton.pytest_bfgs.pytest_constraints.pytest_constraints_phase2.pytest_decompose.pytest_diagnostics.pytest_dof.pytest_entities.pytest_geometry.pytest_expr.pytest_params.pytest_prepass.pytest_codegen.pyconsole_test_phase5.pyAssembly C++ tests (
src/Mod/Assembly/AssemblyTests/) — 7 filesTestCore.pyTestSolverIntegration.pyTestKindredSolverIntegration.pyTestKCSolvePy.pyTestDatumClassification.pyTestAssemblyOriginPlanes.pyTestCommandInsertLink.pyTotal drag API test coverage: zero. No test anywhere calls
pre_drag(),drag_step(), orpost_drag().Coverage gaps
Gap 1: No drag protocol tests
The three-phase drag API (
pre_drag/drag_step/post_drag) is completely untested. This is the primary interaction model for users manipulating assemblies.Missing scenarios:
pre_drag()-> N xdrag_step()->post_drag()Gap 2: No multi-step incremental drag sequences
All existing solve tests use a single-shot solve from displaced initial conditions. None test the incremental pattern where each step's output becomes the next step's initial guess. The planar drift bug only manifests across multiple incremental steps as numerical error accumulates.
Missing scenarios:
Gap 3: No large-rotation drag tests
The largest rotation tested in the suite is 90 degrees (
test_entities.py,test_joints.py), and only as a static initial condition — never as a drag target.Missing scenarios:
Gap 4: No combined-joint drag tests
test_joints.pytests each joint type in isolation. The planar drift bug specifically occurs with Cylindrical + Planar combined. No test exercises joint combinations under drag.Missing scenarios:
Gap 5: No orientation preservation tests across drag steps
test_preference.pytests half-space sign preservation for a single solve, but never verifies that orientation is preserved across a drag sequence. The 91-degree validator in C++ catches catastrophic flips, but there's no test that the solver doesn't gradually drift orientation across steps.Missing scenarios:
dot(z_body, z_fixed) > 0holds at every drag step for a Planar constraintGap 6: No half-space tracking under drag
test_preference.pytestscompute_half_spaces()andapply_half_space_correction()in isolation. It never tests half-space tracking through the drag pipeline where the correction interacts with cached state, baseline updates, and the C++ validator.Missing scenarios:
Gap 7: No
validateNewPlacements()unit testsThe C++ 91-degree orientation validator is untested. It's the final safety net and the symptom that surfaces when the solver produces bad results.
Missing scenarios:
savePlacementsForUndo()) resets the comparison pointProposed test additions
Priority 1 — Regression test for #338
Add
test_planar_cylindrical_drag.py(or extendtest_joints.py) with:Priority 2 — Drag protocol integration tests
Add
test_drag_protocol.pyexercising the Python solver's drag API:test_drag_basic_flow— pre_drag/drag_step/post_drag lifecycletest_drag_step_convergence— every step convergestest_drag_residuals_stay_satisfied— residuals < tol at each steptest_drag_50_steps_smooth_arc— long sequence stabilityPriority 3 — Combined joint drag tests
Extend joint tests with drag sequences for:
Priority 4 — Half-space tracking under drag
Extend
test_preference.pywith drag-sequence half-space tests:test_planar_halfspace_no_correction_on_plane— verify correction_fn=None for distance=0test_halfspace_indicator_stable_across_drag— sign doesn't flip during smooth dragtest_halfspace_correction_off_plane— correction fires correctly for offset planar constraintsPriority 5 — C++ validateNewPlacements unit tests
If feasible via pybind11/FreeCADCmd:
test_validate_small_rotation_passestest_validate_large_rotation_rejectedtest_validate_grounded_movement_rejectedtest_validate_baseline_update_resets_comparisonRelated
Completed successfully.