From 29862fc9bd246beb287997a9242e1b2a40b3a8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Fri, 31 Jan 2025 09:10:00 +0100 Subject: [PATCH] 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. --- .../tests/integration/sync_service.rs | 56 ++----------- crates/matrix-sdk/src/test_utils/mod.rs | 78 +++++++++++++++++++ 2 files changed, 86 insertions(+), 48 deletions(-) diff --git a/crates/matrix-sdk-ui/tests/integration/sync_service.rs b/crates/matrix-sdk-ui/tests/integration/sync_service.rs index 46147fe1c..c7fdc1873 100644 --- a/crates/matrix-sdk-ui/tests/integration/sync_service.rs +++ b/crates/matrix-sdk-ui/tests/integration/sync_service.rs @@ -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"); } diff --git a/crates/matrix-sdk/src/test_utils/mod.rs b/crates/matrix-sdk/src/test_utils/mod.rs index 0594bb134..bea2fe8a0 100644 --- a/crates/matrix-sdk/src/test_utils/mod.rs +++ b/crates/matrix-sdk/src/test_utils/mod.rs @@ -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.