diff --git a/src/protocol/clock/time_extent.rs b/src/protocol/clock/time_extent.rs index 85b5257ad..d0713645b 100644 --- a/src/protocol/clock/time_extent.rs +++ b/src/protocol/clock/time_extent.rs @@ -27,6 +27,15 @@ pub struct TimeExtent { pub amount: TimeExtentMultiplier, } +pub const ZERO: TimeExtent = TimeExtent { + increment: TimeExtentBase::ZERO, + amount: TimeExtentMultiplier::MIN, +}; +pub const MAX: TimeExtent = TimeExtent { + increment: TimeExtentBase::MAX, + amount: TimeExtentMultiplier::MAX, +}; + impl TimeExtent { pub const fn from_sec(seconds: u64, amount: &TimeExtentMultiplier) -> Self { Self { @@ -159,7 +168,7 @@ mod test { use crate::protocol::clock::time_extent::{ checked_duration_from_nanos, DefaultTimeExtentMaker, Extent, MakeTimeExtent, TimeExtent, TimeExtentBase, - TimeExtentProduct, + TimeExtentMultiplier, TimeExtentProduct, MAX, ZERO, }; use crate::protocol::clock::{DefaultClock, DurationSinceUnixEpoch, StoppedTime}; @@ -173,8 +182,12 @@ mod test { const NANOS_PER_SEC: u32 = 1_000_000_000; #[test] - fn it_should_return_a_duration() { - assert_eq!(checked_duration_from_nanos(0).unwrap(), Duration::from_micros(0)); + fn it_should_give_zero_for_zero_input() { + assert_eq!(checked_duration_from_nanos(0).unwrap(), Duration::ZERO); + } + + #[test] + fn it_should_be_the_same_as_duration_implementation_for_u64_numbers() { assert_eq!( checked_duration_from_nanos(1232143214343432).unwrap(), Duration::from_nanos(1232143214343432) @@ -183,6 +196,10 @@ mod test { checked_duration_from_nanos(u64::MAX as u128).unwrap(), Duration::from_nanos(u64::MAX) ); + } + + #[test] + fn it_should_work_for_some_numbers_larger_than_u64() { assert_eq!( checked_duration_from_nanos(TIME_EXTENT_VAL.amount as u128 * NANOS_PER_SEC as u128).unwrap(), Duration::from_secs(TIME_EXTENT_VAL.amount) @@ -190,7 +207,7 @@ mod test { } #[test] - fn it_should_return_tryfrom_int_error() { + fn it_should_fail_for_numbers_that_are_too_large() { assert_eq!( checked_duration_from_nanos(u128::MAX).unwrap_err(), u64::try_from(u128::MAX).unwrap_err() @@ -198,311 +215,340 @@ mod test { } } - mod time_extent_from_sec { + mod time_extent { use super::*; - #[test] - fn it_should_make_time_extent() { - assert_eq!(TIME_EXTENT_VAL.increment, TimeExtentBase::from_secs(2)); - assert_eq!(TIME_EXTENT_VAL.amount, 239812388723); - } - } + mod fn_default { - mod time_extent_default { - use super::*; + use super::*; - #[test] - fn it_should_make_time_extent() { - let time_extent_default = TimeExtent::default(); - assert_eq!(time_extent_default.increment, TimeExtentBase::ZERO); - assert_eq!(time_extent_default.amount, 0); + #[test] + fn it_should_default_initialize_to_zero() { + assert_eq!(TimeExtent::default(), ZERO); + } } - } - mod time_extent_new { - use super::*; + mod fn_from_sec { + use super::*; - #[test] - fn it_should_make_time_extent() { - let time_extent = TimeExtent::new(&TimeExtentBase::from_millis(2), &TIME_EXTENT_VAL.amount); - assert_eq!(time_extent.increment, TimeExtentBase::from_millis(2)); - assert_eq!(time_extent.amount, TIME_EXTENT_VAL.amount); + #[test] + fn it_should_make_empty_for_zero() { + assert_eq!(TimeExtent::from_sec(u64::MIN, &TimeExtentMultiplier::MIN), ZERO); + } + #[test] + fn it_should_make_from_seconds() { + assert_eq!( + TimeExtent::from_sec(TIME_EXTENT_VAL.increment.as_secs(), &TIME_EXTENT_VAL.amount), + TIME_EXTENT_VAL + ); + } } - } - mod time_extent_increase { - use std::num::IntErrorKind; + mod fn_new { + use super::*; - use super::*; + #[test] + fn it_should_make_empty_for_zero() { + assert_eq!(TimeExtent::new(&TimeExtentBase::ZERO, &TimeExtentMultiplier::MIN), ZERO); + } - #[test] - fn it_should_return_increased() { - let time_extent_default = TimeExtent::default(); - let time_extent = TimeExtent::new(&TimeExtentBase::from_millis(2), &TIME_EXTENT_VAL.amount); - - let time_extent_default_increase = TimeExtent { - increment: TimeExtentBase::ZERO, - amount: 50, - }; - let time_extent_increase = TimeExtent { - increment: TimeExtentBase::from_millis(2), - amount: TIME_EXTENT_VAL.amount + 50, - }; - let time_extent_from_sec_increase = TimeExtent { - increment: TIME_EXTENT_VAL.increment, - amount: TIME_EXTENT_VAL.amount + 50, - }; - - assert_eq!(time_extent_default.increase(50).unwrap(), time_extent_default_increase); - assert_eq!(time_extent.increase(50).unwrap(), time_extent_increase); - assert_eq!(TIME_EXTENT_VAL.increase(50).unwrap(), time_extent_from_sec_increase); + #[test] + fn it_should_make_new() { + assert_eq!( + TimeExtent::new(&TimeExtentBase::from_millis(2), &TIME_EXTENT_VAL.amount), + TimeExtent { + increment: TimeExtentBase::from_millis(2), + amount: TIME_EXTENT_VAL.amount + } + ); + } } - #[test] - fn it_should_postive_overflow() { - assert_eq!(TIME_EXTENT_VAL.increase(u64::MAX), Err(IntErrorKind::PosOverflow)); - } - } + mod fn_increase { + use std::num::IntErrorKind; - mod time_extent_decrease { - use std::num::IntErrorKind; + use super::*; - use super::*; + #[test] + fn it_should_not_increase_for_zero() { + assert_eq!(ZERO.increase(0).unwrap(), ZERO); + } - #[test] - fn it_should_return_decreased() { - let time_extent_default = TimeExtent::default(); - let time_extent = TimeExtent::new(&TimeExtentBase::from_millis(2), &TIME_EXTENT_VAL.amount); - - let time_extent_default_decrease = TimeExtent { - increment: TimeExtentBase::ZERO, - amount: 0, - }; - let time_extent_decrease = TimeExtent { - increment: TimeExtentBase::from_millis(2), - amount: TIME_EXTENT_VAL.amount - 50, - }; - let time_extent_from_sec_decrease = TimeExtent { - increment: TIME_EXTENT_VAL.increment, - amount: TIME_EXTENT_VAL.amount - 50, - }; - - assert_eq!(time_extent_default.decrease(0).unwrap(), time_extent_default_decrease); - assert_eq!(time_extent.decrease(50).unwrap(), time_extent_decrease); - assert_eq!(TIME_EXTENT_VAL.decrease(50).unwrap(), time_extent_from_sec_decrease); - } + #[test] + fn it_should_increase() { + assert_eq!( + TIME_EXTENT_VAL.increase(50).unwrap(), + TimeExtent { + increment: TIME_EXTENT_VAL.increment, + amount: TIME_EXTENT_VAL.amount + 50, + } + ); + } - #[test] - fn it_should_return_an_negitive_overflow() { - assert_eq!(TIME_EXTENT_VAL.decrease(u64::MAX), Err(IntErrorKind::NegOverflow)); + #[test] + fn it_should_fail_when_attempting_to_increase_beyond_bounds() { + assert_eq!(TIME_EXTENT_VAL.increase(u64::MAX), Err(IntErrorKind::PosOverflow)); + } } - } - mod time_extent_total { - use super::*; + mod fn_decrease { + use std::num::IntErrorKind; - #[test] - fn it_should_return_total() { - let time_extent_default = TimeExtent::default(); - let time_extent = TimeExtent::new(&TimeExtentBase::from_millis(2), &(TIME_EXTENT_VAL.amount / 1000)); + use super::*; - assert_eq!(time_extent_default.total().unwrap().unwrap(), TimeExtentProduct::ZERO); - assert_eq!( - time_extent.total().unwrap().unwrap(), - TimeExtentProduct::new(479624, 776000000) - ); - assert_eq!( - TIME_EXTENT_VAL.total().unwrap().unwrap(), - TimeExtentProduct::from_secs(TIME_EXTENT_VAL.increment.as_secs() * TIME_EXTENT_VAL.amount) - ); - } + #[test] + fn it_should_not_decrease_for_zero() { + assert_eq!(ZERO.decrease(0).unwrap(), ZERO); + } - #[test] - fn it_should_return_none() { - let time_extent_max = TimeExtent { - increment: TimeExtentBase::MAX, - amount: u64::MAX as u64, - }; - assert_eq!(time_extent_max.total(), None); - } + #[test] + fn it_should_decrease() { + assert_eq!( + TIME_EXTENT_VAL.decrease(50).unwrap(), + TimeExtent { + increment: TIME_EXTENT_VAL.increment, + amount: TIME_EXTENT_VAL.amount - 50, + } + ); + } - #[test] - fn it_should_return_tryfrom_int_error() { - let time_extent_max = TimeExtent { - increment: TimeExtentBase::MAX, - amount: 2, - }; - assert_eq!( - time_extent_max.total().unwrap().unwrap_err(), - u64::try_from(u128::MAX).unwrap_err() - ); + #[test] + fn it_should_fail_when_attempting_to_decrease_beyond_bounds() { + assert_eq!(TIME_EXTENT_VAL.decrease(u64::MAX), Err(IntErrorKind::NegOverflow)); + } } - } - mod time_extent_total_next { - use super::*; + mod fn_total { + use super::*; - #[test] - fn it_should_get_the_time_extent_total_next() { - let time_extent_default = TimeExtent::default(); - let time_extent = TimeExtent::new(&TimeExtentBase::from_millis(2), &TIME_EXTENT_VAL.amount); + #[test] + fn it_should_be_zero_for_zero() { + assert_eq!(ZERO.total().unwrap().unwrap(), TimeExtentProduct::ZERO); + } - assert_eq!( - time_extent_default.total_next().unwrap().unwrap(), - TimeExtentProduct::from_secs(0) - ); - assert_eq!( - time_extent.total_next().unwrap().unwrap(), - TimeExtentProduct::new(479624777, 448000000) - ); - assert_eq!( - TIME_EXTENT_VAL.total_next().unwrap().unwrap(), - TimeExtentProduct::from_secs(TIME_EXTENT_VAL.increment.as_secs() * (TIME_EXTENT_VAL.amount + 1)) - ); - } + #[test] + fn it_should_give_a_total() { + assert_eq!( + TIME_EXTENT_VAL.total().unwrap().unwrap(), + TimeExtentProduct::from_secs(TIME_EXTENT_VAL.increment.as_secs() * TIME_EXTENT_VAL.amount) + ); + + assert_eq!( + TimeExtent::new(&TimeExtentBase::from_millis(2), &(TIME_EXTENT_VAL.amount * 1000)) + .total() + .unwrap() + .unwrap(), + TimeExtentProduct::from_secs(TIME_EXTENT_VAL.increment.as_secs() * TIME_EXTENT_VAL.amount) + ); + + assert_eq!( + TimeExtent::new(&TimeExtentBase::from_secs(1), &(u64::MAX)) + .total() + .unwrap() + .unwrap(), + TimeExtentProduct::from_secs(u64::MAX) + ); + } - #[test] - fn it_should_return_none() { - let time_extent_max = TimeExtent { - increment: TimeExtentBase::MAX, - amount: u64::MAX as u64, - }; - assert_eq!(time_extent_max.total_next(), None); - } + #[test] + fn it_should_fail_when_too_large() { + assert_eq!(MAX.total(), None); + } - #[test] - fn it_should_return_tryfrom_int_error() { - let time_extent_max = TimeExtent { - increment: TimeExtentBase::MAX, - amount: 2, - }; - assert_eq!( - time_extent_max.total_next().unwrap().unwrap_err(), - u64::try_from(u128::MAX).unwrap_err() - ); + #[test] + fn it_should_fail_when_product_is_too_large() { + let time_extent = TimeExtent { + increment: MAX.increment, + amount: 2, + }; + assert_eq!( + time_extent.total().unwrap().unwrap_err(), + u64::try_from(u128::MAX).unwrap_err() + ); + } } - } - mod make_time_extent_now { - use super::*; + mod fn_total_next { + use super::*; - #[test] - fn it_should_return_a_time_extent() { - assert_eq!( - DefaultTimeExtentMaker::now(&TIME_EXTENT_VAL.increment).unwrap().unwrap(), - TimeExtent { - increment: TIME_EXTENT_VAL.increment, - amount: 0 - } - ); - - DefaultClock::local_set(&DurationSinceUnixEpoch::from_secs(TIME_EXTENT_VAL.amount * 2)); + #[test] + fn it_should_be_zero_for_zero() { + assert_eq!(ZERO.total_next().unwrap().unwrap(), TimeExtentProduct::ZERO); + } - assert_eq!( - DefaultTimeExtentMaker::now(&TIME_EXTENT_VAL.increment).unwrap().unwrap(), - TIME_EXTENT_VAL - ); - } + #[test] + fn it_should_give_a_total() { + assert_eq!( + TIME_EXTENT_VAL.total_next().unwrap().unwrap(), + TimeExtentProduct::from_secs(TIME_EXTENT_VAL.increment.as_secs() * (TIME_EXTENT_VAL.amount + 1)) + ); + + assert_eq!( + TimeExtent::new(&TimeExtentBase::from_millis(2), &(TIME_EXTENT_VAL.amount * 1000)) + .total_next() + .unwrap() + .unwrap(), + TimeExtentProduct::new( + TIME_EXTENT_VAL.increment.as_secs() * (TIME_EXTENT_VAL.amount), + TimeExtentBase::from_millis(2).as_nanos().try_into().unwrap() + ) + ); + + assert_eq!( + TimeExtent::new(&TimeExtentBase::from_secs(1), &(u64::MAX - 1)) + .total_next() + .unwrap() + .unwrap(), + TimeExtentProduct::from_secs(u64::MAX) + ); + } - #[test] - fn it_should_return_none() { - assert_eq!(DefaultTimeExtentMaker::now(&TimeExtentBase::ZERO), None); - } + #[test] + fn it_should_fail_when_too_large() { + assert_eq!(MAX.total_next(), None); + } - #[test] - fn it_should_return_tryfrom_int_error() { - DefaultClock::local_set(&DurationSinceUnixEpoch::MAX); - assert_eq!( - DefaultTimeExtentMaker::now(&TimeExtentBase::from_millis(1)) - .unwrap() - .unwrap_err(), - u64::try_from(u128::MAX).unwrap_err() - ); + #[test] + fn it_should_fail_when_product_is_too_large() { + let time_extent = TimeExtent { + increment: MAX.increment, + amount: 2, + }; + assert_eq!( + time_extent.total_next().unwrap().unwrap_err(), + u64::try_from(u128::MAX).unwrap_err() + ); + } } } - mod make_time_extent_now_after { - use std::time::Duration; - + mod make_time_extent { use super::*; - #[test] - fn it_should_return_a_time_extent() { - assert_eq!( - DefaultTimeExtentMaker::now_after(&TIME_EXTENT_VAL.increment, &Duration::from_secs(TIME_EXTENT_VAL.amount * 2)) - .unwrap() - .unwrap(), - TIME_EXTENT_VAL - ); - } + mod fn_now { + use super::*; + + #[test] + fn it_should_give_a_time_extent() { + assert_eq!( + DefaultTimeExtentMaker::now(&TIME_EXTENT_VAL.increment).unwrap().unwrap(), + TimeExtent { + increment: TIME_EXTENT_VAL.increment, + amount: 0 + } + ); + + DefaultClock::local_set(&DurationSinceUnixEpoch::from_secs(TIME_EXTENT_VAL.amount * 2)); + + assert_eq!( + DefaultTimeExtentMaker::now(&TIME_EXTENT_VAL.increment).unwrap().unwrap(), + TIME_EXTENT_VAL + ); + } - #[test] - fn it_should_return_none() { - assert_eq!( - DefaultTimeExtentMaker::now_after(&TimeExtentBase::ZERO, &Duration::ZERO), - None - ); + #[test] + fn it_should_fail_for_zero() { + assert_eq!(DefaultTimeExtentMaker::now(&TimeExtentBase::ZERO), None); + } - DefaultClock::local_set(&DurationSinceUnixEpoch::MAX); - assert_eq!(DefaultTimeExtentMaker::now_after(&TimeExtentBase::ZERO, &Duration::MAX), None); + #[test] + fn it_should_fail_if_amount_exceeds_bounds() { + DefaultClock::local_set(&DurationSinceUnixEpoch::MAX); + assert_eq!( + DefaultTimeExtentMaker::now(&TimeExtentBase::from_millis(1)) + .unwrap() + .unwrap_err(), + u64::try_from(u128::MAX).unwrap_err() + ); + } } - #[test] - fn it_should_return_tryfrom_int_error() { - DefaultClock::local_set(&DurationSinceUnixEpoch::MAX); - assert_eq!( - DefaultTimeExtentMaker::now_after(&TimeExtentBase::from_millis(1), &Duration::ZERO) + mod fn_now_after { + use std::time::Duration; + + use super::*; + + #[test] + fn it_should_give_a_time_extent() { + assert_eq!( + DefaultTimeExtentMaker::now_after( + &TIME_EXTENT_VAL.increment, + &Duration::from_secs(TIME_EXTENT_VAL.amount * 2) + ) .unwrap() - .unwrap_err(), - u64::try_from(u128::MAX).unwrap_err() - ); - } - } - mod make_time_extent_now_before { - use std::time::Duration; + .unwrap(), + TIME_EXTENT_VAL + ); + } - use super::*; + #[test] + fn it_should_fail_for_zero() { + assert_eq!( + DefaultTimeExtentMaker::now_after(&TimeExtentBase::ZERO, &Duration::ZERO), + None + ); - #[test] - fn it_should_return_a_time_extent() { - DefaultClock::local_set(&DurationSinceUnixEpoch::MAX); + DefaultClock::local_set(&DurationSinceUnixEpoch::MAX); + assert_eq!(DefaultTimeExtentMaker::now_after(&TimeExtentBase::ZERO, &Duration::MAX), None); + } - assert_eq!( - DefaultTimeExtentMaker::now_before( - &TimeExtentBase::from_secs(u32::MAX as u64), - &Duration::from_secs(u32::MAX as u64) - ) - .unwrap() - .unwrap(), - TimeExtent { - increment: TimeExtentBase::from_secs(u32::MAX as u64), - amount: 4294967296 - } - ); + #[test] + fn it_should_fail_if_amount_exceeds_bounds() { + DefaultClock::local_set(&DurationSinceUnixEpoch::MAX); + assert_eq!( + DefaultTimeExtentMaker::now_after(&TimeExtentBase::from_millis(1), &Duration::ZERO) + .unwrap() + .unwrap_err(), + u64::try_from(u128::MAX).unwrap_err() + ); + } } + mod fn_now_before { + use std::time::Duration; - #[test] - fn it_should_return_none() { - assert_eq!( - DefaultTimeExtentMaker::now_before(&TimeExtentBase::ZERO, &Duration::ZERO), - None - ); + use super::*; - assert_eq!( - DefaultTimeExtentMaker::now_before(&TimeExtentBase::ZERO, &Duration::MAX), - None - ); - } + #[test] + fn it_should_give_a_time_extent() { + DefaultClock::local_set(&DurationSinceUnixEpoch::MAX); - #[test] - fn it_should_return_tryfrom_int_error() { - DefaultClock::local_set(&DurationSinceUnixEpoch::MAX); - assert_eq!( - DefaultTimeExtentMaker::now_before(&TimeExtentBase::from_millis(1), &Duration::ZERO) + assert_eq!( + DefaultTimeExtentMaker::now_before( + &TimeExtentBase::from_secs(u32::MAX as u64), + &Duration::from_secs(u32::MAX as u64) + ) .unwrap() - .unwrap_err(), - u64::try_from(u128::MAX).unwrap_err() - ); + .unwrap(), + TimeExtent { + increment: TimeExtentBase::from_secs(u32::MAX as u64), + amount: 4294967296 + } + ); + } + + #[test] + fn it_should_fail_for_zero() { + assert_eq!( + DefaultTimeExtentMaker::now_before(&TimeExtentBase::ZERO, &Duration::ZERO), + None + ); + + assert_eq!( + DefaultTimeExtentMaker::now_before(&TimeExtentBase::ZERO, &Duration::MAX), + None + ); + } + + #[test] + fn it_should_fail_if_amount_exceeds_bounds() { + DefaultClock::local_set(&DurationSinceUnixEpoch::MAX); + assert_eq!( + DefaultTimeExtentMaker::now_before(&TimeExtentBase::from_millis(1), &Duration::ZERO) + .unwrap() + .unwrap_err(), + u64::try_from(u128::MAX).unwrap_err() + ); + } } } }