venuss 0.0.3

Venus celestial simulation crate for the MilkyWay SolarSystem workspace
Documentation
use venuss::lighting::day_night::{DayNightCycle, DaylightState};
use venuss::lighting::seasons::{Season, season_at};
use venuss::lighting::solar_position::{SolarPosition, solar_declination_deg};

// ── Day/Night ──

#[test]
fn midday_equator_is_day() {
    let c = DayNightCycle::new(0.0);
    let s = c.state_at(0.0, 12.0);
    assert_eq!(s, DaylightState::Day);
}

#[test]
fn midnight_equator_is_night() {
    let c = DayNightCycle::new(0.0);
    let s = c.state_at(0.0, 0.0);
    assert_eq!(s, DaylightState::Night);
}

#[test]
fn state_at_various_latitudes() {
    let c = DayNightCycle::new(0.0);
    for lat in [-60.0, -30.0, 0.0, 30.0, 60.0] {
        let s = c.state_at(lat, 12.0);
        assert!(s == DaylightState::Day || s == DaylightState::Twilight);
    }
}

#[test]
fn very_long_day_cycle() {
    let c = DayNightCycle::new(90.0);
    let s = c.state_at(0.0, 12.0);
    assert!(s == DaylightState::Day || s == DaylightState::Twilight || s == DaylightState::Night);
}

// ── Seasons ──

#[test]
fn season_at_0_is_spring() {
    assert_eq!(season_at(0.0), Season::Spring);
}

#[test]
fn season_at_90_is_summer() {
    assert_eq!(season_at(90.0), Season::Summer);
}

#[test]
fn season_at_180_is_autumn() {
    assert_eq!(season_at(180.0), Season::Autumn);
}

#[test]
fn season_at_270_is_winter() {
    assert_eq!(season_at(270.0), Season::Winter);
}

#[test]
fn four_distinct_seasons() {
    let s0 = season_at(0.0);
    let s90 = season_at(90.0);
    let s180 = season_at(180.0);
    let s270 = season_at(270.0);
    assert!(s0 != s90 && s90 != s180 && s180 != s270);
}

// ── Solar Position ──

#[test]
fn solar_declination_bounded() {
    let d = solar_declination_deg(0.0);
    assert!(d.abs() < 90.0);
}

#[test]
fn solar_declination_varies_with_ls() {
    let d0 = solar_declination_deg(0.0);
    let d90 = solar_declination_deg(90.0);
    assert!((d0 - d90).abs() > 0.001 || d0.abs() < 0.1);
}

#[test]
fn solar_position_noon_equator_above_horizon() {
    let sp = SolarPosition::compute(0.0, 12.0, 0.0, 0.0);
    assert!(sp.is_above_horizon());
}

#[test]
fn solar_position_midnight_below_horizon() {
    let sp = SolarPosition::compute(0.0, 0.0, 0.0, 0.0);
    assert!(!sp.is_above_horizon());
}

#[test]
fn solar_position_elevation_noon_positive() {
    let sp = SolarPosition::compute(0.0, 12.0, 0.0, 0.0);
    assert!(sp.elevation_deg > 0.0);
}

#[test]
fn solar_direction_unit_vector() {
    let sp = SolarPosition::compute(0.0, 12.0, 0.0, 0.0);
    let len = (sp.direction[0].powi(2) + sp.direction[1].powi(2) + sp.direction[2].powi(2)).sqrt();
    assert!((len - 1.0).abs() < 0.01);
}

#[test]
fn solar_position_at_pole_finite() {
    let sp = SolarPosition::compute(0.0, 12.0, 90.0, 0.0);
    assert!(sp.elevation_deg.is_finite());
}

// ── Venus-specific: extremely slow rotation ──

#[test]
fn venus_day_very_long() {
    assert!(venuss::SOL_S.abs() > 1.0e7);
}

#[test]
fn venus_sidereal_day_longer_than_year() {
    assert!(venuss::SIDEREAL_DAY_S.abs() > venuss::VENUS_YEAR_S);
}