apsis-rs/crates/physics/apsis-leap/tests/table.rs

81 lines
2.7 KiB
Rust

//! Tests for the leap second table.
use apsis_leap::{
LEAP_SECONDS, TABLE_COVERS_FROM_MJD, TAI_MINUS_UTC_AFTER_LAST_ENTRY, mjd_from_ymd,
};
#[test]
fn table_is_ordered_and_monotonic() {
let mut previous = f64::NEG_INFINITY;
for entry in LEAP_SECONDS {
assert!(
(1..=12).contains(&entry.month),
"month out of range: {entry:?}"
);
assert!((1..=31).contains(&entry.day), "day out of range: {entry:?}");
let mjd = entry.effective_mjd();
assert!(mjd > previous, "table is not ordered at {entry:?}");
previous = mjd;
}
}
#[test]
fn every_entry_increases_the_offset_by_one_second() {
// The table starts at the inherited offset of ten seconds and every
// later announcement inserted exactly one second.
assert_eq!(LEAP_SECONDS[0].tai_minus_utc, 10.0);
for pair in LEAP_SECONDS.windows(2) {
let (earlier, later) = (pair[0], pair[1]);
assert!(
(later.tai_minus_utc - earlier.tai_minus_utc - 1.0).abs() < f64::EPSILON,
"offset step is not one second between {earlier:?} and {later:?}"
);
}
}
#[test]
fn table_extremes_match_the_announced_values() {
assert_eq!(LEAP_SECONDS[0].effective_mjd(), 41_317.0);
let last = LEAP_SECONDS[LEAP_SECONDS.len() - 1];
assert_eq!(last.year, 2017);
assert_eq!(last.month, 1);
assert_eq!(last.day, 1);
assert_eq!(last.tai_minus_utc, 37.0);
assert_eq!(last.effective_mjd(), 57_754.0);
}
#[test]
fn table_contains_every_announcement_since_1972() {
// Twenty seven leap seconds were introduced between 1972 and 2017
// inclusive of the initial 1972-01-01 entry.
assert_eq!(LEAP_SECONDS.len(), 28);
}
#[test]
fn coverage_constants_match_the_table_boundaries() {
assert_eq!(TABLE_COVERS_FROM_MJD, LEAP_SECONDS[0].effective_mjd());
assert_eq!(TAI_MINUS_UTC_AFTER_LAST_ENTRY, 37.0);
}
#[test]
fn known_calendar_dates_map_to_known_modified_julian_dates() {
// MJD 0 is the start of 1858-11-17.
assert_eq!(mjd_from_ymd(1858, 11, 17), 0.0);
// The calendar day of J2000.0 is MJD 51544.
assert_eq!(mjd_from_ymd(2000, 1, 1), 51_544.0);
// The Unix epoch is MJD 40587.
assert_eq!(mjd_from_ymd(1970, 1, 1), 40_587.0);
// The last leap second.
assert_eq!(mjd_from_ymd(2017, 1, 1), 57_754.0);
assert_eq!(mjd_from_ymd(2024, 1, 1), 60_310.0);
}
#[test]
fn calendar_conversion_handles_leap_days_and_month_ends() {
// 2000 is a leap year, 1900 is not.
assert_eq!(mjd_from_ymd(2000, 3, 1) - mjd_from_ymd(2000, 2, 1), 29.0);
assert_eq!(mjd_from_ymd(1900, 3, 1) - mjd_from_ymd(1900, 2, 1), 28.0);
// Consecutive month ends are one day apart.
assert_eq!(mjd_from_ymd(2024, 3, 1) - mjd_from_ymd(2024, 2, 29), 1.0);
}