use diode_base::defer;
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
#[test]
fn test_defer_basic_functionality() {
let executed = Arc::new(Mutex::new(false));
let executed_clone = executed.clone();
{
let _defer = defer(move || {
*executed_clone.lock().unwrap() = true;
});
assert!(!*executed.lock().unwrap());
}
assert!(*executed.lock().unwrap());
}
#[test]
fn test_defer_macro_basic() {
let executed = Arc::new(Mutex::new(false));
let executed_clone = executed.clone();
{
defer!({
*executed_clone.lock().unwrap() = true;
});
assert!(!*executed.lock().unwrap());
}
assert!(*executed.lock().unwrap());
}
#[test]
fn test_defer_macro_single_expression() {
let counter = Arc::new(Mutex::new(0));
let counter_clone = counter.clone();
{
defer!(*counter_clone.lock().unwrap() += 1);
assert_eq!(*counter.lock().unwrap(), 0);
}
assert_eq!(*counter.lock().unwrap(), 1);
}
#[test]
fn test_multiple_defers_lifo_order() {
let execution_order = Arc::new(Mutex::new(Vec::new()));
{
let order1 = execution_order.clone();
let order2 = execution_order.clone();
let order3 = execution_order.clone();
let _defer1 = defer(move || {
order1.lock().unwrap().push(1);
});
let _defer2 = defer(move || {
order2.lock().unwrap().push(2);
});
let _defer3 = defer(move || {
order3.lock().unwrap().push(3);
});
assert!(execution_order.lock().unwrap().is_empty());
}
assert_eq!(*execution_order.lock().unwrap(), vec![3, 2, 1]);
}
#[test]
fn test_defer_in_function_scope() {
fn test_function() -> i32 {
let counter = Rc::new(RefCell::new(0));
let counter_clone = counter.clone();
let _defer = defer(move || {
*counter_clone.borrow_mut() += 10;
});
*counter.borrow_mut() += 5;
assert_eq!(*counter.borrow(), 5);
*counter.borrow()
}
let result = test_function();
assert_eq!(result, 5);
}
#[test]
fn test_defer_with_mutable_reference() {
let mut counter = 0;
{
let counter_ptr = &mut counter as *mut i32;
let _defer = defer(move || unsafe {
*counter_ptr += 1;
});
counter += 5;
assert_eq!(counter, 5);
}
assert_eq!(counter, 6);
}
#[test]
fn test_defer_with_string_operations() {
let result = Arc::new(Mutex::new(String::new()));
let result_clone = result.clone();
{
let _defer = defer(move || {
result_clone.lock().unwrap().push_str("-end");
});
result.lock().unwrap().push_str("start");
assert_eq!(*result.lock().unwrap(), "start");
}
assert_eq!(*result.lock().unwrap(), "start-end");
}
#[test]
fn test_defer_explicit_drop() {
let executed = Arc::new(Mutex::new(false));
let executed_clone = executed.clone();
let defer_guard = defer(move || {
*executed_clone.lock().unwrap() = true;
});
assert!(!*executed.lock().unwrap());
drop(defer_guard);
assert!(*executed.lock().unwrap());
}
#[test]
fn test_defer_nested_scopes() {
let execution_order = Arc::new(Mutex::new(Vec::new()));
{
let order1 = execution_order.clone();
let _defer_outer = defer(move || {
order1.lock().unwrap().push("outer");
});
{
let order2 = execution_order.clone();
let _defer_inner = defer(move || {
order2.lock().unwrap().push("inner");
});
assert!(execution_order.lock().unwrap().is_empty());
}
assert_eq!(*execution_order.lock().unwrap(), vec!["inner"]);
}
assert_eq!(*execution_order.lock().unwrap(), vec!["inner", "outer"]);
}
#[test]
fn test_defer_with_complex_closure() {
let results = Arc::new(Mutex::new(Vec::new()));
{
let results_clone = results.clone();
let _defer = defer(move || {
let mut guard = results_clone.lock().unwrap();
for i in 1..=3 {
guard.push(i * i);
}
});
assert!(results.lock().unwrap().is_empty());
}
assert_eq!(*results.lock().unwrap(), vec![1, 4, 9]);
}
#[test]
fn test_defer_macro_with_multiple_statements() {
let values = Arc::new(Mutex::new(Vec::new()));
let values_clone = values.clone();
{
defer!({
let mut guard = values_clone.lock().unwrap();
guard.push(1);
guard.push(2);
guard.push(3);
});
assert!(values.lock().unwrap().is_empty());
}
assert_eq!(*values.lock().unwrap(), vec![1, 2, 3]);
}
#[test]
fn test_defer_multiple_times_same_scope() {
let counter = Arc::new(Mutex::new(0));
{
let _defer0 = {
let counter_clone = counter.clone();
defer(move || {
*counter_clone.lock().unwrap() += 0;
})
};
let _defer1 = {
let counter_clone = counter.clone();
defer(move || {
*counter_clone.lock().unwrap() += 1;
})
};
let _defer2 = {
let counter_clone = counter.clone();
defer(move || {
*counter_clone.lock().unwrap() += 2;
})
};
let _defer3 = {
let counter_clone = counter.clone();
defer(move || {
*counter_clone.lock().unwrap() += 3;
})
};
let _defer4 = {
let counter_clone = counter.clone();
defer(move || {
*counter_clone.lock().unwrap() += 4;
})
};
assert_eq!(*counter.lock().unwrap(), 0);
}
assert_eq!(*counter.lock().unwrap(), 10);
}