Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

+161
View File
@@ -0,0 +1,161 @@
use dever_runtime::{
async_stream::{AsyncStream, Error},
channel::Channel,
task::{Limits, Runtime},
};
use futures_util::stream;
use std::{
future::{Future, poll_fn},
sync::{
Arc,
atomic::{AtomicUsize, Ordering},
},
task::Poll,
};
fn runtime() -> Runtime {
Runtime::new(Limits {
threads: 2,
workers: 1,
tasks: 8,
})
.unwrap()
}
async fn pending(future: std::pin::Pin<&mut impl Future>) {
let mut future = future;
poll_fn(|context| {
assert!(future.as_mut().poll(context).is_pending());
Poll::Ready(())
})
.await;
}
struct Notice(Arc<AtomicUsize>);
impl Drop for Notice {
fn drop(&mut self) {
self.0.fetch_add(1, Ordering::SeqCst);
}
}
#[test]
fn values_are_lazy_and_aliases_share_cursor_and_close() {
let calls = Arc::new(AtomicUsize::new(0));
let observed = calls.clone();
let values = AsyncStream::values((1..=3).inspect(move |_| {
calls.fetch_add(1, Ordering::SeqCst);
}));
assert_eq!(observed.load(Ordering::SeqCst), 0);
let alias = values.clone();
runtime()
.run(async |_| {
assert_eq!(values.next().await, Ok(Some(1)));
assert_eq!(alias.next().await, Ok(Some(2)));
assert_eq!(observed.load(Ordering::SeqCst), 2);
alias.close();
assert_eq!(values.next().await, Ok(None));
assert_eq!(observed.load(Ordering::SeqCst), 2);
})
.unwrap();
}
#[test]
fn channel_stream_preserves_null_items_and_external_channel_alias() {
runtime()
.run(async |_| {
let channel = Channel::new(2).unwrap();
channel.send(None).await.unwrap();
channel.send(Some(2)).await.unwrap();
let values = AsyncStream::channel(channel.clone());
assert_eq!(values.next().await, Ok(Some(None)));
values.close();
assert_eq!(values.next().await, Ok(None));
assert_eq!(channel.receive().await, Ok(Some(Some(2))));
channel.send(Some(3)).await.unwrap();
channel.close().await.unwrap();
let remaining = AsyncStream::channel(channel);
assert_eq!(remaining.next().await, Ok(Some(Some(3))));
assert_eq!(remaining.next().await, Ok(None));
})
.unwrap();
}
#[test]
fn close_wakes_current_and_queued_pulls() {
runtime()
.run(async |_| {
let values = AsyncStream::channel(Channel::<i64>::new(1).unwrap());
let mut first = std::pin::pin!(values.next());
let mut second = std::pin::pin!(values.next());
pending(first.as_mut()).await;
pending(second.as_mut()).await;
values.close();
assert_eq!(first.await, Ok(None));
assert_eq!(second.await, Ok(None));
})
.unwrap();
}
#[test]
fn cancellation_closes_aliases_and_releases_the_producer() {
let drops = Arc::new(AtomicUsize::new(0));
let observed = drops.clone();
let values = AsyncStream::<i64>::new(stream::unfold(Notice(drops), |owner| async move {
std::future::pending::<()>().await;
Some((Ok(1), owner))
}));
let alias = values.clone();
runtime()
.run(async |scope| {
let (started, ready) = tokio::sync::oneshot::channel();
let pending = scope
.spawn_leaf(move || async move {
let _owner = values.close_on_drop();
let mut next = std::pin::pin!(values.next());
pending(next.as_mut()).await;
started.send(()).unwrap();
next.await
})
.unwrap();
ready.await.unwrap();
pending.stop().await.unwrap();
assert_eq!(observed.load(Ordering::SeqCst), 1);
assert_eq!(alias.next().await, Ok(None));
})
.unwrap();
}
#[test]
fn terminal_fault_releases_source_before_delivery_and_is_not_repeated() {
let drops = Arc::new(AtomicUsize::new(0));
let observed = drops.clone();
let values = AsyncStream::<i64>::new(stream::unfold(Notice(drops), |owner| async move {
Some((Err(Error::Overflow), owner))
}));
runtime()
.run(async |_| {
assert_eq!(values.next().await, Err(Error::Overflow));
assert_eq!(observed.load(Ordering::SeqCst), 1);
assert_eq!(values.next().await, Ok(None));
})
.unwrap();
}
#[test]
fn ticks_are_created_without_runtime_and_closed_without_waiting_for_deadline() {
assert!(matches!(AsyncStream::ticks(0), Err(Error::Period)));
assert!(matches!(AsyncStream::ticks(-1), Err(Error::Period)));
let values = AsyncStream::ticks(60000).unwrap();
runtime()
.run(async |_| {
let mut first = std::pin::pin!(values.next());
pending(first.as_mut()).await;
values.close();
assert_eq!(first.await, Ok(None));
let values = AsyncStream::ticks(1).unwrap();
assert_eq!(values.next().await, Ok(Some(1)));
assert_eq!(values.next().await, Ok(Some(2)));
values.close();
})
.unwrap();
}