diff options
Diffstat (limited to 'vendor/async-stream/tests')
| -rw-r--r-- | vendor/async-stream/tests/for_await.rs | 23 | ||||
| -rw-r--r-- | vendor/async-stream/tests/spans_preserved.rs | 15 | ||||
| -rw-r--r-- | vendor/async-stream/tests/stream.rs | 237 | ||||
| -rw-r--r-- | vendor/async-stream/tests/try_stream.rs | 87 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/unsoundness_issue_106.rs | 30 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/unsoundness_issue_106.stderr | 36 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/unsoundness_issue_107.rs | 23 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/unsoundness_issue_107.stderr | 13 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/yield_bad_expr_in_macro.rs | 11 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/yield_bad_expr_in_macro.stderr | 5 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/yield_in_async.rs | 11 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/yield_in_async.stderr | 13 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/yield_in_closure.rs | 11 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/yield_in_closure.stderr | 37 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/yield_in_nested_fn.rs | 9 | ||||
| -rw-r--r-- | vendor/async-stream/tests/ui/yield_in_nested_fn.stderr | 24 |
16 files changed, 585 insertions, 0 deletions
diff --git a/vendor/async-stream/tests/for_await.rs b/vendor/async-stream/tests/for_await.rs new file mode 100644 index 00000000..590ffbd9 --- /dev/null +++ b/vendor/async-stream/tests/for_await.rs @@ -0,0 +1,23 @@ +use async_stream::stream; + +use futures_util::stream::StreamExt; + +#[tokio::test] +async fn test() { + let s = stream! { + yield "hello"; + yield "world"; + }; + + let s = stream! { + for await x in s { + yield x.to_owned() + "!"; + } + }; + + let values: Vec<_> = s.collect().await; + + assert_eq!(2, values.len()); + assert_eq!("hello!", values[0]); + assert_eq!("world!", values[1]); +} diff --git a/vendor/async-stream/tests/spans_preserved.rs b/vendor/async-stream/tests/spans_preserved.rs new file mode 100644 index 00000000..f2663b8a --- /dev/null +++ b/vendor/async-stream/tests/spans_preserved.rs @@ -0,0 +1,15 @@ +use async_stream::stream; +use futures_util::pin_mut; +use futures_util::stream::StreamExt; + +#[tokio::test] +async fn spans_preserved() { + let s = stream! { + assert_eq!(line!(), 8); + }; + pin_mut!(s); + + while s.next().await.is_some() { + unreachable!(); + } +} diff --git a/vendor/async-stream/tests/stream.rs b/vendor/async-stream/tests/stream.rs new file mode 100644 index 00000000..4e26a3d1 --- /dev/null +++ b/vendor/async-stream/tests/stream.rs @@ -0,0 +1,237 @@ +use async_stream::stream; + +use futures_core::stream::{FusedStream, Stream}; +use futures_util::pin_mut; +use futures_util::stream::StreamExt; +use tokio::sync::mpsc; +use tokio_test::assert_ok; + +#[tokio::test] +async fn noop_stream() { + let s = stream! {}; + pin_mut!(s); + + while s.next().await.is_some() { + unreachable!(); + } +} + +#[tokio::test] +async fn empty_stream() { + let mut ran = false; + + { + let r = &mut ran; + let s = stream! { + *r = true; + println!("hello world!"); + }; + pin_mut!(s); + + while s.next().await.is_some() { + unreachable!(); + } + } + + assert!(ran); +} + +#[tokio::test] +async fn yield_single_value() { + let s = stream! { + yield "hello"; + }; + + let values: Vec<_> = s.collect().await; + + assert_eq!(1, values.len()); + assert_eq!("hello", values[0]); +} + +#[tokio::test] +async fn fused() { + let s = stream! { + yield "hello"; + }; + pin_mut!(s); + + assert!(!s.is_terminated()); + assert_eq!(s.next().await, Some("hello")); + assert_eq!(s.next().await, None); + + assert!(s.is_terminated()); + // This should return None from now on + assert_eq!(s.next().await, None); +} + +#[tokio::test] +async fn yield_multi_value() { + let s = stream! { + yield "hello"; + yield "world"; + yield "dizzy"; + }; + + let values: Vec<_> = s.collect().await; + + assert_eq!(3, values.len()); + assert_eq!("hello", values[0]); + assert_eq!("world", values[1]); + assert_eq!("dizzy", values[2]); +} + +#[tokio::test] +async fn unit_yield_in_select() { + use tokio::select; + + async fn do_stuff_async() {} + + let s = stream! { + select! { + _ = do_stuff_async() => yield, + else => yield, + } + }; + + let values: Vec<_> = s.collect().await; + assert_eq!(values.len(), 1); +} + +#[tokio::test] +async fn yield_with_select() { + use tokio::select; + + async fn do_stuff_async() {} + async fn more_async_work() {} + + let s = stream! { + select! { + _ = do_stuff_async() => yield "hey", + _ = more_async_work() => yield "hey", + else => yield "hey", + } + }; + + let values: Vec<_> = s.collect().await; + assert_eq!(values, vec!["hey"]); +} + +#[tokio::test] +async fn return_stream() { + fn build_stream() -> impl Stream<Item = u32> { + stream! { + yield 1; + yield 2; + yield 3; + } + } + + let s = build_stream(); + + let values: Vec<_> = s.collect().await; + assert_eq!(3, values.len()); + assert_eq!(1, values[0]); + assert_eq!(2, values[1]); + assert_eq!(3, values[2]); +} + +#[tokio::test] +async fn consume_channel() { + let (tx, mut rx) = mpsc::channel(10); + + let s = stream! { + while let Some(v) = rx.recv().await { + yield v; + } + }; + + pin_mut!(s); + + for i in 0..3 { + assert_ok!(tx.send(i).await); + assert_eq!(Some(i), s.next().await); + } + + drop(tx); + assert_eq!(None, s.next().await); +} + +#[tokio::test] +async fn borrow_self() { + struct Data(String); + + impl Data { + fn stream<'a>(&'a self) -> impl Stream<Item = &str> + 'a { + stream! { + yield &self.0[..]; + } + } + } + + let data = Data("hello".to_string()); + let s = data.stream(); + pin_mut!(s); + + assert_eq!(Some("hello"), s.next().await); +} + +#[tokio::test] +async fn stream_in_stream() { + let s = stream! { + let s = stream! { + for i in 0..3 { + yield i; + } + }; + + pin_mut!(s); + while let Some(v) = s.next().await { + yield v; + } + }; + + let values: Vec<_> = s.collect().await; + assert_eq!(3, values.len()); +} + +#[tokio::test] +async fn yield_non_unpin_value() { + let s: Vec<_> = stream! { + for i in 0..3 { + yield async move { i }; + } + } + .buffered(1) + .collect() + .await; + + assert_eq!(s, vec![0, 1, 2]); +} + +#[test] +fn inner_try_stream() { + use async_stream::try_stream; + use tokio::select; + + async fn do_stuff_async() {} + + let _ = stream! { + select! { + _ = do_stuff_async() => { + let another_s = try_stream! { + yield; + }; + let _: Result<(), ()> = Box::pin(another_s).next().await.unwrap(); + }, + else => {}, + } + yield + }; +} + +#[rustversion::attr(not(stable), ignore)] +#[test] +fn test() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/*.rs"); +} diff --git a/vendor/async-stream/tests/try_stream.rs b/vendor/async-stream/tests/try_stream.rs new file mode 100644 index 00000000..c404e627 --- /dev/null +++ b/vendor/async-stream/tests/try_stream.rs @@ -0,0 +1,87 @@ +use async_stream::try_stream; + +use futures_core::stream::Stream; +use futures_util::stream::StreamExt; + +#[tokio::test] +async fn single_err() { + let s = try_stream! { + if true { + Err("hello")?; + } else { + yield "world"; + } + + unreachable!(); + }; + + let values: Vec<_> = s.collect().await; + assert_eq!(1, values.len()); + assert_eq!(Err("hello"), values[0]); +} + +#[tokio::test] +async fn yield_then_err() { + let s = try_stream! { + yield "hello"; + Err("world")?; + unreachable!(); + }; + + let values: Vec<_> = s.collect().await; + assert_eq!(2, values.len()); + assert_eq!(Ok("hello"), values[0]); + assert_eq!(Err("world"), values[1]); +} + +#[tokio::test] +async fn convert_err() { + struct ErrorA(u8); + #[derive(PartialEq, Debug)] + struct ErrorB(u8); + impl From<ErrorA> for ErrorB { + fn from(a: ErrorA) -> ErrorB { + ErrorB(a.0) + } + } + + fn test() -> impl Stream<Item = Result<&'static str, ErrorB>> { + try_stream! { + if true { + Err(ErrorA(1))?; + } else { + Err(ErrorB(2))?; + } + yield "unreachable"; + } + } + + let values: Vec<_> = test().collect().await; + assert_eq!(1, values.len()); + assert_eq!(Err(ErrorB(1)), values[0]); +} + +#[tokio::test] +async fn multi_try() { + fn test() -> impl Stream<Item = Result<i32, String>> { + try_stream! { + let a = Ok::<_, String>(Ok::<_, String>(123))??; + for _ in 1..10 { + yield a; + } + } + } + let values: Vec<_> = test().collect().await; + assert_eq!(9, values.len()); + assert_eq!( + std::iter::repeat(123).take(9).map(Ok).collect::<Vec<_>>(), + values + ); +} + +#[allow(unused)] +fn issue_65() -> impl Stream<Item = Result<u32, ()>> { + try_stream! { + yield Err(())?; + } +} diff --git a/vendor/async-stream/tests/ui/unsoundness_issue_106.rs b/vendor/async-stream/tests/ui/unsoundness_issue_106.rs new file mode 100644 index 00000000..2b969ee4 --- /dev/null +++ b/vendor/async-stream/tests/ui/unsoundness_issue_106.rs @@ -0,0 +1,30 @@ +use async_stream::stream; +use futures_util::StreamExt; + +use std::pin::pin; + +macro_rules! asynk { + ($e:expr) => { + async { $e } + }; +} + +#[tokio::main] +async fn main() { + pin!(stream! { + let yield_42 = asynk!(yield 42_usize); + let s = stream! { + yield Box::new(12345); + yield_42.await; // yield 42 -- wait that's not a Box!? + }; + for await (n, i) in s.enumerate() { + println!("Item at index {n}:\n {i}"); + // Item at index 0: + // 12345 + // Item at index 1: + // Segmentation fault + } + }) + .next() + .await; +} diff --git a/vendor/async-stream/tests/ui/unsoundness_issue_106.stderr b/vendor/async-stream/tests/ui/unsoundness_issue_106.stderr new file mode 100644 index 00000000..0c0214c0 --- /dev/null +++ b/vendor/async-stream/tests/ui/unsoundness_issue_106.stderr @@ -0,0 +1,36 @@ +error[E0767]: use of unreachable label `'__async_stream_private_check_scope` + --> tests/ui/unsoundness_issue_106.rs:14:10 + | +14 | pin!(stream! { + | __________^ +15 | | let yield_42 = asynk!(yield 42_usize); +16 | | let s = stream! { +17 | | yield Box::new(12345); +... | +26 | | } +27 | | }) + | | ^ + | | | + | |_____unreachable label `'__async_stream_private_check_scope` + | unreachable label defined here + | + = note: labels are unreachable through functions, closures, async blocks and modules + = note: this error originates in the macro `$crate::__private::stream_inner` which comes from the expansion of the macro `stream` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0267]: `break` inside `async` block + --> tests/ui/unsoundness_issue_106.rs:14:10 + | +8 | async { $e } + | ----- enclosing `async` block +... +14 | pin!(stream! { + | __________^ +15 | | let yield_42 = asynk!(yield 42_usize); +16 | | let s = stream! { +17 | | yield Box::new(12345); +... | +26 | | } +27 | | }) + | |_____^ cannot `break` inside `async` block + | + = note: this error originates in the macro `$crate::__private::stream_inner` which comes from the expansion of the macro `stream` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/async-stream/tests/ui/unsoundness_issue_107.rs b/vendor/async-stream/tests/ui/unsoundness_issue_107.rs new file mode 100644 index 00000000..61fd153e --- /dev/null +++ b/vendor/async-stream/tests/ui/unsoundness_issue_107.rs @@ -0,0 +1,23 @@ +use async_stream::stream; +use futures_util::StreamExt; + +use std::pin::pin; + +#[tokio::main] +async fn main() { + let mut outer = vec![]; + { + let v = vec![0; 10]; + let v_ref = &v; + let mut s = pin!(stream! { + for x in v_ref { + yield x + } + }); + while let Some(x) = s.next().await { + outer.push(x); + } + }; + // use-after-free + println!("{outer:?}"); // […garbage allocator internals…, 0, 0, 0] +} diff --git a/vendor/async-stream/tests/ui/unsoundness_issue_107.stderr b/vendor/async-stream/tests/ui/unsoundness_issue_107.stderr new file mode 100644 index 00000000..9b81e62b --- /dev/null +++ b/vendor/async-stream/tests/ui/unsoundness_issue_107.stderr @@ -0,0 +1,13 @@ +error[E0597]: `v` does not live long enough + --> tests/ui/unsoundness_issue_107.rs:11:21 + | +10 | let v = vec![0; 10]; + | - binding `v` declared here +11 | let v_ref = &v; + | ^^ borrowed value does not live long enough +... +20 | }; + | - `v` dropped here while still borrowed +21 | // use-after-free +22 | println!("{outer:?}"); // […garbage allocator internals…, 0, 0, 0] + | --------- borrow later used here diff --git a/vendor/async-stream/tests/ui/yield_bad_expr_in_macro.rs b/vendor/async-stream/tests/ui/yield_bad_expr_in_macro.rs new file mode 100644 index 00000000..37fcd347 --- /dev/null +++ b/vendor/async-stream/tests/ui/yield_bad_expr_in_macro.rs @@ -0,0 +1,11 @@ +use async_stream::stream; + +fn main() { + async fn work() {} + + stream! { + tokio::select! { + _ = work() => yield fn f() {}, + } + }; +} diff --git a/vendor/async-stream/tests/ui/yield_bad_expr_in_macro.stderr b/vendor/async-stream/tests/ui/yield_bad_expr_in_macro.stderr new file mode 100644 index 00000000..1377054f --- /dev/null +++ b/vendor/async-stream/tests/ui/yield_bad_expr_in_macro.stderr @@ -0,0 +1,5 @@ +error: expected an expression + --> tests/ui/yield_bad_expr_in_macro.rs:8:33 + | +8 | _ = work() => yield fn f() {}, + | ^^ diff --git a/vendor/async-stream/tests/ui/yield_in_async.rs b/vendor/async-stream/tests/ui/yield_in_async.rs new file mode 100644 index 00000000..24e73304 --- /dev/null +++ b/vendor/async-stream/tests/ui/yield_in_async.rs @@ -0,0 +1,11 @@ +use async_stream::stream; + +fn main() { + stream! { + let f = async { + yield 123; + }; + + let v = f.await; + }; +} diff --git a/vendor/async-stream/tests/ui/yield_in_async.stderr b/vendor/async-stream/tests/ui/yield_in_async.stderr new file mode 100644 index 00000000..db2451aa --- /dev/null +++ b/vendor/async-stream/tests/ui/yield_in_async.stderr @@ -0,0 +1,13 @@ +error[E0658]: yield syntax is experimental + --> tests/ui/yield_in_async.rs:6:13 + | +6 | yield 123; + | ^^^^^^^^^ + | + = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information + +error[E0727]: `async` coroutines are not yet supported + --> tests/ui/yield_in_async.rs:6:13 + | +6 | yield 123; + | ^^^^^^^^^ diff --git a/vendor/async-stream/tests/ui/yield_in_closure.rs b/vendor/async-stream/tests/ui/yield_in_closure.rs new file mode 100644 index 00000000..cd6ebd9f --- /dev/null +++ b/vendor/async-stream/tests/ui/yield_in_closure.rs @@ -0,0 +1,11 @@ +use async_stream::stream; + +fn main() { + stream! { + Ok("value") + .and_then(|v| { + yield v; + Ok(()) + }); + }; +} diff --git a/vendor/async-stream/tests/ui/yield_in_closure.stderr b/vendor/async-stream/tests/ui/yield_in_closure.stderr new file mode 100644 index 00000000..4d2f6c21 --- /dev/null +++ b/vendor/async-stream/tests/ui/yield_in_closure.stderr @@ -0,0 +1,37 @@ +error[E0658]: yield syntax is experimental + --> tests/ui/yield_in_closure.rs:7:17 + | +7 | yield v; + | ^^^^^^^ + | + = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information + +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> tests/ui/yield_in_closure.rs:7:17 + | +7 | yield v; + | ^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +6 | .and_then(#[coroutine] |v| { + | ++++++++++++ + +error[E0277]: expected a `FnOnce(&str)` closure, found `{coroutine@$DIR/tests/ui/yield_in_closure.rs:6:23: 6:26}` + --> tests/ui/yield_in_closure.rs:6:23 + | +6 | .and_then(|v| { + | ______________--------_^ + | | | + | | required by a bound introduced by this call +7 | | yield v; +8 | | Ok(()) +9 | | }); + | |_____________^ expected an `FnOnce(&str)` closure, found `{coroutine@$DIR/tests/ui/yield_in_closure.rs:6:23: 6:26}` + | + = help: the trait `FnOnce(&str)` is not implemented for `{coroutine@$DIR/tests/ui/yield_in_closure.rs:6:23: 6:26}` +note: required by a bound in `Result::<T, E>::and_then` + --> $RUST/core/src/result.rs + | + | pub fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Result::<T, E>::and_then` diff --git a/vendor/async-stream/tests/ui/yield_in_nested_fn.rs b/vendor/async-stream/tests/ui/yield_in_nested_fn.rs new file mode 100644 index 00000000..9ae6cf2c --- /dev/null +++ b/vendor/async-stream/tests/ui/yield_in_nested_fn.rs @@ -0,0 +1,9 @@ +use async_stream::stream; + +fn main() { + stream! { + fn foo() { + yield "hello"; + } + }; +} diff --git a/vendor/async-stream/tests/ui/yield_in_nested_fn.stderr b/vendor/async-stream/tests/ui/yield_in_nested_fn.stderr new file mode 100644 index 00000000..951be34d --- /dev/null +++ b/vendor/async-stream/tests/ui/yield_in_nested_fn.stderr @@ -0,0 +1,24 @@ +error[E0658]: yield syntax is experimental + --> tests/ui/yield_in_nested_fn.rs:6:13 + | +6 | yield "hello"; + | ^^^^^^^^^^^^^ + | + = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information + +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> tests/ui/yield_in_nested_fn.rs:6:13 + | +6 | yield "hello"; + | ^^^^^^^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +5 | #[coroutine] fn foo() { + | ++++++++++++ + +error[E0627]: yield expression outside of coroutine literal + --> tests/ui/yield_in_nested_fn.rs:6:13 + | +6 | yield "hello"; + | ^^^^^^^^^^^^^ |
