use ruchy::runtime::async_runtime::AsyncRuntime;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll, Wake};
use std::time::Duration;
#[cfg(test)]
mod async_runtime_unit_tests {
use super::*;
#[test]
fn test_async_runtime_new() {
let runtime = AsyncRuntime::new();
let _ = runtime;
}
#[test]
fn test_async_runtime_default() {
let runtime = AsyncRuntime::default();
let _ = runtime;
}
#[tokio::test]
async fn test_async_runtime_spawn_simple() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async { 42 });
let result = handle.await;
assert_eq!(result, 42);
}
#[tokio::test]
async fn test_async_runtime_spawn_with_computation() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
let mut sum = 0;
for i in 1..=10 {
sum += i;
}
sum
});
let result = handle.await;
assert_eq!(result, 55); }
#[tokio::test]
async fn test_async_runtime_sleep() {
let runtime = AsyncRuntime::new();
let start = std::time::Instant::now();
runtime.sleep(Duration::from_millis(10)).await;
let elapsed = start.elapsed();
assert!(elapsed >= Duration::from_millis(10));
assert!(elapsed < Duration::from_millis(100)); }
#[tokio::test]
async fn test_async_runtime_spawn_multiple() {
let runtime = AsyncRuntime::new();
let handle1 = runtime.spawn(async { 1 });
let handle2 = runtime.spawn(async { 2 });
let handle3 = runtime.spawn(async { 3 });
let result1 = handle1.await;
let result2 = handle2.await;
let result3 = handle3.await;
assert_eq!(result1, 1);
assert_eq!(result2, 2);
assert_eq!(result3, 3);
}
#[tokio::test]
async fn test_async_runtime_spawn_with_sleep() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
tokio::time::sleep(Duration::from_millis(10)).await;
"done"
});
let result = handle.await;
assert_eq!(result, "done");
}
#[tokio::test]
async fn test_async_runtime_concurrent_spawns() {
let runtime = AsyncRuntime::new();
let mut handles = vec![];
for i in 0..10 {
let handle = runtime.spawn(async move {
tokio::time::sleep(Duration::from_millis(1)).await;
i * 2
});
handles.push(handle);
}
let mut results = vec![];
for handle in handles {
results.push(handle.await);
}
for (i, result) in results.iter().enumerate() {
assert_eq!(*result, i * 2);
}
}
#[tokio::test]
async fn test_async_runtime_nested_spawn() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
let runtime2 = AsyncRuntime::new();
let inner_handle = runtime2.spawn(async { 100 });
inner_handle.await
});
let result = handle.await;
assert_eq!(result, 100);
}
#[tokio::test]
async fn test_async_runtime_error_handling() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
let result: Result<i32, &str> = Ok(42);
result.unwrap()
});
let result = handle.await;
assert_eq!(result, 42);
}
#[tokio::test]
async fn test_async_runtime_with_strings() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
let mut s = String::from("Hello");
s.push_str(", World!");
s
});
let result = handle.await;
assert_eq!(result, "Hello, World!");
}
#[tokio::test]
async fn test_async_runtime_with_vec() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
let mut v = vec![1, 2, 3];
v.push(4);
v.push(5);
v
});
let result = handle.await;
assert_eq!(result, vec![1, 2, 3, 4, 5]);
}
#[tokio::test]
async fn test_multiple_sleeps() {
let runtime = AsyncRuntime::new();
let start = std::time::Instant::now();
runtime.sleep(Duration::from_millis(5)).await;
runtime.sleep(Duration::from_millis(5)).await;
runtime.sleep(Duration::from_millis(5)).await;
let elapsed = start.elapsed();
assert!(elapsed >= Duration::from_millis(15));
}
#[tokio::test]
async fn test_zero_duration_sleep() {
let runtime = AsyncRuntime::new();
let start = std::time::Instant::now();
runtime.sleep(Duration::from_millis(0)).await;
let elapsed = start.elapsed();
assert!(elapsed < Duration::from_millis(10));
}
#[test]
fn test_join_handle_future_impl() {
let runtime = tokio::runtime::Runtime::new().unwrap();
runtime.block_on(async {
let async_runtime = AsyncRuntime::new();
let handle = async_runtime.spawn(async { 123 });
let result = handle.await;
assert_eq!(result, 123);
});
}
struct NoopWaker;
impl Wake for NoopWaker {
fn wake(self: Arc<Self>) {}
fn wake_by_ref(self: &Arc<Self>) {}
}
#[test]
fn test_join_handle_poll() {
let runtime = tokio::runtime::Runtime::new().unwrap();
runtime.block_on(async {
let async_runtime = AsyncRuntime::new();
let mut handle = async_runtime.spawn(async { 999 });
let waker = Arc::new(NoopWaker).into();
let mut context = Context::from_waker(&waker);
let pinned = Pin::new(&mut handle);
match pinned.poll(&mut context) {
Poll::Ready(value) => assert_eq!(value, 999),
Poll::Pending => {
}
}
});
}
}
#[cfg(test)]
mod async_runtime_property_tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn test_spawn_returns_value(value: i32) {
let runtime = tokio::runtime::Runtime::new().unwrap();
runtime.block_on(async move {
let async_runtime = AsyncRuntime::new();
let val_copy = value;
let handle = async_runtime.spawn(async move { val_copy });
let result = handle.await;
assert_eq!(result, value);
});
}
#[test]
fn test_sleep_duration(millis in 0u64..10u64) {
let runtime = tokio::runtime::Runtime::new().unwrap();
runtime.block_on(async {
let async_runtime = AsyncRuntime::new();
let duration = Duration::from_millis(millis);
let start = std::time::Instant::now();
async_runtime.sleep(duration).await;
let elapsed = start.elapsed();
assert!(elapsed >= duration);
});
}
}
}
#[cfg(test)]
mod async_runtime_stress_tests {
use super::*;
#[tokio::test]
#[ignore] async fn test_many_concurrent_spawns() {
let runtime = AsyncRuntime::new();
let mut handles = vec![];
for i in 0..1000 {
let handle = runtime.spawn(async move {
i * i
});
handles.push(handle);
}
for (i, handle) in handles.into_iter().enumerate() {
let result = handle.await;
assert_eq!(result, i * i);
}
}
#[tokio::test]
#[ignore] async fn test_many_sequential_sleeps() {
let runtime = AsyncRuntime::new();
let start = std::time::Instant::now();
for _ in 0..100 {
runtime.sleep(Duration::from_micros(100)).await;
}
let elapsed = start.elapsed();
assert!(elapsed >= Duration::from_millis(10));
}
#[tokio::test]
#[ignore] async fn test_deeply_nested_spawns() {
fn nested_spawn_blocking(depth: usize) -> usize {
if depth == 0 {
return 42;
}
nested_spawn_blocking(depth - 1)
}
let result = nested_spawn_blocking(10);
assert_eq!(result, 42);
}
}
#[cfg(test)]
mod async_runtime_integration_tests {
use super::*;
#[tokio::test]
async fn test_runtime_with_shared_state() {
use std::sync::{Arc, Mutex};
let runtime = AsyncRuntime::new();
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter_clone = counter.clone();
let handle = runtime.spawn(async move {
let mut count = counter_clone.lock().unwrap();
*count += 1;
*count
});
handles.push(handle);
}
for handle in handles {
let _ = handle.await;
}
let final_count = *counter.lock().unwrap();
assert_eq!(final_count, 10);
}
#[tokio::test]
async fn test_runtime_task_cancellation_safety() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
for i in 0..1000 {
tokio::time::sleep(Duration::from_micros(10)).await;
if i == 10 {
return "early_exit";
}
}
"completed"
});
let result = handle.await;
assert_eq!(result, "early_exit");
}
#[tokio::test]
async fn test_runtime_resource_cleanup() {
for _ in 0..100 {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
let _data = vec![0u8; 1000];
42
});
let result = handle.await;
assert_eq!(result, 42);
}
}
#[tokio::test]
async fn test_runtime_performance_timing() {
let runtime = AsyncRuntime::new();
let start = std::time::Instant::now();
let handles: Vec<_> = (0..100).map(|i| runtime.spawn(async move { i })).collect();
let spawn_time = start.elapsed();
let start_await = std::time::Instant::now();
for (i, handle) in handles.into_iter().enumerate() {
let result = handle.await;
assert_eq!(result, i);
}
let await_time = start_await.elapsed();
assert!(spawn_time < Duration::from_millis(100));
assert!(await_time < Duration::from_millis(100));
}
#[tokio::test]
async fn test_runtime_mixed_sync_async_work() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
let mut result = 0;
for i in 1..=10 {
result += i;
}
tokio::time::sleep(Duration::from_millis(1)).await;
result *= 2;
tokio::time::sleep(Duration::from_millis(1)).await;
result
});
let result = handle.await;
assert_eq!(result, 110); }
#[tokio::test]
async fn test_runtime_error_propagation() {
let runtime = AsyncRuntime::new();
let success_handle = runtime.spawn(async { Result::<i32, &str>::Ok(42) });
let success_result = success_handle.await;
assert!(success_result.is_ok());
assert_eq!(success_result.unwrap(), 42);
let error_handle = runtime.spawn(async { Result::<i32, &str>::Err("test error") });
let error_result = error_handle.await;
assert!(error_result.is_err());
assert_eq!(error_result.unwrap_err(), "test error");
}
#[tokio::test]
async fn test_runtime_complex_data_structures() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
use std::collections::HashMap;
let mut map = HashMap::new();
map.insert("key1", vec![1, 2, 3]);
map.insert("key2", vec![4, 5, 6]);
map.insert("key3", vec![7, 8, 9]);
tokio::time::sleep(Duration::from_millis(1)).await;
map
});
let result = handle.await;
assert_eq!(result.len(), 3);
assert_eq!(result.get("key1"), Some(&vec![1, 2, 3]));
assert_eq!(result.get("key2"), Some(&vec![4, 5, 6]));
assert_eq!(result.get("key3"), Some(&vec![7, 8, 9]));
}
#[tokio::test]
async fn test_runtime_producer_consumer_pattern() {
use std::sync::mpsc;
let runtime = AsyncRuntime::new();
let (tx, rx) = mpsc::channel();
let producer_handle = runtime.spawn(async move {
for i in 0..10 {
tx.send(i).unwrap();
tokio::time::sleep(Duration::from_millis(1)).await;
}
});
let consumer_handle = runtime.spawn(async move {
let mut sum = 0;
while let Ok(value) = rx.recv() {
sum += value;
if sum >= 45 {
break;
}
}
sum
});
producer_handle.await;
let consumer_result = consumer_handle.await;
assert_eq!(consumer_result, 45); }
}
#[cfg(test)]
mod async_runtime_edge_case_tests {
use super::*;
#[tokio::test]
async fn test_runtime_immediate_completion() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async { "immediate" });
let result = handle.await;
assert_eq!(result, "immediate");
}
#[tokio::test]
async fn test_runtime_unit_return_type() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
let _ = 42 + 8;
});
let result = handle.await;
assert_eq!(result, ());
}
#[tokio::test]
async fn test_runtime_large_data_transfer() {
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async {
let large_vec: Vec<u64> = (0..10000).collect();
large_vec.len()
});
let result = handle.await;
assert_eq!(result, 10000);
}
#[tokio::test]
async fn test_runtime_sleep_precision() {
let runtime = AsyncRuntime::new();
let durations = vec![
Duration::from_millis(1),
Duration::from_millis(5),
Duration::from_millis(10),
Duration::from_millis(50),
];
for duration in durations {
let start = std::time::Instant::now();
runtime.sleep(duration).await;
let elapsed = start.elapsed();
assert!(elapsed >= duration);
assert!(elapsed <= duration + Duration::from_millis(50));
}
}
#[tokio::test]
async fn test_runtime_spawn_different_types() {
let runtime = AsyncRuntime::new();
let bool_handle = runtime.spawn(async { true });
let string_handle = runtime.spawn(async { "test".to_string() });
let vec_handle = runtime.spawn(async { vec![1, 2, 3] });
let option_handle = runtime.spawn(async { Some(42) });
assert_eq!(bool_handle.await, true);
assert_eq!(string_handle.await, "test");
assert_eq!(vec_handle.await, vec![1, 2, 3]);
assert_eq!(option_handle.await, Some(42));
}
#[tokio::test]
async fn test_runtime_concurrent_sleeps() {
let runtime = AsyncRuntime::new();
let start = std::time::Instant::now();
let handles: Vec<_> = (0..5)
.map(|i| {
runtime.spawn(async move {
tokio::time::sleep(Duration::from_millis(10)).await;
i
})
})
.collect();
let mut results = Vec::new();
for handle in handles {
results.push(handle.await);
}
let elapsed = start.elapsed();
assert!(elapsed < Duration::from_millis(40));
assert_eq!(results, vec![0, 1, 2, 3, 4]);
}
#[tokio::test]
async fn test_runtime_recursive_async() {
async fn async_factorial(n: u64) -> u64 {
let mut result = 1;
for i in 1..=n {
tokio::time::sleep(Duration::from_micros(1)).await;
result *= i;
}
result
}
let runtime = AsyncRuntime::new();
let handle = runtime.spawn(async { async_factorial(5).await });
let result = handle.await;
assert_eq!(result, 120); }
}