Add tests for Periodic trait
This required some minor refactoring, but it should be clear enough
through inspection that the semantics are preserved. This sets the
stage for more substantive refactoring.
@@ -15,12 +15,55 @@ pub trait Periodic {
/// Given the time we should start the next task, sleep as long as
/// we need to until that time.
fn sleep_until(&self, next_period_start: SteadyTime) {
- let time_to_wait = (next_period_start - SteadyTime::now()).num_milliseconds();
+ if let Some(time_to_wait) = Self::time_to_wait(SteadyTime::now(), next_period_start) {
+ thread::sleep(time_to_wait);
+ }
+ }
+
+ /// Given the time we should start the next task, determine if we need to sleep,
+ /// and if so for how long.
+ fn time_to_wait(now: SteadyTime, next_period_start: SteadyTime) -> Option<StdDuration> {
+ let time_to_wait = (next_period_start - now).num_milliseconds();
if time_to_wait > 0 {
- thread::sleep(StdDuration::from_millis(time_to_wait as u64));
+ Some(StdDuration::from_millis(time_to_wait as u64))
+ } else {
+ None
}
}
/// Returns the amount of time to wait between tasks.
fn update_period(&self) -> Duration;
}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ struct P {}
+ impl Periodic for P {
+ fn update_period(&self) -> Duration { unimplemented!() }
+ }
+
+ #[test]
+ fn time_to_wait_is_some_when_next_period_start_is_in_the_future() {
+ let now = SteadyTime::now();
+ let time_until_next_period = StdDuration::from_secs(1);
+ let next_period_start = now + Duration::from_std(time_until_next_period).unwrap();
+ assert_eq!(P::time_to_wait(now, next_period_start),
+ Some(time_until_next_period));
+ }
+
+ #[test]
+ fn time_to_wait_is_none_when_next_period_start_is_in_the_past() {
+ let now = SteadyTime::now();
+ let time_until_next_period = StdDuration::from_secs(1);
+ let next_period_start = now - Duration::from_std(time_until_next_period).unwrap();
+ assert_eq!(P::time_to_wait(now, next_period_start), None);
+ }
+
+ #[test]
+ fn time_to_wait_is_none_when_next_period_start_is_now() {
+ let now = SteadyTime::now();
+ assert_eq!(P::time_to_wait(now, now), None);
+ }
+}
