use jupiters::temporal::calendar::{JUPITERDAYSECONDS, *};
use jupiters::temporal::epoch::*;
use jupiters::temporal::time_scale::*;
#[test]
fn calendarjupiterdayseconds() {
assert!(
(JUPITERDAYSECONDS - 35730.0).abs() < 1.0,
"Jupiter day ~35730s: {JUPITERDAYSECONDS}"
);
}
#[test]
fn calendarjupiteryearseconds() {
const { assert!(JUPITERYEARSECONDS > 3.5e8 && JUPITERYEARSECONDS < 4.0e8) };
}
#[test]
fn calendarsecondsperday() {
assert!((SECONDSPERDAY - 86400.0).abs() < 1e-6);
}
#[test]
fn epochj2000jd() {
assert!(
(J2000EPOCH - 2_451_545.0).abs() < 0.01,
"J2000 epoch JD: {J2000EPOCH}"
);
}
#[test]
fn datetimetofrromjdroundtrip() {
let dt = DateTime::new(2000, 1, 1, 12, 0, 0.0);
let jd = dt.tojuliandate();
assert!(
(jd - 2_451_545.0).abs() < 0.01,
"J2000 Julian Date should be ~2451545: {jd}"
);
}
#[test]
fn datetimefromjdroundtrip() {
let jd = 2_460_000.5;
let dt = DateTime::fromjuliandate(jd);
let jd2 = dt.tojuliandate();
assert!((jd - jd2).abs() < 1e-4, "JD roundtrip: {jd} -> {jd2}");
}
#[test]
fn datetimefromjdj2000() {
let dt = DateTime::fromjuliandate(2_451_545.0);
let jd = dt.tojuliandate();
assert!((jd - 2_451_545.0).abs() < 1e-4);
}
#[test]
fn datetimejddifferentvalues() {
let jd1 = DateTime::new(2000, 1, 1, 12, 0, 0.0).tojuliandate();
let jd2 = DateTime::new(2024, 1, 1, 12, 0, 0.0).tojuliandate();
assert!(
(jd2 - jd1).abs() > 8000.0,
"Different years should differ: {jd1} vs {jd2}"
);
}
#[test]
fn datetimemonthfield() {
let dt = DateTime::new(2000, 6, 15, 0, 0, 0.0);
assert_eq!(dt.month, 6);
assert_eq!(dt.day, 15);
}
#[test]
fn datetimehourminutesecond() {
let dt = DateTime::new(2000, 1, 1, 14, 30, 45.5);
assert_eq!(dt.hour, 14);
assert_eq!(dt.minute, 30);
assert!((dt.second - 45.5).abs() < 1e-6);
}
#[test]
fn epochj2000constructor() {
let e = Epoch::j2000();
assert!(
(e.juliandate - 2_451_545.0).abs() < 0.01,
"J2000 epoch JD: {}",
e.juliandate
);
}
#[test]
fn epochfromjd() {
let e = Epoch::fromjd(2_460_000.0);
assert!((e.juliandate - 2_460_000.0).abs() < 1e-6);
}
#[test]
fn epochfrommjd() {
let e = Epoch::frommjd(51544.5);
assert!(
(e.juliandate - 2_451_545.0).abs() < 0.01,
"MJD 51544.5 should give J2000: {}",
e.juliandate
);
}
#[test]
fn epochmjdroundtrip() {
let e = Epoch::frommjd(60000.0);
let mjd = e.tomjd();
assert!((mjd - 60000.0).abs() < 1e-6, "MJD roundtrip: {mjd}");
}
#[test]
fn epochcenturiessincej2000atzero() {
let e = Epoch::j2000();
let c = e.centuriessincej2000();
assert!(c.abs() < 0.001, "Centuries at J2000 should be 0: {c}");
}
#[test]
fn epochcenturiessincej2000at1century() {
let e = Epoch::frommjd(51544.5 + 36525.0);
let c = e.centuriessincej2000();
assert!((c - 1.0).abs() < 0.01, "Should be ~1 century: {c}");
}
#[test]
fn epochdayssincej2000() {
let e = Epoch::j2000();
let d = e.dayssincej2000();
assert!(d.abs() < 0.01, "Days at J2000 should be 0: {d}");
}
#[test]
fn epochdayssincej2000positive() {
let e = Epoch::fromjd(2_451_545.0 + 100.0);
let d = e.dayssincej2000();
assert!((d - 100.0).abs() < 0.01, "Should be 100 days: {d}");
}
#[test]
fn epochjupitergmstdegrees() {
let e = Epoch::j2000();
let gmst = e.jupitergmstdegrees();
assert!(
(gmst - 280.0).abs() < 5.0,
"Jupiter GMST at J2000 should be ~280°: {gmst}"
);
}
#[test]
fn epochjupitergmstvaries() {
let e1 = Epoch::frommjd(51544.5);
let e2 = Epoch::frommjd(51544.5 + 100.0);
let g1 = e1.jupitergmstdegrees();
let g2 = e2.jupitergmstdegrees();
assert!((g1 - g2).abs() > 0.1, "GMST should vary with time");
}
#[test]
fn epochadvancedays() {
let mut e = Epoch::j2000();
e.advancedays(10.0);
assert!((e.dayssincej2000() - 10.0).abs() < 0.01);
}
#[test]
fn epochadvanceseconds() {
let mut e = Epoch::j2000();
e.advanceseconds(86400.0);
assert!((e.dayssincej2000() - 1.0).abs() < 0.01);
}
#[test]
fn timescalerealtime() {
let ts = TimeScale::realtime();
assert!((ts.speedmultiplier - 1.0).abs() < 1e-9);
assert!(!ts.paused);
}
#[test]
fn timescalefastforward() {
let ts = TimeScale::fastforward(100.0);
assert!((ts.speedmultiplier - 100.0).abs() < 1e-9);
}
#[test]
fn timescaleslowmotion() {
let ts = TimeScale::slowmotion(0.1);
assert!(
(ts.speedmultiplier - 10.0).abs() < 1e-6,
"slowmotion(0.1) → 1/0.1=10x: {}",
ts.speedmultiplier
);
}
#[test]
fn timescalestep() {
let mut ts = TimeScale::fastforward(10.0);
ts.step(1.0);
assert!(
(ts.simulationtimes - 10.0).abs() < 1e-6,
"10x speed * 1s dt = 10s sim: {}",
ts.simulationtimes
);
assert!((ts.realtimes - 1.0).abs() < 1e-6);
}
#[test]
fn timescalestepcumulates() {
let mut ts = TimeScale::fastforward(2.0);
ts.step(5.0);
ts.step(5.0);
assert!((ts.realtimes - 10.0).abs() < 0.1);
assert!((ts.simulationtimes - 20.0).abs() < 0.1);
}
#[test]
fn timescalepauseresume() {
let mut ts = TimeScale::realtime();
ts.pause();
assert!(ts.paused);
ts.step(100.0);
assert!(
ts.simulationtimes.abs() < 1e-9,
"Paused step should give 0 sim time: {}",
ts.simulationtimes
);
ts.resume();
assert!(!ts.paused);
ts.step(1.0);
assert!(
(ts.simulationtimes - 1.0).abs() < 1e-6,
"Resumed should work: {}",
ts.simulationtimes
);
}
#[test]
fn timescaletogglepause() {
let mut ts = TimeScale::realtime();
ts.togglepause();
assert!(ts.paused);
ts.togglepause();
assert!(!ts.paused);
}
#[test]
fn timescalesetspeed() {
let mut ts = TimeScale::realtime();
ts.setspeed(50.0);
assert!((ts.speedmultiplier - 50.0).abs() < 1e-9);
}
#[test]
fn timescalesimulationdt() {
let ts = TimeScale::fastforward(10.0);
let sdt = ts.simulationdt(2.0);
assert!((sdt - 20.0).abs() < 1e-6);
}
#[test]
fn timescalesimulationdtpaused() {
let mut ts = TimeScale::fastforward(10.0);
ts.pause();
let sdt = ts.simulationdt(2.0);
assert!(sdt.abs() < 1e-9, "Paused simulationdt should be 0: {sdt}");
}
#[test]
fn timescalesimhours() {
let mut ts = TimeScale::realtime();
ts.step(3600.0);
assert!((ts.simhours() - 1.0).abs() < 0.01);
}
#[test]
fn timescalesimdays() {
let mut ts = TimeScale::realtime();
ts.step(86400.0);
assert!((ts.simdays() - 1.0).abs() < 0.01);
}
#[test]
fn timescalesimjupiterdays() {
let mut ts = TimeScale::realtime();
ts.step(35730.0);
assert!(
(ts.simjupiterdays() - 1.0).abs() < 0.01,
"Should be ~1 Jupiter day: {}",
ts.simjupiterdays()
);
}
#[test]
fn timescalesimjupiteryears() {
let mut ts = TimeScale::fastforward(1000.0);
let jyear_s = 86400.0 * 4332.59;
ts.step(jyear_s / 1000.0);
assert!(
(ts.simjupiteryears() - 1.0).abs() < 0.01,
"Should be ~1 Jupiter year: {}",
ts.simjupiteryears()
);
}
#[test]
fn timescalemultiplestepconsistency() {
let mut ts = TimeScale::fastforward(5.0);
for _ in 0..100 {
ts.step(0.1);
}
assert!((ts.realtimes - 10.0).abs() < 0.1);
assert!((ts.simulationtimes - 50.0).abs() < 0.1);
}
#[test]
fn timescaleinitialzero() {
let ts = TimeScale::realtime();
assert!(ts.simulationtimes.abs() < 1e-15);
assert!(ts.realtimes.abs() < 1e-15);
}