- One `SCENARIO("description")` per logical test group, with `[tag1][tag2]` annotations
- 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.
- **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.
- 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.
- 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
### 2. Duplication Elimination
- Use lambdas that capture the fixture for repeated setup→call→assert patterns
- Use lambdas that capture the fixture for repeated setup→call→assert patterns
- Reuse shared structs in-place (mutate fields rather than recreating)
- 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
### 3. Assertions
- Include `src/test_utilities.h` for tolerance constants and test utilities
- 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
### 4. Precalc Scripts
- For each test file, create `scripts/precalc_<test_name>.py` that computes expected values.
- For each test file, create `scripts/precalc_<test_name>.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).
- **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})`).
- 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).
- 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.
- 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.
- **No decorative comments in precalc scripts.** Use simple blank lines between sections, no `# ====` or `# -----` separators.
- Run with: `python3 scripts/precalc_<test_name>.py`
- Run with: `python3 scripts/precalc_<test_name>.py`
- If sim_engine.py lacks a feature, **stop to notify the user what feature is missing**
## Refactoring Procedure
## Test Refactoring Status
### 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_<test_name>.py` and run it to get expected values.
- Copy from `old_tests/` to `tests/`, rewrite using the pattern from `test_true_anomaly_roundtrip.cpp`.
- 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`.
#### Final Systematic REQUIRE Statement Review
### Completed
After Step 3, review every `REQUIRE` in the test file:
- `test_barkers_equation` — Barker's equation unit tests + parabolic propagation
- `test_rendezvous` — needs Hohmann transfer calculations
## Tooling & Sim Engine Capabilities
## Tooling & Sim Engine Capabilities
@ -129,40 +119,46 @@ After Step 3, review every `REQUIRE` in the test file:
- Energy functions (KE, PE, total)
- Energy functions (KE, PE, total)
- Hyperbolic propagation
- Hyperbolic propagation
## Test Refactoring Status
## Refactoring Procedure
### Completed
### Step 1: Refactor
- `test_barkers_equation` — Barker's equation unit tests + parabolic propagation
- **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.
- Create `scripts/precalc_<test_name>.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.
- 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.
- `test_extreme_timescales` — 9 TEST_CASEs → 1 SCENARIO with 11 SECTIONs, all WithinAbs use named constants
- **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.**