use fluxion_core::{FluxionError, StreamItem};
use fluxion_stream::{CombineWithPreviousExt, MapOrderedExt};
use fluxion_test_utils::{test_channel_with_errors, unwrap_stream, Sequenced};
#[tokio::test]
async fn test_map_ordered_propagates_errors() -> anyhow::Result<()> {
let (tx, stream) = test_channel_with_errors::<Sequenced<i32>>();
let mut result = stream
.combine_with_previous()
.map_ordered(|x| Sequenced::new(format!("Current: {}", x.current.value)));
tx.unbounded_send(StreamItem::Value(Sequenced::new(1)))?;
assert!(
matches!(unwrap_stream(&mut result, 100).await, StreamItem::Value(ref v) if v.value == "Current: 1")
);
tx.unbounded_send(StreamItem::Error(FluxionError::stream_error("Error")))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Error(_)
));
tx.unbounded_send(StreamItem::Value(Sequenced::new(2)))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Value(_)
));
drop(tx);
Ok(())
}
#[tokio::test]
async fn test_map_ordered_transformation_after_error() -> anyhow::Result<()> {
let (tx, stream) = test_channel_with_errors::<Sequenced<i32>>();
let mut result = stream
.combine_with_previous()
.map_ordered(|x| Sequenced::new(x.current.value * 2));
tx.unbounded_send(StreamItem::Value(Sequenced::with_timestamp(10, 1)))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Value(v) if v.value == 20
));
tx.unbounded_send(StreamItem::Value(Sequenced::with_timestamp(20, 2)))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Value(v) if v.value == 40
));
tx.unbounded_send(StreamItem::Error(FluxionError::stream_error("Error")))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Error(_)
));
tx.unbounded_send(StreamItem::Value(Sequenced::with_timestamp(40, 4)))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Value(v) if v.value == 80
));
drop(tx);
Ok(())
}
#[tokio::test]
async fn test_map_ordered_preserves_error_passthrough() -> anyhow::Result<()> {
let (tx, stream) = test_channel_with_errors::<Sequenced<i32>>();
let mut result = stream
.combine_with_previous()
.map_ordered(|x| Sequenced::new(x.current.value * 100));
tx.unbounded_send(StreamItem::Error(FluxionError::stream_error("Error")))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Error(_)
),);
tx.unbounded_send(StreamItem::Value(Sequenced::with_timestamp(2, 2)))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Value(v) if v.value == 200
));
drop(tx);
Ok(())
}
#[tokio::test]
async fn test_map_ordered_chain_after_error() -> anyhow::Result<()> {
let (tx, stream) = test_channel_with_errors::<Sequenced<i32>>();
let mut result = stream
.combine_with_previous()
.map_ordered(|x| Sequenced::new(x.current.value * 2));
tx.unbounded_send(StreamItem::Value(Sequenced::with_timestamp(5, 1)))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Value(v) if v.value == 10
));
tx.unbounded_send(StreamItem::Error(FluxionError::stream_error("Error")))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Error(_)
));
tx.unbounded_send(StreamItem::Value(Sequenced::with_timestamp(15, 3)))?;
assert!(matches!(
unwrap_stream(&mut result, 100).await,
StreamItem::Value(v) if v.value == 30
));
drop(tx);
Ok(())
}