81 lines
2.7 KiB
Rust
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);
|
|
}
|