diff --git a/continue.md b/continue.md index f3d4aa1..bad57b5 100644 --- a/continue.md +++ b/continue.md @@ -4,6 +4,7 @@ ### 1. Structure - One `SCENARIO("description")` per logical test group, with `[tag1][tag2]` annotations +- Run `./build/orbit_test --list-tags` to see tags used by other tests. Original tags from the old test file are a useful starting point, but the implementor has discretion to choose appropriate tags. - **Use SCENARIO to share setup/teardown across multiple SECTIONs.** Catch2 re-initializes the fixture before each SECTION, so declare shared constants, structs, and variables in the SCENARIO body (between the opening `{` and the first `SECTION`). These persist across all SECTIONs within the SCENARIO. - Example: a `SimulationState* sim` created once in the SCENARIO body, then each SECTION mutates and tests it independently. - Embed expected values directly in `WithinAbs()` calls (see Section 4 for precalc script usage). No need to declare named constants unless the value is reused. @@ -13,7 +14,6 @@ ### 2. Duplication Elimination - Use lambdas that capture the fixture for repeated setup→call→assert patterns - Reuse shared structs in-place (mutate fields rather than recreating) -- Single-line `SECTION`s when body is one statement: `SECTION("name") { helper(arg); }` ### 3. Assertions - Include `src/test_utilities.h` for tolerance constants and test utilities @@ -43,7 +43,6 @@ All constants defined in `src/test_utilities.h` — use those, do not redefine l ### 4. Precalc Scripts - For each test file, create `scripts/precalc_.py` that computes expected values. -- **Check the capability matrix first** — only use sim_engine.py for implemented features. - **Always output local-frame values** (distances from parent, not global from origin). - C++ tests typically use local coordinates (e.g., `vec3_distance(craft->local_position, (Vec3){0,0,0})`). - Global distances are dominated by parent body positions (e.g., Earth-Sun distance swamps LEO orbit). @@ -51,51 +50,42 @@ All constants defined in `src/test_utilities.h` — use those, do not redefine l - Output C++-style comments with precalculated expected values for embedding in the test. Tolerances are chosen separately by the test writer using the Tolerance Reference table — the precalc script should not output tolerance values. - **No decorative comments in precalc scripts.** Use simple blank lines between sections, no `# ====` or `# -----` separators. - Run with: `python3 scripts/precalc_.py` -- If sim_engine.py lacks a feature, **stop to notify the user what feature is missing** -## Refactoring Procedure - -### Step 1: Refactor -- Verify the test file has a TOML config in `old_tests/`. If it doesn't, the test is likely hardcoded — still refactor the C++ code but skip the TOML rewrite step. -- Check if the test is already in `tests/` (already refactored). Skip if so. -- Check the capability matrix in the Tooling & Sim Engine Capabilities section — if the test needs SOI, maneuvers, rendezvous, etc., flag this before starting. -- Process **one test file at a time**. -- Create `scripts/precalc_.py` and run it to get expected values. -- Copy from `old_tests/` to `tests/`, rewrite using the pattern from `test_true_anomaly_roundtrip.cpp`. -- Rewrite TOML configs to TOML 1.0 inline table syntax (single-line `{}`). -- Follow all rules in sections 1-4 above. - -### Step 2: Tighten Tolerances -- Build and verify: `make test-build` then `./build/orbit_test -s '[tag]'`. -- Run full suite: `./build/orbit_test | tail`. -- Review every tolerance against actual observed errors from `-s` output. -- **If a test fails due to a tolerance being too tight, report the observed error to the user and ask whether to loosen the constant or investigate the root cause. Never silently widen a tolerance.** -- Refer to the tolerance reference table in Section 3 for constant names. - -### Step 3: Code Review -- Remove unused includes (only include what's actually used). -- Remove unused variables (e.g., `const double mu = G * M_sun;` if never referenced). -- Look for repeated initialization patterns — extract into helper lambdas (`make_elements`, `convert_and_recover`). -- Use `const` for all fixture data and recovered results. -- Replace C-style arrays with `std::array` where appropriate. -- Ensure consistent tolerance usage (no hardcoded `1e-4` when `ANG_TOL_COARSE` exists). -- Check for `compare_vec3` availability in `test_utilities` instead of 6 individual `REQUIRE_THAT` calls. -- Run full suite again: `make test`. +## Test Refactoring Status -#### Final Systematic REQUIRE Statement Review -After Step 3, review every `REQUIRE` in the test file: +### Completed +- `test_barkers_equation` — Barker's equation unit tests + parabolic propagation +- `test_cartesian_to_elements_advanced` — Advanced conversion tests (eccentricity spectrum, inclination, true anomaly, 3D orientation) +- `test_cartesian_to_elements_basic` — Element round-trip conversion (semi-major axis, eccentricity, true anomaly, inclination, radius, velocity) +- `test_parabolic_orbit` — Parabolic orbit energy conservation + escape trajectory + initial conditions +- `test_extreme_eccentricity` — High-eccentricity orbits (single SCENARIO, precalculated values, REL_TOL) +- `test_extreme_orientation_mixed` — Extreme orientation conversions, rotation matrix properties, singularity handling +- `test_extreme_timescales` — 9 TEST_CASEs → 1 SCENARIO with 11 SECTIONs, all WithinAbs use named constants +- `test_analytical_propagation` — 5 SCENARIOs → 1 SCENARIO with 23 SECTIONs, precalculated values, all WithinAbs use named constants +- `test_moon_orbits` — Multi-body hierarchical propagation with local/global coordinate tracking +- `test_energy` — Energy calculations and conservation tests +- `test_inclined_orbits` — 3D inclined orbit conversions, Molniya orbits, rotation matrices +- `test_maneuvers` — Impulsive burn tests with precalculated values +- `test_orbital_period` — Orbital period calculations, SCENARIO/SECTION pattern +- `test_true_anomaly_roundtrip` — True anomaly conversion round-trips, tight tolerances +- `test_physics_utilities` — Vector math, acceleration, matrix ops, rotation matrices, compare_vec3 +- `test_periapsis_burn` — prograde burns +- `test_hybrid_burns` — 14 TEST_CASEs → 1 SCENARIO with 22 SECTIONs, impulse + continuous burns, precalculated values; converted 17 qualitative checks to quantitative, replaced hardcoded tolerances with named constants (A_TOL, E_TOL, D_TOL, M_TOL, ANG_TOL, R_TOL) -1. `grep -Rn 'REQUIRE' tests/.cpp` -2. Categorize each: - - **Hardcoded tolerances** → replace with named constant - - **Qualitative** (`a > b`, `x < 0.1`, `fabs(x) > 0`) → convert to quantitative via precalc - - **OK as-is** → booleans, integers, strings, enums -5. Verify precalc outputs all needed values -6. `make test-build` → `./build/orbit_test -s '[tag]'` +### Can Refactor Now (sim_engine.py supports all features needed) +- `test_omega_debug` — burn + element reconstruction + maneuver triggers +- `test_maneuver_planning` — maneuver trigger system (TIME + elliptical TRUE_ANOMALY triggers) +- `test_orbit_rendering` — rendering tests (check if sim_engine needed) +- `test_precision_boundaries` — boundary condition tests +- `test_invalid_parent_assignment` — validation/error handling tests +- `test_newton_raphson_convergence` — numerical convergence tests -### Step 4: User interaction -- **Always ask for review** before moving to the next file. -- **Only commit when asked.** +### Blocked on Missing Features +- `test_soi_transition` — needs SOI transitions +- `test_root_body_transitions` — needs SOI transitions +- `test_hybrid_energy_conservation` — needs energy functions (KE, PE, total) +- `test_hyperbolic_orbit` — needs hyperbolic propagation +- `test_rendezvous` — needs Hohmann transfer calculations ## Tooling & Sim Engine Capabilities @@ -129,40 +119,46 @@ After Step 3, review every `REQUIRE` in the test file: - Energy functions (KE, PE, total) - Hyperbolic propagation -## Test Refactoring Status +## Refactoring Procedure -### Completed -- `test_barkers_equation` — Barker's equation unit tests + parabolic propagation -- `test_cartesian_to_elements_advanced` — Advanced conversion tests (eccentricity spectrum, inclination, true anomaly, 3D orientation) -- `test_cartesian_to_elements_basic` — Element round-trip conversion (semi-major axis, eccentricity, true anomaly, inclination, radius, velocity) -- `test_parabolic_orbit` — Parabolic orbit energy conservation + escape trajectory + initial conditions -- `test_extreme_eccentricity` — High-eccentricity orbits (single SCENARIO, precalculated values, REL_TOL) -- `test_extreme_orientation_mixed` — Extreme orientation conversions, rotation matrix properties, singularity handling -- `test_extreme_timescales` — 9 TEST_CASEs → 1 SCENARIO with 11 SECTIONs, all WithinAbs use named constants -- `test_analytical_propagation` — 5 SCENARIOs → 1 SCENARIO with 23 SECTIONs, precalculated values, all WithinAbs use named constants -- `test_moon_orbits` — Multi-body hierarchical propagation with local/global coordinate tracking -- `test_energy` — Energy calculations and conservation tests -- `test_inclined_orbits` — 3D inclined orbit conversions, Molniya orbits, rotation matrices -- `test_maneuvers` — Impulsive burn tests with precalculated values -- `test_orbital_period` — Orbital period calculations, SCENARIO/SECTION pattern -- `test_true_anomaly_roundtrip` — True anomaly conversion round-trips, tight tolerances -- `test_physics_utilities` — Vector math, acceleration, matrix ops, rotation matrices, compare_vec3 -- `test_periapsis_burn` — prograde burns -- `test_hybrid_burns` — 14 TEST_CASEs → 1 SCENARIO with 22 SECTIONs, impulse + continuous burns, precalculated values; converted 17 qualitative checks to quantitative, replaced hardcoded tolerances with named constants (A_TOL, E_TOL, D_TOL, M_TOL, ANG_TOL, R_TOL) +### Step 1: Refactor +- **Pre-flight check:** Before starting, verify the python ./scripts/sim_engine.py supports all features the test needs (SOI, Hohmann transfers, rendezvous, hyperbolic propagation, energy functions). If any feature is missing, stop and report it to the user — do not begin refactoring until unblocked. +- Check if the test is already in `tests/` (already refactored). Skip if so. +- Process **one test file at a time**. +- Create `scripts/precalc_.py` and run it to get expected values. Tests that use the simulation engine will need a precalc script regardless of whether a TOML config exists. +- Copy from `old_tests/` to `tests/`, rewrite using the pattern from `test_true_anomaly_roundtrip.cpp`. +- Verify the test file has a TOML config in `old_tests/`. If it doesn't, the test is likely hardcoded — still refactor the C++ code but skip the TOML rewrite step. +- Rewrite TOML configs to TOML 1.0 inline table syntax (single-line `{}`). +- Follow all rules in sections 1-4 above. -### Can Refactor Now (sim_engine.py supports all features needed) -- `test_omega_debug` — burn + element reconstruction + maneuver triggers -- `test_maneuver_planning` — maneuver trigger system (TIME + elliptical TRUE_ANOMALY triggers) -- `test_orbit_rendering` — rendering tests (check if sim_engine needed) -- `test_precision_boundaries` — boundary condition tests -- `test_invalid_parent_assignment` — validation/error handling tests -- `test_newton_raphson_convergence` — numerical convergence tests +### Step 2: Tighten Tolerances +- Build and verify: `make test-build` then `./build/orbit_test -s '[tag]'`. +- Run full suite: `./build/orbit_test | tail`. +- Review every tolerance against actual observed errors from `-s` output. +- **If a test fails due to a tolerance being too tight, report the observed error to the user and ask whether to loosen the constant or investigate the root cause. Never silently widen a tolerance.** +- Refer to the tolerance reference table in Section 3 for constant names. -### Blocked on Missing Features -- `test_soi_transition` — needs SOI transitions -- `test_root_body_transitions` — needs SOI transitions -- `test_hybrid_energy_conservation` — needs energy functions (KE, PE, total) -- `test_hyperbolic_orbit` — needs hyperbolic propagation -- `test_rendezvous` — needs Hohmann transfer calculations +### Step 3: Code Review +- Remove unused includes (only include what's actually used). +- Remove unused variables (e.g., `const double mu = G * M_sun;` if never referenced). +- Look for repeated initialization patterns — extract into helper lambdas (`make_elements`, `convert_and_recover`). +- Use `const` for all fixture data and recovered results. +- Replace C-style arrays with `std::array` where appropriate. +- Ensure consistent tolerance usage (no hardcoded `1e-4` when `ANG_TOL_COARSE` exists). +- Check for `compare_vec3` availability in `test_utilities` instead of 6 individual `REQUIRE_THAT` calls. +- Run full suite again: `make test`. + +#### Final Systematic REQUIRE Statement Review +After Step 3, review every `REQUIRE` in the test file: +1. `grep -Rn 'REQUIRE' tests/.cpp` +2. Categorize each: + - **Hardcoded tolerances** → replace with named constant + - **Qualitative** (`a > b`, `x < 0.1`, `fabs(x) > 0`) → convert to quantitative via precalc + - **OK as-is** → booleans, integers, strings, enums +4. Verify precalc outputs all needed values +5. `make test-build` → `./build/orbit_test -s '[tag]'` +### Step 4: User interaction +- **Always ask for review** before moving to the next file. +- **Only commit when asked.**