test+docs(simulation): address PR #164 re-review (maritime)

Re-review of the maritime moderation addition (Hoshe REQUEST_CHANGES, Tyre APPROVE):

- every_planet_class_derives_within_its_band now sweeps hydrosphere
  (none/ocean/liquid_water/rivers/ice) as well, so the maritime-compressed
  gradient path is covered by the band invariant — not just the None/1.0 case.
  (Hoshe #1, Tyre #1)
- Update the BodyParams.hydrosphere doc comment to the real systems.db vocabulary
  (liquid_water/ocean-coastal/extensive/etc.) the maritime table keys on. (Hoshe #2)

cargo test passes (the band sweep now ~59k in-band assertions), clippy -D warnings
clean, fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-08 19:09:39 +02:00
co-authored by Claude Opus 4.8
parent b894a721ad
commit bafed6ad9a
+26 -16
View File
@@ -133,7 +133,11 @@ pub enum VegetationClass {
/// only — see `derive_temperature_c`.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct BodyParams {
/// `bodies.hydrosphere` — "ocean" | "ice" | "rivers" | "none" | "subsurface" | NULL
/// `bodies.hydrosphere` — the real vocabulary in systems.db: "ice",
/// "liquid_water", "none", "rivers", "moderate", "ocean", "minimal", "trace",
/// "subsurface_liquid", "rivers-lakes", "extensive", "subsurface_ice",
/// "subsurface", "ocean-coastal" | NULL. The `[hydrosphere_maritime]` table
/// keys on these for temperature moderation (D-240).
pub hydrosphere: Option<String>,
/// `bodies.atmosphere` — "breathable" | "thin" | "toxic" | "none" | "dense" | NULL
pub atmosphere: Option<String>,
@@ -1359,21 +1363,27 @@ mod tests {
// Sweep sea level AND high altitude so the lapse term + clamp
// are exercised jointly against the cold end, not just lat alone.
for elev in [0.0_f64, 6.0] {
for seed in seeds {
let params = BodyParams {
planet_class: Some((*class).into()),
atmosphere: Some((*atmo).into()),
region_latitude_deg: lat,
elevation_km: elev,
..Default::default()
};
let t = derive_temperature_c(&params, &climate, seed)
.expect("non-airless body must have temperature");
assert!(
t >= cold && t <= warm,
"class={class} atmo={atmo} lat={lat} elev={elev} seed={seed}: \
temperature {t}°C outside band [{cold}, {warm}]"
);
// Sweep hydrosphere too, so the maritime-compressed gradient
// path is covered by the band invariant (not just None/1.0).
for hydro in ["none", "ocean", "liquid_water", "rivers", "ice"] {
for seed in seeds {
let params = BodyParams {
planet_class: Some((*class).into()),
atmosphere: Some((*atmo).into()),
hydrosphere: Some(hydro.into()),
region_latitude_deg: lat,
elevation_km: elev,
..Default::default()
};
let t = derive_temperature_c(&params, &climate, seed)
.expect("non-airless body must have temperature");
assert!(
t >= cold && t <= warm,
"class={class} atmo={atmo} hydro={hydro} lat={lat} \
elev={elev} seed={seed}: temperature {t}°C outside \
band [{cold}, {warm}]"
);
}
}
}
}