Skip to content

Commit

Permalink
increase code coverage (#68)
Browse files Browse the repository at this point in the history
* antex/pcv: add more tests
* channel: add more tests
* navigation/ionmessage: add more tests
* navigation/health: add more tests
* hardware/: add more tests
* antex: add coordinates conversion methods

Signed-off-by: Guillaume W. Bres <[email protected]>
  • Loading branch information
gwbres authored Dec 8, 2022
1 parent 00ccf92 commit 06e1889
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 26 deletions.
1 change: 1 addition & 0 deletions rinex/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ wkt = { version = "0.10.0", default-features = false, optional = true }
serde = { version = "1.0", optional = true, default-features = false, features = ["derive"] }
flate2 = { version = "1.0.24", optional = true, default-features = false, features = ["zlib"] }
hifitime = { version = "3.7.0", features = ["serde", "std"] }
map_3d = "0.1.4"

[dev-dependencies]
criterion = "0.4"
Expand Down
73 changes: 69 additions & 4 deletions rinex/src/antex/frequency.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Antex - special RINEX type specific structures
use crate::channel;
use crate::channel::Channel;

#[derive(Debug, Clone, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize))]
Expand Down Expand Up @@ -48,7 +48,7 @@ impl Pattern {
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct Frequency {
/// Channel, example: L1, L2 for GPS, E1, E5 for GAL...
pub channel: channel::Channel,
pub channel: Channel,
/// Northern component of the mean antenna phase center
/// relative to the antenna reference point (ARP),
/// in [mm]
Expand All @@ -70,7 +70,7 @@ pub struct Frequency {
impl Default for Frequency {
fn default() -> Self {
Self {
channel: channel::Channel::default(),
channel: Channel::default(),
north: 0.0_f64,
east: 0.0_f64,
up: 0.0_f64,
Expand All @@ -80,7 +80,53 @@ impl Default for Frequency {
}

impl Frequency {
pub fn with_channel(&self, channel: channel::Channel) -> Self {
/// Returns ARP coordinates in Geodetic system.
/// Ref. position must be given in (lat, lon, altitude) [m]
pub fn arp_geodetic(&self, ref_pos: (f64, f64, f64)) -> (f64, f64, f64) {
map_3d::enu2geodetic(
self.east * 10.0E-3,
self.north * 10.0E-3,
self.up * 10.0E-3,
ref_pos.0,
ref_pos.1,
ref_pos.2,
map_3d::Ellipsoid::WGS84,
)
}
/// Returns ARP coordinates in ECEF system.
pub fn arp_ecef(&self, ref_pos: (f64, f64, f64)) -> (f64, f64, f64) {
map_3d::enu2ecef(
self.east * 10.0E-3,
self.north * 10.0E-3,
self.up * 10.0E-3,
ref_pos.0,
ref_pos.1,
ref_pos.2,
map_3d::Ellipsoid::WGS84,
)
}
/// Returns ARP coordinates as North Earth Down coordinates
pub fn arp_ned(&self, ref_pos: (f64, f64, f64)) -> (f64, f64, f64) {
let ecef = map_3d::enu2ecef(
self.east * 10.0E-3,
self.north * 10.0E-3,
self.up * 10.0E-3,
ref_pos.0,
ref_pos.1,
ref_pos.2,
map_3d::Ellipsoid::WGS84,
);
map_3d::ecef2ned(
ecef.0,
ecef.1,
ecef.2,
ref_pos.0,
ref_pos.1,
ref_pos.2,
map_3d::Ellipsoid::WGS84,
)
}
pub fn with_channel(&self, channel: Channel) -> Self {
let mut f = self.clone();
f.channel = channel.clone();
f
Expand All @@ -106,3 +152,22 @@ impl Frequency {
f
}
}

#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_pattern() {
let default = Pattern::default();
assert_eq!(default, Pattern::NonAzimuthDependent(Vec::new()));
assert_eq!(default.is_azimuth_dependent(), false);
}
#[test]
fn test_frequency() {
let default = Frequency::default();
assert_eq!(default.channel, Channel::default());
assert_eq!(default.north, 0.0_f64);
assert_eq!(default.east, 0.0_f64);
assert_eq!(default.up, 0.0_f64);
}
}
22 changes: 22 additions & 0 deletions rinex/src/antex/pcv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,25 @@ impl Pcv {
s
}
}

#[cfg(test)]
mod test {
use super::*;
use std::str::FromStr;
#[test]
fn test_pcv() {
assert_eq!(Pcv::default(), Pcv::Absolute);
assert!(Pcv::Absolute.is_absolute());
assert_eq!(Pcv::Relative(String::from("AOAD/M_T")).is_absolute(), false);

let pcv = Pcv::from_str("A");
assert!(pcv.is_ok());
let pcv = pcv.unwrap();
assert_eq!(pcv, Pcv::Absolute);

let pcv = Pcv::from_str("R");
assert!(pcv.is_ok());
let pcv = pcv.unwrap();
assert_eq!(pcv, Pcv::Relative(String::from("AOAD/M_T")));
}
}
20 changes: 11 additions & 9 deletions rinex/src/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,16 +278,18 @@ impl Channel {
mod test {
use super::*;
use std::str::FromStr;
/*#[test]
fn test_code() {
assert_eq!(Code::from_str("C1").is_ok(), true);
assert_eq!(Code::from_str("L1").is_err(), true);
assert_eq!(Code::from_str("P1").is_ok(), true);
}*/
#[test]
fn test_channel() {
assert_eq!(Channel::from_str("L1").is_ok(), true);
assert_eq!(Channel::from_str("C1").is_err(), true);
assert_eq!(Channel::from_str("L5").is_ok(), true);
assert!(Channel::from_str("L1").is_ok());
assert!(Channel::from_str("C1").is_err());
assert!(Channel::from_str("L5").is_ok());

let l1 = Channel::from_str("L1").unwrap();
assert_eq!(l1.carrier_frequency_mhz(), 1575.42_f64);
assert_eq!(l1.carrier_wavelength(), 299792458.0 / 1575.42_f64 / 10.0E6);
let channel = Channel::from_observable(Constellation::GPS, "L1C");
assert!(channel.is_ok());
let channel = channel.unwrap();
assert_eq!(channel, Channel::L1);
}
}
10 changes: 10 additions & 0 deletions rinex/src/epoch/flag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,14 @@ mod test {
assert_eq!(EpochFlag::from_str("6").unwrap(), EpochFlag::CycleSlip);
assert!(EpochFlag::from_str("7").is_err());
}
#[test]
fn to_str() {
assert_eq!(format!("{}", EpochFlag::Ok), "0");
assert_eq!(format!("{}", EpochFlag::PowerFailure), "1");
assert_eq!(format!("{}", EpochFlag::AntennaBeingMoved), "2");
assert_eq!(format!("{}", EpochFlag::NewSiteOccupation), "3");
assert_eq!(format!("{}", EpochFlag::HeaderInformationFollows), "4");
assert_eq!(format!("{}", EpochFlag::ExternalEvent), "5");
assert_eq!(format!("{}", EpochFlag::CycleSlip), "6");
}
}
16 changes: 16 additions & 0 deletions rinex/src/hardware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,19 @@ impl SvAntenna {
s
}
}

#[cfg(test)]
mod test {
use super::*;
use std::str::FromStr;
#[test]
fn rcvr_parser() {
let content = "2090088 LEICA GR50 4.51 ";
let rcvr = Rcvr::from_str(content);
assert!(rcvr.is_ok());
let rcvr = rcvr.unwrap();
assert_eq!(rcvr.model, "LEICA GR50");
assert_eq!(rcvr.sn, "2090088");
assert_eq!(rcvr.firmware, "4.51");
}
}
43 changes: 31 additions & 12 deletions rinex/src/ionex/grid.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#[cfg(feature = "serde")]
use serde::Serialize;
use std::ops::Rem;
use thiserror::Error;

#[cfg(feature = "serde")]
use serde::Serialize;

/// Grid definition Error
#[derive(Error, Debug)]
pub enum Error {
Expand All @@ -18,18 +19,21 @@ pub enum Error {
#[derive(Debug, Clone, Default, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct GridLinspace {
/// Grid start value, in km
/// Grid start coordinates [ddeg]
pub start: f32,
/// Grid end value, in km
/// Grid end coordinates [ddeg]
pub end: f32,
/// Grid scaping / increment value, in km
/// Grid spacing (inncrement value), [ddeg]
pub spacing: f32,
}

impl GridLinspace {
/// Builds a new Linspace definition
pub fn new(start: f32, end: f32, spacing: f32) -> Result<Self, Error> {
let r = end.rem(start);
/*
* End / Start must be multiple of one another
*/
if r == 0.0 {
if end.rem(spacing) == 0.0 {
Ok(Self {
Expand All @@ -44,10 +48,9 @@ impl GridLinspace {
Err(Error::GridStartEndError)
}
}
// Returns total distance, in km, covered by
// this Grid linear space
pub fn total_distance(&self) -> f32 {
(self.end - self.start) * self.spacing
// Returns grid length, in terms of data points
pub fn length(&self) -> usize {
(self.end / self.spacing).floor() as usize
}
/// Returns true if self is a single point space
pub fn is_single_point(&self) -> bool {
Expand Down Expand Up @@ -91,8 +94,24 @@ impl Grid {
pub fn is_2d_grid(&self) -> bool {
self.height.is_single_point()
}
/// Returns total projected 2D area covered [km²]
pub fn total_area(&self) -> f32 {
self.latitude.total_distance() * self.longitude.total_distance()
}

#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_grid() {
let default = GridLinspace::default();
assert_eq!(
default,
GridLinspace {
start: 0.0,
end: 0.0,
spacing: 0.0,
}
);
let grid = GridLinspace::new(1.0, 10.0, 1.0).unwrap();
assert_eq!(grid.length(), 10);
assert_eq!(grid.is_single_point(), false);
}
}
13 changes: 13 additions & 0 deletions rinex/src/ionex/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,16 @@ impl FromStr for RefSystem {
}
}
}

#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_refsystem() {
let default = RefSystem::default();
assert_eq!(
default,
RefSystem::GnssConstellation(Constellation::default())
);
}
}
31 changes: 30 additions & 1 deletion rinex/src/navigation/health.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub enum GloHealth {

impl Default for GloHealth {
fn default() -> Self {
Self::Healthy
Self::Unhealthy
}
}

Expand Down Expand Up @@ -119,3 +119,32 @@ bitflags! {
const E5B_HS1 = 0x80;
}
}

#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_gps() {
assert_eq!(Health::default(), Health::Unhealthy);
assert_eq!(format!("{:E}", Health::default()), "0E0");
}
#[test]
fn test_irnss() {
assert_eq!(IrnssHealth::default(), IrnssHealth::Unknown);
assert_eq!(format!("{:E}", IrnssHealth::default()), "1E0");
}
#[test]
fn test_geo_sbas() {
assert_eq!(GeoHealth::default(), GeoHealth::Unknown);
assert_eq!(format!("{:E}", Health::default()), "0E0");
}
#[test]
fn test_glo() {
assert_eq!(GloHealth::default(), GloHealth::Unhealthy);
assert_eq!(format!("{:E}", GloHealth::default()), "4E0");
}
#[test]
fn test_gal() {
assert_eq!(GalHealth::default(), GalHealth::empty());
}
}
Loading

0 comments on commit 06e1889

Please sign in to comment.