refactor: Add the assert_next_eq_with_timeout test helper

This test helper is the same as the assert_next_eq helper, but it waits
for the stream to be ready for a certain amount of time instead of
expecting it to be ready right away.
This commit is contained in:
Damir Jelić
2025-01-31 09:10:00 +01:00
parent 585224b2fa
commit 29862fc9bd
2 changed files with 86 additions and 48 deletions

View File

@@ -18,8 +18,8 @@ use std::{
};
use matrix_sdk::{
assert_next_eq_with_timeout,
test_utils::{logged_in_client_with_server, mocks::MatrixMockServer},
timeout::timeout,
};
use matrix_sdk_test::async_test;
use matrix_sdk_ui::sync_service::{State, SyncService};
@@ -225,23 +225,12 @@ async fn test_sync_service_offline_mode() {
sync_service.start().await;
assert_next_eq!(states, State::Running);
let next_state = timeout(states.next(), Duration::from_millis(500))
.await
.expect("We should have changed states by now")
.unwrap();
assert_eq!(next_state, State::Offline, "We should have entered the offline mode");
assert_next_eq_with_timeout!(states, State::Offline, 500 ms, "We should have entered the offline mode");
}
mock_server.mock_versions().ok().expect(1..).mount().await;
let next_state = timeout(states.next(), Duration::from_millis(500))
.await
.expect("We should changed the state")
.unwrap();
assert_eq!(next_state, State::Running, "We should have continued to sync");
assert_next_eq_with_timeout!(states, State::Running, 500 ms, "We should have continued to sync");
}
#[async_test]
@@ -262,21 +251,9 @@ async fn test_sync_service_offline_mode_stopping() {
sync_service.start().await;
assert_next_eq!(states, State::Running);
let next_state = timeout(states.next(), Duration::from_millis(500))
.await
.expect("We should have changed states by now")
.unwrap();
assert_eq!(next_state, State::Offline, "We should have entered the offline mode");
assert_next_eq_with_timeout!(states, State::Offline, 500 ms, "We should have entered the offline mode");
sync_service.stop().await;
let next_state = timeout(states.next(), Duration::from_millis(500))
.await
.expect("We should have changed the state by now")
.unwrap();
assert_eq!(next_state, State::Idle, "We should have entered the idle mode");
assert_next_eq_with_timeout!(states, State::Idle, 500 ms, "We should have entered the idle mode");
}
#[async_test]
@@ -295,27 +272,10 @@ async fn test_sync_service_offline_mode_restarting() {
sync_service.start().await;
assert_next_eq!(states, State::Running);
let next_state = timeout(states.next(), Duration::from_millis(500))
.await
.expect("We should have changed states by now")
.unwrap();
assert_eq!(next_state, State::Offline, "We should have entered the offline mode");
assert_next_eq_with_timeout!(states, State::Offline, 500 ms, "We should have entered the offline mode");
sync_service.start().await;
let next_state = timeout(states.next(), Duration::from_millis(500))
.await
.expect("We should have changed the state by now")
.unwrap();
assert_eq!(next_state, State::Running, "We should have entered the running mode");
let next_state = timeout(states.next(), Duration::from_millis(500))
.await
.expect("We should have changed the state by now")
.unwrap();
assert_eq!(next_state, State::Offline, "We should have entered the offline mode again");
assert_next_eq_with_timeout!(states, State::Running, 500 ms, "We should have entered the running mode");
assert_next_eq_with_timeout!(states, State::Offline, 500 ms, "We should have entered the offline mode again");
}

View File

@@ -154,6 +154,84 @@ macro_rules! assert_next_matches_with_timeout {
};
}
/// Asserts that the next item from an asynchronous stream is equal to the
/// expected value, with an optional timeout and custom error message.
///
/// # Arguments
///
/// * `$stream` - The asynchronous stream to retrieve the next item from.
/// * `$expected` - The expected value to assert against.
/// * `$timeout ms` (optional) - A timeout in milliseconds (e.g., `200ms`).
/// Defaults to `100ms`.
/// * `$msg` (optional) - A formatted message string for assertion failure.
///
/// # Examples
///
/// ```
/// # async {
/// # use matrix_sdk::assert_next_eq_with_timeout;
/// # use tokio_stream::StreamExt;
///
/// let mut stream = tokio_stream::iter(vec![42]);
/// assert_next_eq_with_timeout!(stream, 42);
///
/// let mut stream = tokio_stream::iter(vec![42]);
/// assert_next_eq_with_timeout!(stream, 42, 200 ms);
///
/// let mut stream = tokio_stream::iter(vec![42]);
/// assert_next_eq_with_timeout!(
/// stream,
/// 42,
/// "Expected 42 but got something else"
/// );
///
/// let mut stream = tokio_stream::iter(vec![42]);
/// assert_next_eq_with_timeout!(stream, 42, 200 ms, "Expected 42 within 200ms");
/// # };
/// ```
#[macro_export]
macro_rules! assert_next_eq_with_timeout {
($stream:expr, $expected:expr) => {
$crate::assert_next_eq_with_timeout_impl!($stream, $expected, std::time::Duration::from_millis(100));
};
($stream:expr, $expected:expr, $timeout:literal ms) => {
$crate::assert_next_eq_with_timeout_impl!($stream, $expected, std::time::Duration::from_millis($timeout));
};
($stream:expr, $expected:expr, $timeout:literal ms, $($msg:tt)*) => {
$crate::assert_next_eq_with_timeout_impl!($stream, $expected, std::time::Duration::from_millis($timeout), $($msg)*);
};
($stream:expr, $expected:expr, $($msg:tt)*) => {
$crate::assert_next_eq_with_timeout_impl!($stream, $expected, std::time::Duration::from_millis(100), $($msg)*);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! assert_next_eq_with_timeout_impl {
($stream:expr, $expected:expr, $timeout:expr) => {
let next_value = tokio::time::timeout(
$timeout,
$stream.next()
)
.await
.expect("We should be able to get the next value out of the stream by now")
.expect("The stream should have given us a new value instead of None");
assert_eq!(next_value, $expected);
};
($stream:expr, $expected:expr, $timeout:expr, $($msg:tt)*) => {
let next_value = tokio::time::timeout(
$timeout,
$stream.next()
)
.await
.expect("We should be able to get the next value out of the stream by now")
.expect("The stream should have given us a new value instead of None");
assert_eq!(next_value, $expected, $($msg)*);
};
}
/// Like `assert_let`, but with the possibility to add an optional timeout.
///
/// If not provided, a timeout value of 100 milliseconds is used.