diff --git a/src/common.rs b/src/common.rs index c66aafc..c0d91a0 100644 --- a/src/common.rs +++ b/src/common.rs @@ -86,6 +86,23 @@ where self.update_expectations(expected) } + /// Returns whether all expectations have been consumed. + pub fn is_consumed(&self) -> bool { + self.expected.lock().unwrap().is_empty() + } + + /// Wait until all expectations have been consumed or panic if timeout is reached. + pub fn wait_for_consumption(&self, timeout: std::time::Duration) { + let start = std::time::Instant::now(); + while start.elapsed() < timeout { + if self.is_consumed() { + return; + } + std::thread::sleep(std::time::Duration::from_millis(1)); + } + panic!("Timeout reached while waiting for expectations to be consumed"); + } + /// Assert that all expectations on a given mock have been consumed. pub fn done(&mut self) { self.done_impl(true); @@ -191,6 +208,25 @@ mod tests { mock.done(); } + #[test] + fn wait_for_consumption() { + let expectations = [0u8, 1u8]; + let mut mock: Generic = Generic::new(&expectations); + assert!(!mock.is_consumed()); + + let mut mock_clone = mock.clone(); + let handle = thread::spawn(move || { + assert_eq!(mock_clone.next(), Some(0u8)); + assert_eq!(mock_clone.next(), Some(1u8)); + }); + + mock.wait_for_consumption(std::time::Duration::from_millis(1000)); + assert!(mock.is_consumed()); + mock.done(); + + handle.join().unwrap(); + } + #[test] #[should_panic( expected = "WARNING: A mock (from embedded-hal-mock) was dropped without calling the `.done()` method. See https://github.com/dbrgn/embedded-hal-mock/issues/34 for more details."