foundation: move apsis-core tests into tests directory

This commit is contained in:
ApsisRS contributors 2026-09-26 13:01:58 +08:00
parent 42d2e34bea
commit d1666ac28a
6 changed files with 217 additions and 223 deletions

View File

@ -134,44 +134,3 @@ pub const STANDARD_ATMOSPHERE: f64 = 101_325.0;
/// ///
/// Exact by definition of the Celsius scale. /// Exact by definition of the Celsius scale.
pub const ZERO_CELSIUS_IN_KELVIN: f64 = 273.15; pub const ZERO_CELSIUS_IN_KELVIN: f64 = 273.15;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn defining_constants_are_exact() {
assert_eq!(SPEED_OF_LIGHT, 299_792_458.0);
assert_eq!(BOLTZMANN, 1.380_649e-23);
assert_eq!(PLANCK, 6.626_070_15e-34);
assert_eq!(ELEMENTARY_CHARGE, 1.602_176_634e-19);
assert_eq!(ASTRONOMICAL_UNIT, 149_597_870_700.0);
assert_eq!(STANDARD_GRAVITY, 9.806_65);
}
#[test]
fn time_constants_are_consistent() {
assert_eq!(HOUR, MINUTE * 60.0);
assert_eq!(DAY, HOUR * 24.0);
assert_eq!(JULIAN_YEAR, DAY * 365.25);
assert_eq!(JULIAN_CENTURY, JULIAN_YEAR * 100.0);
}
#[test]
fn j2000_minus_unix_epoch_is_the_expected_span() {
// The two epochs are 10 957 days apart.
assert_eq!(JULIAN_DATE_J2000 - JULIAN_DATE_UNIX_EPOCH, 10_957.5);
assert_eq!(SECONDS_J2000_TO_UNIX, 10_957.5 * DAY);
assert_eq!(SECONDS_J2000_TO_UNIX, 946_728_000.0);
}
#[test]
fn earth_flattening_matches_the_inverse_value() {
assert!((1.0 / EARTH_FLATTENING - 298.257_223_563).abs() < 1e-9);
}
#[test]
fn celsius_offset_is_exact() {
assert_eq!(ZERO_CELSIUS_IN_KELVIN, 273.15);
}
}

View File

@ -168,78 +168,3 @@ impl From<ErrorKind> for Error {
/// A [`Result`](core::result::Result) whose error type is [`Error`]. /// A [`Result`](core::result::Result) whose error type is [`Error`].
pub type Result<T> = core::result::Result<T, Error>; pub type Result<T> = core::result::Result<T, Error>;
#[cfg(test)]
mod tests {
use super::{Error, ErrorKind, Result};
use core::fmt;
#[derive(Debug)]
struct Underlying;
impl fmt::Display for Underlying {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("underlying failure")
}
}
impl core::error::Error for Underlying {}
#[test]
fn kind_is_reported() {
let error = Error::new(ErrorKind::Parse);
assert_eq!(error.kind(), ErrorKind::Parse);
assert_eq!(error.message(), None);
}
#[test]
fn message_is_reported() {
let error = Error::with_message(ErrorKind::OutOfRange, "semi-major axis is negative");
assert_eq!(error.kind(), ErrorKind::OutOfRange);
assert_eq!(error.message(), Some("semi-major axis is negative"));
}
#[test]
fn display_includes_kind_and_message() {
let error = Error::with_message(ErrorKind::Parse, "bad checksum");
assert_eq!(error.to_string(), "parse error: bad checksum");
assert_eq!(Error::new(ErrorKind::NotFound).to_string(), "not found");
}
#[test]
fn source_is_exposed() {
let error = Error::with_source(ErrorKind::Other, Underlying);
assert!(std::error::Error::source(&error).is_some());
assert_eq!(error.kind(), ErrorKind::Other);
}
#[test]
fn context_and_cause_replace_previous_values() {
let error = Error::new(ErrorKind::Other)
.with_context("first")
.with_context("second")
.caused_by(Underlying);
assert_eq!(error.message(), Some("second"));
assert!(std::error::Error::source(&error).is_some());
}
#[test]
fn converts_from_kind() {
let error: Error = ErrorKind::Unsupported.into();
assert_eq!(error.kind(), ErrorKind::Unsupported);
}
#[test]
fn works_in_result_position() {
fn fail() -> Result<u32> {
Err(Error::new(ErrorKind::NotFinite))
}
let outcome = fail();
assert!(outcome.is_err());
assert_eq!(
outcome.err().map(|error| error.kind()),
Some(ErrorKind::NotFinite)
);
}
}

View File

@ -61,110 +61,3 @@ pub trait Quantity: Copy {
U::from_value(base / <U as Quantity>::U::factor_to_base()) U::from_value(base / <U as Quantity>::U::factor_to_base())
} }
} }
#[cfg(test)]
mod tests {
use super::{Quantity, Unit};
use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq)]
struct Length;
#[derive(Debug, Clone, Copy)]
struct Meter;
#[derive(Debug, Clone, Copy)]
struct Kilometer;
impl fmt::Display for Meter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("m")
}
}
impl fmt::Display for Kilometer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("km")
}
}
impl Unit for Meter {
type Dimension = Length;
fn factor_to_base() -> f64 {
1.0
}
fn symbol() -> &'static str {
"m"
}
}
impl Unit for Kilometer {
type Dimension = Length;
fn factor_to_base() -> f64 {
1_000.0
}
fn symbol() -> &'static str {
"km"
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
struct Meters(f64);
#[derive(Debug, Clone, Copy, PartialEq)]
struct Kilometers(f64);
impl Quantity for Meters {
type U = Meter;
fn value(self) -> f64 {
self.0
}
fn from_value(value: f64) -> Self {
Self(value)
}
}
impl Quantity for Kilometers {
type U = Kilometer;
fn value(self) -> f64 {
self.0
}
fn from_value(value: f64) -> Self {
Self(value)
}
}
#[test]
fn value_round_trips() {
let distance = Meters::from_value(1_500.0);
assert_eq!(distance.value(), 1_500.0);
}
#[test]
fn converts_between_units_of_one_dimension() {
let distance = Meters::from_value(2_500.0);
let in_kilometers: Kilometers = distance.to_unit();
assert!((in_kilometers.value() - 2.5).abs() < 1e-12);
}
#[test]
fn conversion_round_trips() {
let original = Kilometers::from_value(7.25);
let round_tripped: Kilometers = original.to_unit::<Meters>().to_unit();
assert!((round_tripped.value() - 7.25).abs() < 1e-12);
}
#[test]
fn unit_metadata_is_available() {
assert_eq!(<Meter as Unit>::symbol(), "m");
assert_eq!(<Kilometer as Unit>::factor_to_base(), 1_000.0);
}
}

View File

@ -0,0 +1,39 @@
//! Tests for the physical and astronomical constants.
use apsis_core::constant::*;
#[test]
fn defining_constants_are_exact() {
assert_eq!(SPEED_OF_LIGHT, 299_792_458.0);
assert_eq!(BOLTZMANN, 1.380_649e-23);
assert_eq!(PLANCK, 6.626_070_15e-34);
assert_eq!(ELEMENTARY_CHARGE, 1.602_176_634e-19);
assert_eq!(ASTRONOMICAL_UNIT, 149_597_870_700.0);
assert_eq!(STANDARD_GRAVITY, 9.806_65);
}
#[test]
fn time_constants_are_consistent() {
assert_eq!(HOUR, MINUTE * 60.0);
assert_eq!(DAY, HOUR * 24.0);
assert_eq!(JULIAN_YEAR, DAY * 365.25);
assert_eq!(JULIAN_CENTURY, JULIAN_YEAR * 100.0);
}
#[test]
fn j2000_minus_unix_epoch_is_the_expected_span() {
// The two epochs are 10 957 days apart.
assert_eq!(JULIAN_DATE_J2000 - JULIAN_DATE_UNIX_EPOCH, 10_957.5);
assert_eq!(SECONDS_J2000_TO_UNIX, 10_957.5 * DAY);
assert_eq!(SECONDS_J2000_TO_UNIX, 946_728_000.0);
}
#[test]
fn earth_flattening_matches_the_inverse_value() {
assert!((1.0 / EARTH_FLATTENING - 298.257_223_563).abs() < 1e-9);
}
#[test]
fn celsius_offset_is_exact() {
assert_eq!(ZERO_CELSIUS_IN_KELVIN, 273.15);
}

View File

@ -0,0 +1,73 @@
//! Tests for the workspace error type and result alias.
use apsis_core::{Error, ErrorKind, Result};
use core::fmt;
#[derive(Debug)]
struct Underlying;
impl fmt::Display for Underlying {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("underlying failure")
}
}
impl core::error::Error for Underlying {}
#[test]
fn kind_is_reported() {
let error = Error::new(ErrorKind::Parse);
assert_eq!(error.kind(), ErrorKind::Parse);
assert_eq!(error.message(), None);
}
#[test]
fn message_is_reported() {
let error = Error::with_message(ErrorKind::OutOfRange, "semi-major axis is negative");
assert_eq!(error.kind(), ErrorKind::OutOfRange);
assert_eq!(error.message(), Some("semi-major axis is negative"));
}
#[test]
fn display_includes_kind_and_message() {
let error = Error::with_message(ErrorKind::Parse, "bad checksum");
assert_eq!(error.to_string(), "parse error: bad checksum");
assert_eq!(Error::new(ErrorKind::NotFound).to_string(), "not found");
}
#[test]
fn source_is_exposed() {
let error = Error::with_source(ErrorKind::Other, Underlying);
assert!(std::error::Error::source(&error).is_some());
assert_eq!(error.kind(), ErrorKind::Other);
}
#[test]
fn context_and_cause_replace_previous_values() {
let error = Error::new(ErrorKind::Other)
.with_context("first")
.with_context("second")
.caused_by(Underlying);
assert_eq!(error.message(), Some("second"));
assert!(std::error::Error::source(&error).is_some());
}
#[test]
fn converts_from_kind() {
let error: Error = ErrorKind::Unsupported.into();
assert_eq!(error.kind(), ErrorKind::Unsupported);
}
#[test]
fn works_in_result_position() {
fn fail() -> Result<u32> {
Err(Error::new(ErrorKind::NotFinite))
}
let outcome = fail();
assert!(outcome.is_err());
assert_eq!(
outcome.err().map(|error| error.kind()),
Some(ErrorKind::NotFinite)
);
}

View File

@ -0,0 +1,105 @@
//! Tests for the unit and quantity marker traits.
use apsis_core::{Quantity, Unit};
use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq)]
struct Length;
#[derive(Debug, Clone, Copy)]
struct Meter;
#[derive(Debug, Clone, Copy)]
struct Kilometer;
impl fmt::Display for Meter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("m")
}
}
impl fmt::Display for Kilometer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("km")
}
}
impl Unit for Meter {
type Dimension = Length;
fn factor_to_base() -> f64 {
1.0
}
fn symbol() -> &'static str {
"m"
}
}
impl Unit for Kilometer {
type Dimension = Length;
fn factor_to_base() -> f64 {
1_000.0
}
fn symbol() -> &'static str {
"km"
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
struct Meters(f64);
#[derive(Debug, Clone, Copy, PartialEq)]
struct Kilometers(f64);
impl Quantity for Meters {
type U = Meter;
fn value(self) -> f64 {
self.0
}
fn from_value(value: f64) -> Self {
Self(value)
}
}
impl Quantity for Kilometers {
type U = Kilometer;
fn value(self) -> f64 {
self.0
}
fn from_value(value: f64) -> Self {
Self(value)
}
}
#[test]
fn value_round_trips() {
let distance = Meters::from_value(1_500.0);
assert_eq!(distance.value(), 1_500.0);
}
#[test]
fn converts_between_units_of_one_dimension() {
let distance = Meters::from_value(2_500.0);
let in_kilometers: Kilometers = distance.to_unit();
assert!((in_kilometers.value() - 2.5).abs() < 1e-12);
}
#[test]
fn conversion_round_trips() {
let original = Kilometers::from_value(7.25);
let round_tripped: Kilometers = original.to_unit::<Meters>().to_unit();
assert!((round_tripped.value() - 7.25).abs() < 1e-12);
}
#[test]
fn unit_metadata_is_available() {
assert_eq!(<Meter as Unit>::symbol(), "m");
assert_eq!(<Kilometer as Unit>::factor_to_base(), 1_000.0);
}