Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-core/tests/ice_drip_kittest.rs

//! **Kittest PROOF for the ice-drip winter decor** (the Skaði "Skade Vinter"
//! scene) — the same shape as `facett-graph3d`'s clock-determinism kittest.
//!
//! 1. **Deterministic given `(seed, clock)`** — two drips at the same clock have
//!    byte-identical observable `state_json()`; advancing the clock changes it.
//! 2. **It really paints in a real egui frame** — driven headlessly through
//!    `egui_kittest` (no GPU): the icicles + falling melt-droplets + frost shimmer
//!    are laid into a live `egui::Painter` without panicking.
//! 3. **The gate holds** — a disabled drip has zero active droplets.
//!
//! Run: `cargo test -p facett-core --test ice_drip_kittest`.

use egui_kittest::Harness;

use facett_core::effects::IceDrip;

#[test]
fn ice_drip_is_clock_deterministic_paints_headlessly_and_gates() {
    // (1) Deterministic: same seed + clock ⇒ identical observable state.
    let a = IceDrip::new(12, 7).enabled(true).at_clock(2.0);
    let b = IceDrip::new(12, 7).enabled(true).at_clock(2.0);
    assert_eq!(a.state_json(), b.state_json(), "same (seed,clock) ⇒ identical drip");
    let later = IceDrip::new(12, 7).enabled(true).at_clock(2.4);
    assert_ne!(a.state_json(), later.state_json(), "advancing the clock moves the drip");

    // Every live droplet's fall is normalised into [0,1] (gravity curve), and the
    // scene is non-empty — real winter motion, not a stub.
    let s = a.state_json();
    assert_eq!(s["enabled"], true);
    assert!(s["active_droplets"].as_u64().unwrap() > 0, "live droplets: {s}");
    for d in s["droplets"].as_array().unwrap() {
        let y = d["y_norm"].as_f64().unwrap();
        assert!((0.0..=1.0).contains(&y), "droplet fall is normalised: {d}");
    }

    // (2) It paints inside a real egui layout (headless kittest, no GPU): drive the
    // drip off the harness clock and lay it onto the live painter.
    let mut drip = IceDrip::new(12, 7).enabled(true);
    let mut harness = Harness::builder()
        .with_size(egui::vec2(420.0, 300.0))
        .build_ui(move |ui| {
            let r = ui.max_rect();
            drip.set_clock(ui.input(|i| i.time) as f32);
            drip.paint(ui.painter(), r);
            ui.label("skaði · skade vinter");
        });
    harness.run();

    // (3) The gate: a disabled drip is dark — nothing active.
    let off = IceDrip::new(12, 7).at_clock(2.0); // enabled defaults false
    assert_eq!(off.state_json()["active_droplets"], serde_json::json!(0), "disabled ⇒ no droplets");

    #[cfg(feature = "testmatrix")]
    facett_core::testmatrix::emit(
        "IceDrip",
        "ice_drip_clock_determinism_paint_gate",
        a.state_json() == b.state_json()
            && a.state_json() != later.state_json()
            && off.state_json()["active_droplets"] == serde_json::json!(0),
        "deterministic at a pinned clock, paints headlessly, disabled = no droplets",
    );
}