foundation: move apsis-core tests into tests directory
This commit is contained in:
parent
42d2e34bea
commit
d1666ac28a
|
|
@ -134,44 +134,3 @@ pub const STANDARD_ATMOSPHERE: f64 = 101_325.0;
|
|||
///
|
||||
/// Exact by definition of the Celsius scale.
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,78 +168,3 @@ impl From<ErrorKind> for Error {
|
|||
|
||||
/// A [`Result`](core::result::Result) whose error type is [`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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,110 +61,3 @@ pub trait Quantity: Copy {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in New Issue