foundation: move apsis-units tests into tests directory
This commit is contained in:
parent
d1666ac28a
commit
1adbbe3b64
|
|
@ -129,65 +129,3 @@ impl fmt::Display for Degrees {
|
|||
|
||||
impl_quantity_ops!(Radians);
|
||||
impl_quantity_ops!(Degrees);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Degrees, Radians};
|
||||
use crate::dimension::Angle;
|
||||
use apsis_core::{Quantity, Unit};
|
||||
use core::f64::consts::PI;
|
||||
|
||||
#[test]
|
||||
fn direct_conversions_are_consistent() {
|
||||
assert!((Degrees::new(180.0).to_radians().value() - PI).abs() < 1e-12);
|
||||
assert!((Radians::new(PI).to_degrees().value() - 180.0).abs() < 1e-12);
|
||||
assert!((Degrees::new(90.0).to_radians().value() - PI / 2.0).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generic_conversion_matches_direct_conversion() {
|
||||
let angle = Degrees::new(45.0);
|
||||
let via_trait: Radians = angle.to_unit();
|
||||
assert!((via_trait.value() - angle.to_radians().value()).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conversion_round_trips() {
|
||||
let original = Degrees::new(137.5);
|
||||
let round_tripped: Degrees = original.to_unit::<Radians>().to_unit();
|
||||
assert!((round_tripped.value() - original.value()).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wrap_places_angles_in_the_canonical_range() {
|
||||
for turns in -3..=3 {
|
||||
let angle = Radians::new(PI + f64::from(turns) * 2.0 * PI);
|
||||
let wrapped = angle.wrap();
|
||||
assert!(wrapped.value() >= -PI);
|
||||
assert!(wrapped.value() < PI);
|
||||
// Wrapping shifts by whole turns, so the angle is preserved
|
||||
// modulo two pi.
|
||||
let difference = angle.value() - wrapped.value();
|
||||
assert!((difference / (2.0 * PI)).fract().abs() < 1e-12);
|
||||
}
|
||||
assert!((Radians::new(0.0).wrap().value()).abs() < 1e-12);
|
||||
assert!((Radians::new(PI).wrap().value() + PI).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_metadata_is_available() {
|
||||
assert_eq!(Radians::symbol(), "rad");
|
||||
assert_eq!(Degrees::symbol(), "deg");
|
||||
assert_eq!(Radians::factor_to_base(), 1.0);
|
||||
assert!((Degrees::factor_to_base() - PI / 180.0).abs() < 1e-15);
|
||||
fn assert_angle<U: Unit<Dimension = Angle>>() {}
|
||||
assert_angle::<Radians>();
|
||||
assert_angle::<Degrees>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_includes_the_symbol() {
|
||||
assert_eq!(Radians::new(1.0).to_string(), "1 rad");
|
||||
assert_eq!(Degrees::new(90.0).to_string(), "90 deg");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,34 +63,3 @@ impl fmt::Display for Hertz {
|
|||
}
|
||||
|
||||
impl_quantity_ops!(Hertz);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Hertz;
|
||||
use crate::dimension::Frequency;
|
||||
use apsis_core::Unit;
|
||||
|
||||
#[test]
|
||||
fn stores_the_given_value() {
|
||||
assert_eq!(Hertz::new(1_575.42).value(), 1_575.42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn period_is_the_reciprocal() {
|
||||
assert!((Hertz::new(2.0).period() - 0.5).abs() < 1e-12);
|
||||
assert!(Hertz::new(0.0).period().is_infinite());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_metadata_is_available() {
|
||||
assert_eq!(Hertz::symbol(), "Hz");
|
||||
assert_eq!(Hertz::factor_to_base(), 1.0);
|
||||
fn assert_frequency<U: Unit<Dimension = Frequency>>() {}
|
||||
assert_frequency::<Hertz>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_includes_the_symbol() {
|
||||
assert_eq!(Hertz::new(1_000.0).to_string(), "1000 Hz");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,72 +113,3 @@ impl fmt::Display for Kilometers {
|
|||
|
||||
impl_quantity_ops!(Meters);
|
||||
impl_quantity_ops!(Kilometers);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Kilometers, Meters};
|
||||
use crate::dimension::Length;
|
||||
use apsis_core::{Quantity, Unit};
|
||||
|
||||
#[test]
|
||||
fn stores_the_given_value() {
|
||||
assert_eq!(Meters::new(12.5).value(), 12.5);
|
||||
assert_eq!(Kilometers::new(-3.0).value(), -3.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn direct_conversions_are_consistent() {
|
||||
assert_eq!(Meters::new(2_500.0).to_kilometers().value(), 2.5);
|
||||
assert_eq!(Kilometers::new(2.5).to_meters().value(), 2_500.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generic_conversion_matches_direct_conversion() {
|
||||
let distance = Meters::new(2_500.0);
|
||||
let via_trait: Kilometers = distance.to_unit();
|
||||
assert_eq!(via_trait, distance.to_kilometers());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conversion_round_trips() {
|
||||
let original = Kilometers::new(42.195);
|
||||
let round_tripped: Kilometers = original.to_unit::<Meters>().to_unit();
|
||||
assert!((round_tripped.value() - original.value()).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn units_report_their_metadata() {
|
||||
assert_eq!(Meters::symbol(), "m");
|
||||
assert_eq!(Kilometers::symbol(), "km");
|
||||
assert_eq!(Meters::factor_to_base(), 1.0);
|
||||
assert_eq!(Kilometers::factor_to_base(), 1_000.0);
|
||||
// Both units measure the same dimension, which is what makes the
|
||||
// generic conversion above type check.
|
||||
fn assert_length<U: Unit<Dimension = Length>>() {}
|
||||
assert_length::<Meters>();
|
||||
assert_length::<Kilometers>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arithmetic_operates_on_the_stored_value() {
|
||||
let sum = Meters::new(1.5) + Meters::new(2.5);
|
||||
assert_eq!(sum.value(), 4.0);
|
||||
let difference = Meters::new(4.0) - Meters::new(1.0);
|
||||
assert_eq!(difference.value(), 3.0);
|
||||
let scaled = Meters::new(3.0) * 2.0;
|
||||
assert_eq!(scaled.value(), 6.0);
|
||||
let straddled = 2.0 * Meters::new(3.0);
|
||||
assert_eq!(straddled.value(), 6.0);
|
||||
let halved = Meters::new(3.0) / 2.0;
|
||||
assert_eq!(halved.value(), 1.5);
|
||||
let ratio = Meters::new(3.0) / Meters::new(1.5);
|
||||
assert_eq!(ratio, 2.0);
|
||||
assert_eq!((-Meters::new(1.0)).value(), -1.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_includes_the_symbol() {
|
||||
assert_eq!(Meters::new(1.0).to_string(), "1 m");
|
||||
assert_eq!(Kilometers::new(2.0).to_string(), "2 km");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,46 +77,3 @@ impl fmt::Display for Kelvin {
|
|||
}
|
||||
|
||||
impl_quantity_ops!(Kelvin);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Kelvin;
|
||||
use crate::dimension::Temperature;
|
||||
use apsis_core::Unit;
|
||||
use apsis_core::constant::ZERO_CELSIUS_IN_KELVIN;
|
||||
|
||||
#[test]
|
||||
fn stores_the_given_value() {
|
||||
assert_eq!(Kelvin::new(290.0).value(), 290.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn celsius_conversion_uses_the_exact_offset() {
|
||||
let freezing = Kelvin::from_celsius(0.0);
|
||||
assert_eq!(freezing.value(), ZERO_CELSIUS_IN_KELVIN);
|
||||
assert_eq!(freezing.to_celsius(), 0.0);
|
||||
let boiling = Kelvin::from_celsius(100.0);
|
||||
assert!((boiling.to_celsius() - 100.0).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn celsius_conversion_round_trips() {
|
||||
let original = Kelvin::new(273.15 + 21.5);
|
||||
assert!(
|
||||
(Kelvin::from_celsius(original.to_celsius()).value() - original.value()).abs() < 1e-12
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_metadata_is_available() {
|
||||
assert_eq!(Kelvin::symbol(), "K");
|
||||
assert_eq!(Kelvin::factor_to_base(), 1.0);
|
||||
fn assert_temperature<U: Unit<Dimension = Temperature>>() {}
|
||||
assert_temperature::<Kelvin>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_includes_the_symbol() {
|
||||
assert_eq!(Kelvin::new(300.0).to_string(), "300 K");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,37 +55,3 @@ impl fmt::Display for Seconds {
|
|||
}
|
||||
|
||||
impl_quantity_ops!(Seconds);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Seconds;
|
||||
use crate::dimension::Time;
|
||||
use apsis_core::Unit;
|
||||
|
||||
#[test]
|
||||
fn stores_the_given_value() {
|
||||
assert_eq!(Seconds::new(0.5).value(), 0.5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_metadata_is_available() {
|
||||
assert_eq!(Seconds::symbol(), "s");
|
||||
assert_eq!(Seconds::factor_to_base(), 1.0);
|
||||
fn assert_time<U: Unit<Dimension = Time>>() {}
|
||||
assert_time::<Seconds>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arithmetic_operates_on_the_stored_value() {
|
||||
assert_eq!((Seconds::new(1.0) + Seconds::new(2.0)).value(), 3.0);
|
||||
assert_eq!((Seconds::new(3.0) - Seconds::new(2.0)).value(), 1.0);
|
||||
assert_eq!((Seconds::new(3.0) * 2.0).value(), 6.0);
|
||||
assert_eq!((Seconds::new(3.0) / 3.0).value(), 1.0);
|
||||
assert_eq!(Seconds::new(6.0) / Seconds::new(3.0), 2.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_includes_the_symbol() {
|
||||
assert_eq!(Seconds::new(1.5).to_string(), "1.5 s");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
//! Tests for plane angle quantities.
|
||||
|
||||
use apsis_core::{Quantity, Unit};
|
||||
use apsis_units::dimension::Angle;
|
||||
use apsis_units::{Degrees, Radians};
|
||||
use core::f64::consts::PI;
|
||||
|
||||
#[test]
|
||||
fn direct_conversions_are_consistent() {
|
||||
assert!((Degrees::new(180.0).to_radians().value() - PI).abs() < 1e-12);
|
||||
assert!((Radians::new(PI).to_degrees().value() - 180.0).abs() < 1e-12);
|
||||
assert!((Degrees::new(90.0).to_radians().value() - PI / 2.0).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generic_conversion_matches_direct_conversion() {
|
||||
let angle = Degrees::new(45.0);
|
||||
let via_trait: Radians = angle.to_unit();
|
||||
assert!((via_trait.value() - angle.to_radians().value()).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conversion_round_trips() {
|
||||
let original = Degrees::new(137.5);
|
||||
let round_tripped: Degrees = original.to_unit::<Radians>().to_unit();
|
||||
assert!((round_tripped.value() - original.value()).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wrap_places_angles_in_the_canonical_range() {
|
||||
for turns in -3..=3 {
|
||||
let angle = Radians::new(PI + f64::from(turns) * 2.0 * PI);
|
||||
let wrapped = angle.wrap();
|
||||
assert!(wrapped.value() >= -PI);
|
||||
assert!(wrapped.value() < PI);
|
||||
// Wrapping shifts by whole turns, so the angle is preserved
|
||||
// modulo two pi.
|
||||
let difference = angle.value() - wrapped.value();
|
||||
assert!((difference / (2.0 * PI)).fract().abs() < 1e-12);
|
||||
}
|
||||
assert!((Radians::new(0.0).wrap().value()).abs() < 1e-12);
|
||||
assert!((Radians::new(PI).wrap().value() + PI).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_metadata_is_available() {
|
||||
assert_eq!(Radians::symbol(), "rad");
|
||||
assert_eq!(Degrees::symbol(), "deg");
|
||||
assert_eq!(Radians::factor_to_base(), 1.0);
|
||||
assert!((Degrees::factor_to_base() - PI / 180.0).abs() < 1e-15);
|
||||
fn assert_angle<U: Unit<Dimension = Angle>>() {}
|
||||
assert_angle::<Radians>();
|
||||
assert_angle::<Degrees>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_includes_the_symbol() {
|
||||
assert_eq!(Radians::new(1.0).to_string(), "1 rad");
|
||||
assert_eq!(Degrees::new(90.0).to_string(), "90 deg");
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
//! Tests for frequency quantities.
|
||||
|
||||
use apsis_core::Unit;
|
||||
use apsis_units::Hertz;
|
||||
use apsis_units::dimension::Frequency;
|
||||
|
||||
#[test]
|
||||
fn stores_the_given_value() {
|
||||
assert_eq!(Hertz::new(1_575.42).value(), 1_575.42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn period_is_the_reciprocal() {
|
||||
assert!((Hertz::new(2.0).period() - 0.5).abs() < 1e-12);
|
||||
assert!(Hertz::new(0.0).period().is_infinite());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_metadata_is_available() {
|
||||
assert_eq!(Hertz::symbol(), "Hz");
|
||||
assert_eq!(Hertz::factor_to_base(), 1.0);
|
||||
fn assert_frequency<U: Unit<Dimension = Frequency>>() {}
|
||||
assert_frequency::<Hertz>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_includes_the_symbol() {
|
||||
assert_eq!(Hertz::new(1_000.0).to_string(), "1000 Hz");
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
//! Tests for length quantities.
|
||||
|
||||
use apsis_core::{Quantity, Unit};
|
||||
use apsis_units::dimension::Length;
|
||||
use apsis_units::{Kilometers, Meters};
|
||||
|
||||
#[test]
|
||||
fn stores_the_given_value() {
|
||||
assert_eq!(Meters::new(12.5).value(), 12.5);
|
||||
assert_eq!(Kilometers::new(-3.0).value(), -3.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn direct_conversions_are_consistent() {
|
||||
assert_eq!(Meters::new(2_500.0).to_kilometers().value(), 2.5);
|
||||
assert_eq!(Kilometers::new(2.5).to_meters().value(), 2_500.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generic_conversion_matches_direct_conversion() {
|
||||
let distance = Meters::new(2_500.0);
|
||||
let via_trait: Kilometers = distance.to_unit();
|
||||
assert_eq!(via_trait, distance.to_kilometers());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conversion_round_trips() {
|
||||
let original = Kilometers::new(42.195);
|
||||
let round_tripped: Kilometers = original.to_unit::<Meters>().to_unit();
|
||||
assert!((round_tripped.value() - original.value()).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn units_report_their_metadata() {
|
||||
assert_eq!(Meters::symbol(), "m");
|
||||
assert_eq!(Kilometers::symbol(), "km");
|
||||
assert_eq!(Meters::factor_to_base(), 1.0);
|
||||
assert_eq!(Kilometers::factor_to_base(), 1_000.0);
|
||||
// Both units measure the same dimension, which is what makes the
|
||||
// generic conversion above type check.
|
||||
fn assert_length<U: Unit<Dimension = Length>>() {}
|
||||
assert_length::<Meters>();
|
||||
assert_length::<Kilometers>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arithmetic_operates_on_the_stored_value() {
|
||||
let sum = Meters::new(1.5) + Meters::new(2.5);
|
||||
assert_eq!(sum.value(), 4.0);
|
||||
let difference = Meters::new(4.0) - Meters::new(1.0);
|
||||
assert_eq!(difference.value(), 3.0);
|
||||
let scaled = Meters::new(3.0) * 2.0;
|
||||
assert_eq!(scaled.value(), 6.0);
|
||||
let straddled = 2.0 * Meters::new(3.0);
|
||||
assert_eq!(straddled.value(), 6.0);
|
||||
let halved = Meters::new(3.0) / 2.0;
|
||||
assert_eq!(halved.value(), 1.5);
|
||||
let ratio = Meters::new(3.0) / Meters::new(1.5);
|
||||
assert_eq!(ratio, 2.0);
|
||||
assert_eq!((-Meters::new(1.0)).value(), -1.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_includes_the_symbol() {
|
||||
assert_eq!(Meters::new(1.0).to_string(), "1 m");
|
||||
assert_eq!(Kilometers::new(2.0).to_string(), "2 km");
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
//! Tests for thermodynamic temperature quantities.
|
||||
|
||||
use apsis_core::Unit;
|
||||
use apsis_core::constant::ZERO_CELSIUS_IN_KELVIN;
|
||||
use apsis_units::Kelvin;
|
||||
use apsis_units::dimension::Temperature;
|
||||
|
||||
#[test]
|
||||
fn stores_the_given_value() {
|
||||
assert_eq!(Kelvin::new(290.0).value(), 290.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn celsius_conversion_uses_the_exact_offset() {
|
||||
let freezing = Kelvin::from_celsius(0.0);
|
||||
assert_eq!(freezing.value(), ZERO_CELSIUS_IN_KELVIN);
|
||||
assert_eq!(freezing.to_celsius(), 0.0);
|
||||
let boiling = Kelvin::from_celsius(100.0);
|
||||
assert!((boiling.to_celsius() - 100.0).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn celsius_conversion_round_trips() {
|
||||
let original = Kelvin::new(273.15 + 21.5);
|
||||
assert!((Kelvin::from_celsius(original.to_celsius()).value() - original.value()).abs() < 1e-12);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_metadata_is_available() {
|
||||
assert_eq!(Kelvin::symbol(), "K");
|
||||
assert_eq!(Kelvin::factor_to_base(), 1.0);
|
||||
fn assert_temperature<U: Unit<Dimension = Temperature>>() {}
|
||||
assert_temperature::<Kelvin>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_includes_the_symbol() {
|
||||
assert_eq!(Kelvin::new(300.0).to_string(), "300 K");
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
//! Tests for the duration quantity.
|
||||
|
||||
use apsis_core::Unit;
|
||||
use apsis_units::Seconds;
|
||||
use apsis_units::dimension::Time;
|
||||
|
||||
#[test]
|
||||
fn stores_the_given_value() {
|
||||
assert_eq!(Seconds::new(0.5).value(), 0.5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_metadata_is_available() {
|
||||
assert_eq!(Seconds::symbol(), "s");
|
||||
assert_eq!(Seconds::factor_to_base(), 1.0);
|
||||
fn assert_time<U: Unit<Dimension = Time>>() {}
|
||||
assert_time::<Seconds>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arithmetic_operates_on_the_stored_value() {
|
||||
assert_eq!((Seconds::new(1.0) + Seconds::new(2.0)).value(), 3.0);
|
||||
assert_eq!((Seconds::new(3.0) - Seconds::new(2.0)).value(), 1.0);
|
||||
assert_eq!((Seconds::new(3.0) * 2.0).value(), 6.0);
|
||||
assert_eq!((Seconds::new(3.0) / 3.0).value(), 1.0);
|
||||
assert_eq!(Seconds::new(6.0) / Seconds::new(3.0), 2.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_includes_the_symbol() {
|
||||
assert_eq!(Seconds::new(1.5).to_string(), "1.5 s");
|
||||
}
|
||||
Loading…
Reference in New Issue