use asteroidsfactory::types::*;
#[test]
fn near_earth_apollo_basic() {
let a = near_earth::NearEarthAsteroid::new(500.0, 2500.0, 1.5, 0.3);
assert!(a.mass > 0.0);
assert!(a.surface_gravity() > 0.0);
assert!(a.escape_velocity() > 0.0);
assert!(a.perihelion_au() < a.semi_major_axis);
assert!(a.aphelion_au() > a.semi_major_axis);
}
#[test]
fn near_earth_group_classification() {
let apollo = near_earth::NearEarthAsteroid::new(100.0, 3000.0, 1.5, 0.6);
assert!(apollo.perihelion_au() < 1.017);
assert!(apollo.semi_major_axis >= 1.0);
let amor = near_earth::NearEarthAsteroid::new(100.0, 3000.0, 1.2, 0.1);
assert!(amor.perihelion_au() > 1.017);
}
#[test]
fn near_earth_tisserand() {
let a = near_earth::NearEarthAsteroid::new(200.0, 2500.0, 2.0, 0.5);
let tj = a.tisserand_jupiter();
assert!(tj > 0.0);
assert!(tj < 6.0);
}
#[test]
fn near_earth_velocity_at_perihelion_greater_than_aphelion() {
let a = near_earth::NearEarthAsteroid::new(300.0, 2500.0, 1.5, 0.4);
assert!(a.velocity_at_perihelion() > a.velocity_at_aphelion());
}
#[test]
fn near_earth_equilibrium_temperature() {
let a = near_earth::NearEarthAsteroid::new(200.0, 2500.0, 1.0, 0.1).with_albedo(0.15);
let t = a.equilibrium_temp_perihelion();
assert!(t > 200.0);
assert!(t < 400.0);
}
#[test]
fn near_earth_absolute_magnitude() {
let a = near_earth::NearEarthAsteroid::new(500.0, 2500.0, 1.5, 0.3).with_albedo(0.15);
let h = a.absolute_magnitude();
assert!(h > 10.0);
assert!(h < 30.0);
}
#[test]
fn main_belt_basic() {
let a = main_belt::MainBeltAsteroid::new(50000.0, 2700.0, 2.7);
assert!(a.mass > 0.0);
assert!(a.surface_gravity() > 0.0);
assert!(a.orbital_period() > 0.0);
}
#[test]
fn main_belt_kirkwood_gap() {
let in_gap = main_belt::MainBeltAsteroid::new(1000.0, 2700.0, 2.502);
assert!(in_gap.is_in_kirkwood_gap());
let not_gap = main_belt::MainBeltAsteroid::new(1000.0, 2700.0, 2.7);
assert!(!not_gap.is_in_kirkwood_gap());
}
#[test]
fn main_belt_spectral_type() {
let a = main_belt::MainBeltAsteroid::new(10000.0, 2700.0, 2.7)
.with_spectral_type(main_belt::SpectralType::M);
assert!(matches!(a.spectral_type, main_belt::SpectralType::M));
}
#[test]
fn main_belt_centrifugal_limit() {
let a = main_belt::MainBeltAsteroid::new(5000.0, 2700.0, 2.7);
let min_density = a.centrifugal_limit_density();
assert!(min_density > 0.0);
}
#[test]
fn main_belt_hill_sphere() {
let a = main_belt::MainBeltAsteroid::new(50000.0, 3000.0, 2.5);
let rh = a.hill_sphere_radius();
assert!(rh > 0.0);
assert!(rh > a.radius);
}
#[test]
fn trojan_l4_basic() {
let t = trojan::Trojan::new(20000.0, 2000.0, 5.2).with_lagrange_point(trojan::TrojanPoint::L4);
assert!(t.mass > 0.0);
let angle = t.lagrange_angle();
assert!((angle - std::f64::consts::PI / 3.0).abs() < 0.01);
}
#[test]
fn trojan_l5_angle() {
let t = trojan::Trojan::new(10000.0, 2000.0, 5.2).with_lagrange_point(trojan::TrojanPoint::L5);
let angle = t.lagrange_angle();
assert!((angle - (-std::f64::consts::PI / 3.0)).abs() < 0.01);
}
#[test]
fn trojan_libration() {
let t = trojan::Trojan::new(15000.0, 2000.0, 5.2).with_libration_amplitude(15.0);
let period = t.libration_period();
assert!(period > 0.0);
}
#[test]
fn trojan_stability() {
use asteroidsfactory::config::parameters::SOLAR_MASS;
let t = trojan::Trojan::new(10000.0, 2000.0, 5.2)
.with_eccentricity(0.05)
.with_inclination(10.0);
let s = t.stability_parameter(SOLAR_MASS);
assert!(s > 0.0);
}
#[test]
fn centaur_basic() {
let c = centaur::Centaur::new(50000.0, 1500.0, 13.0, 0.3);
assert!(c.mass > 0.0);
assert!(c.surface_gravity() > 0.0);
assert!(c.orbital_period() > 0.0);
}
#[test]
fn centaur_tisserand_values() {
let c = centaur::Centaur::new(30000.0, 1500.0, 13.0, 0.3);
let tj = c.tisserand_jupiter();
let tn = c.tisserand_neptune();
assert!(tj > 0.0);
assert!(tn > 0.0);
}
#[test]
fn centaur_dynamical_lifetime() {
let c = centaur::Centaur::new(50000.0, 1500.0, 15.0, 0.4);
let lt = c.dynamical_lifetime_estimate();
assert!(lt > 0.0);
}
#[test]
fn centaur_cometary_activity() {
let inside = centaur::Centaur::new(50000.0, 1500.0, 5.0, 0.5);
assert!(inside.is_inside_snow_line());
let outside = centaur::Centaur::new(50000.0, 1500.0, 20.0, 0.1);
assert!(!outside.is_inside_snow_line());
}
#[test]
fn binary_basic() {
let b = binary::BinaryAsteroid::new(5000.0, 1000.0, 2000.0, 20000.0);
assert!(b.mutual_orbital_period() > 0.0);
assert!(b.mutual_orbital_velocity_primary() > 0.0);
}
#[test]
fn binary_stability() {
let stable = binary::BinaryAsteroid::new(5000.0, 2000.0, 2000.0, 50000.0)
.with_heliocentric_orbit(2.5, 0.1);
assert!(stable.is_stable());
}
#[test]
fn binary_contact() {
let separated = binary::BinaryAsteroid::new(5000.0, 3000.0, 2000.0, 50000.0);
assert!(!separated.is_contact_binary());
let close = binary::BinaryAsteroid::new(5000.0, 3000.0, 2000.0, 7500.0);
assert!(!close.is_contact_binary());
}
#[test]
fn binary_roche_limit() {
let b = binary::BinaryAsteroid::new(5000.0, 3000.0, 2000.0, 30000.0);
let roche = b.roche_limit();
assert!(roche > 0.0);
}
#[test]
fn rubble_pile_basic() {
let r = rubble_pile::RubblePile::new(500.0, 3000.0, 0.4);
assert!(r.mass > 0.0);
assert!(r.bulk_density < r.grain_density);
}
#[test]
fn rubble_pile_spin_barrier() {
let r = rubble_pile::RubblePile::new(500.0, 3000.0, 0.4);
let limit = r.spin_limit_period();
assert!(limit > 0.0);
}
#[test]
fn rubble_pile_spin_stability() {
let slow = rubble_pile::RubblePile::new(500.0, 3000.0, 0.3).with_rotation_period(20000.0);
assert!(slow.is_spin_stable());
let fast = rubble_pile::RubblePile::new(500.0, 3000.0, 0.3).with_rotation_period(1.0);
assert!(!fast.is_spin_stable());
}
#[test]
fn rubble_pile_porosity_estimate() {
let r = rubble_pile::RubblePile::new(10000.0, 3000.0, 0.5);
let p = r.macro_porosity_estimate();
assert!(p > 0.0);
assert!(p <= 1.0);
}
#[test]
fn rubble_pile_yorp() {
let r = rubble_pile::RubblePile::new(500.0, 3000.0, 0.4).with_orbit(2.5, 0.1);
let t = r.yorp_timescale(2.5);
assert!(t > 0.0);
}
#[test]
fn metallic_basic() {
let m = metallic::MetallicAsteroid::new(50000.0, 0.85);
assert!(m.mass > 0.0);
assert!(m.surface_gravity() > 0.0);
assert!(m.iron_fraction > 0.0);
}
#[test]
fn metallic_composition() {
let m = metallic::MetallicAsteroid::new(10000.0, 0.9).with_nickel_fraction(0.08);
let content = m.metal_content_mass();
assert!(content > 0.0);
assert!(content < m.mass);
let sil = m.silicate_fraction();
assert!(sil >= 0.0);
assert!(sil < 1.0);
}
#[test]
fn metallic_differentiation() {
let large = metallic::MetallicAsteroid::new(100000.0, 0.9).with_orbit(2.7, 0.1);
let small = metallic::MetallicAsteroid::new(100.0, 0.5).with_orbit(2.7, 0.1);
assert!(large.is_differentiated());
assert!(!small.is_differentiated());
}
#[test]
fn metallic_core_radius() {
let m = metallic::MetallicAsteroid::new(50000.0, 0.9);
let core = m.core_radius_estimate();
assert!(core > 0.0);
assert!(core <= m.radius);
}
#[test]
fn metallic_thermal_conductivity() {
let m = metallic::MetallicAsteroid::new(10000.0, 0.85);
let k = m.thermal_conductivity_estimate();
assert!(k > 0.0);
}
#[test]
fn pha_basic() {
let p = pha::PotentiallyHazardousAsteroid::new(100.0, 3000.0, 1.2, 0.5, 0.03);
assert!(p.mass > 0.0);
assert!(p.surface_gravity() > 0.0);
}
#[test]
fn pha_classification() {
let is_pha =
pha::PotentiallyHazardousAsteroid::new(100.0, 3000.0, 1.5, 0.5, 0.03).with_albedo(0.15);
assert!(is_pha.is_pha());
let not_pha =
pha::PotentiallyHazardousAsteroid::new(1.0, 3000.0, 3.0, 0.1, 0.1).with_albedo(0.15);
assert!(!not_pha.is_pha());
}
#[test]
fn pha_impact_energy() {
let p = pha::PotentiallyHazardousAsteroid::new(500.0, 3000.0, 1.2, 0.4, 0.02);
let j = p.impact_energy_joules();
let mt = p.impact_energy_megatons();
assert!(j > 0.0);
assert!(mt > 0.0);
}
#[test]
fn pha_torino_scale() {
let p = pha::PotentiallyHazardousAsteroid::new(5000.0, 3000.0, 1.1, 0.5, 0.01);
let scale = p.torino_scale_estimate();
assert!(scale <= 10);
}
#[test]
fn pha_crater_diameter() {
let p = pha::PotentiallyHazardousAsteroid::new(500.0, 3000.0, 1.2, 0.5, 0.02);
let crater = p.crater_diameter_estimate();
assert!(crater > 0.0);
}
#[test]
fn pha_deflection() {
let p = pha::PotentiallyHazardousAsteroid::new(200.0, 3000.0, 1.3, 0.4, 0.03);
let dv = p.deflection_delta_v(10.0);
assert!(dv > 0.0);
}
#[test]
fn generated_asteroid_enum() {
let nea = near_earth::NearEarthAsteroid::new(100.0, 2500.0, 1.5, 0.4);
let generated = GeneratedAsteroid::NearEarth(nea);
match generated {
GeneratedAsteroid::NearEarth(_) => {}
_ => panic!("wrong variant"),
}
}
#[test]
fn generated_asteroid_all_variants() {
let variants = vec![
GeneratedAsteroid::NearEarth(near_earth::NearEarthAsteroid::new(100.0, 2500.0, 1.5, 0.4)),
GeneratedAsteroid::MainBelt(main_belt::MainBeltAsteroid::new(5000.0, 2700.0, 2.7)),
GeneratedAsteroid::Trojan(trojan::Trojan::new(10000.0, 2000.0, 5.2)),
GeneratedAsteroid::Centaur(centaur::Centaur::new(30000.0, 1500.0, 13.0, 0.3)),
GeneratedAsteroid::Binary(binary::BinaryAsteroid::new(5000.0, 2000.0, 2000.0, 30000.0)),
GeneratedAsteroid::RubblePile(rubble_pile::RubblePile::new(500.0, 3000.0, 0.4)),
GeneratedAsteroid::Metallic(metallic::MetallicAsteroid::new(50000.0, 0.85)),
GeneratedAsteroid::PHA(pha::PotentiallyHazardousAsteroid::new(
100.0, 3000.0, 1.2, 0.5, 0.03,
)),
];
assert_eq!(variants.len(), 8);
let mut count = 0;
for v in &variants {
match v {
GeneratedAsteroid::NearEarth(_) => count += 1,
GeneratedAsteroid::MainBelt(_) => count += 1,
GeneratedAsteroid::Trojan(_) => count += 1,
GeneratedAsteroid::Centaur(_) => count += 1,
GeneratedAsteroid::Binary(_) => count += 1,
GeneratedAsteroid::RubblePile(_) => count += 1,
GeneratedAsteroid::Metallic(_) => count += 1,
GeneratedAsteroid::PHA(_) => count += 1,
}
}
assert_eq!(count, 8);
}