use super::*;
use crate::arithmetic::push_int;
use crate::value::Value;
#[test]
fn test_spawn_registry_guard_cleanup() {
let closure_id = 12345;
let env: Box<[Value]> = vec![Value::Int(42), Value::Int(99)].into_boxed_slice();
let fn_ptr: usize = 0x1234;
{
let mut registry = SPAWN_CLOSURE_REGISTRY.lock().unwrap();
registry.insert(closure_id, (fn_ptr, env));
}
{
let registry = SPAWN_CLOSURE_REGISTRY.lock().unwrap();
assert!(registry.contains_key(&closure_id));
}
{
let _guard = SpawnRegistryGuard::new(closure_id);
}
{
let registry = SPAWN_CLOSURE_REGISTRY.lock().unwrap();
assert!(
!registry.contains_key(&closure_id),
"Guard should have cleaned up registry entry on drop"
);
}
}
#[test]
fn test_spawn_registry_guard_disarm() {
let closure_id = 54321;
let env: Box<[Value]> = vec![Value::Int(10), Value::Int(20)].into_boxed_slice();
let fn_ptr: usize = 0x5678;
{
let mut registry = SPAWN_CLOSURE_REGISTRY.lock().unwrap();
registry.insert(closure_id, (fn_ptr, env));
}
{
let mut guard = SpawnRegistryGuard::new(closure_id);
guard.disarm();
}
{
let registry = SPAWN_CLOSURE_REGISTRY.lock().unwrap();
assert!(
registry.contains_key(&closure_id),
"Disarmed guard should not clean up registry entry"
);
drop(registry);
let mut registry = SPAWN_CLOSURE_REGISTRY.lock().unwrap();
registry.remove(&closure_id);
}
}
unsafe extern "C" fn add_one_quot(stack: Stack) -> Stack {
unsafe {
let stack = push_int(stack, 1);
crate::arithmetic::add(stack)
}
}
#[test]
fn test_push_quotation() {
unsafe {
let stack: Stack = crate::stack::alloc_test_stack();
let fn_ptr = add_one_quot as *const () as usize;
let stack = push_quotation(stack, fn_ptr, fn_ptr);
let (_stack, value) = pop(stack);
assert!(matches!(value, Value::Quotation { .. }));
}
}
#[test]
fn test_call_quotation() {
unsafe {
let stack: Stack = crate::stack::alloc_test_stack();
let stack = push_int(stack, 5);
let fn_ptr = add_one_quot as *const () as usize;
let stack = push_quotation(stack, fn_ptr, fn_ptr);
let stack = call(stack);
let (_stack, result) = pop(stack);
assert_eq!(result, Value::Int(6));
}
}
unsafe extern "C" fn noop_quot(stack: Stack) -> Stack {
stack
}
#[test]
fn test_spawn_quotation() {
unsafe {
crate::scheduler::scheduler_init();
let stack: Stack = crate::stack::alloc_test_stack();
let fn_ptr = noop_quot as *const () as usize;
let stack = push_quotation(stack, fn_ptr, fn_ptr);
let stack = spawn(stack);
let (_stack, result) = pop(stack);
match result {
Value::Int(strand_id) => {
assert!(strand_id > 0, "Strand ID should be positive");
}
_ => panic!("Expected Int (strand ID), got {:?}", result),
}
crate::scheduler::wait_all_strands();
}
}