use hypen_engine::ir::NodeId;
use hypen_engine::lifecycle::component::{ComponentLifecycle, ComponentLifecycleEvent};
use std::sync::{Arc, Mutex};
fn test_node_id() -> NodeId {
NodeId::default()
}
#[test]
fn test_lifecycle_new() {
let lifecycle = ComponentLifecycle::new();
let node_id = test_node_id();
lifecycle.notify_mounted(node_id);
lifecycle.notify_unmounted(node_id);
}
#[test]
fn test_notify_mounted_calls_callback() {
let mut lifecycle = ComponentLifecycle::new();
let events = Arc::new(Mutex::new(Vec::new()));
let events_clone = Arc::clone(&events);
lifecycle.on(move |node_id, event| {
events_clone.lock().unwrap().push((node_id, event));
});
let node_id = test_node_id();
lifecycle.notify_mounted(node_id);
let captured_events = events.lock().unwrap();
assert_eq!(captured_events.len(), 1);
assert_eq!(captured_events[0].1, ComponentLifecycleEvent::Mounted);
}
#[test]
fn test_notify_unmounted_calls_callback() {
let mut lifecycle = ComponentLifecycle::new();
let events = Arc::new(Mutex::new(Vec::new()));
let events_clone = Arc::clone(&events);
lifecycle.on(move |node_id, event| {
events_clone.lock().unwrap().push((node_id, event));
});
let node_id = test_node_id();
lifecycle.notify_unmounted(node_id);
let captured_events = events.lock().unwrap();
assert_eq!(captured_events.len(), 1);
assert_eq!(captured_events[0].1, ComponentLifecycleEvent::Unmounted);
}
#[test]
fn test_lifecycle_events_sequence() {
let mut lifecycle = ComponentLifecycle::new();
let events = Arc::new(Mutex::new(Vec::new()));
let events_clone = Arc::clone(&events);
lifecycle.on(move |_node_id, event| {
events_clone.lock().unwrap().push(event);
});
let node_id = test_node_id();
lifecycle.notify_mounted(node_id);
lifecycle.notify_unmounted(node_id);
let captured_events = events.lock().unwrap();
assert_eq!(captured_events.len(), 2);
assert_eq!(captured_events[0], ComponentLifecycleEvent::Mounted);
assert_eq!(captured_events[1], ComponentLifecycleEvent::Unmounted);
}
#[test]
fn test_lifecycle_default() {
let lifecycle = ComponentLifecycle::default();
let node_id = test_node_id();
lifecycle.notify_mounted(node_id);
}
#[test]
fn test_callback_registration_replaces_previous() {
let mut lifecycle = ComponentLifecycle::new();
let first_called = Arc::new(Mutex::new(false));
let second_called = Arc::new(Mutex::new(false));
let first_clone = Arc::clone(&first_called);
lifecycle.on(move |_node_id, _event| {
*first_clone.lock().unwrap() = true;
});
let second_clone = Arc::clone(&second_called);
lifecycle.on(move |_node_id, _event| {
*second_clone.lock().unwrap() = true;
});
let node_id = test_node_id();
lifecycle.notify_mounted(node_id);
assert!(!(*first_called.lock().unwrap()));
assert!(*second_called.lock().unwrap());
}
#[test]
fn test_callback_receives_correct_node_id() {
let mut lifecycle = ComponentLifecycle::new();
let captured_id = Arc::new(Mutex::new(None));
let captured_id_clone = Arc::clone(&captured_id);
lifecycle.on(move |node_id, _event| {
*captured_id_clone.lock().unwrap() = Some(node_id);
});
let node_id = test_node_id();
lifecycle.notify_mounted(node_id);
let received_id = captured_id.lock().unwrap().unwrap();
assert_eq!(format!("{:?}", received_id), format!("{:?}", node_id));
}
#[test]
fn test_callback_with_multiple_nodes() {
let mut lifecycle = ComponentLifecycle::new();
let events = Arc::new(Mutex::new(Vec::new()));
let events_clone = Arc::clone(&events);
lifecycle.on(move |node_id, event| {
events_clone.lock().unwrap().push((node_id, event));
});
let node1 = test_node_id();
let node2 = test_node_id();
let node3 = test_node_id();
lifecycle.notify_mounted(node1);
lifecycle.notify_mounted(node2);
lifecycle.notify_unmounted(node1);
lifecycle.notify_mounted(node3);
let captured_events = events.lock().unwrap();
assert_eq!(captured_events.len(), 4);
assert_eq!(captured_events[0].1, ComponentLifecycleEvent::Mounted);
assert_eq!(captured_events[1].1, ComponentLifecycleEvent::Mounted);
assert_eq!(captured_events[2].1, ComponentLifecycleEvent::Unmounted);
assert_eq!(captured_events[3].1, ComponentLifecycleEvent::Mounted);
}
#[test]
fn test_callback_can_be_stateful() {
let mut lifecycle = ComponentLifecycle::new();
let mount_count = Arc::new(Mutex::new(0));
let unmount_count = Arc::new(Mutex::new(0));
let mount_clone = Arc::clone(&mount_count);
let unmount_clone = Arc::clone(&unmount_count);
lifecycle.on(move |_node_id, event| match event {
ComponentLifecycleEvent::Mounted => {
*mount_clone.lock().unwrap() += 1;
}
ComponentLifecycleEvent::Unmounted => {
*unmount_clone.lock().unwrap() += 1;
}
});
let node_id = test_node_id();
lifecycle.notify_mounted(node_id);
lifecycle.notify_unmounted(node_id);
lifecycle.notify_mounted(node_id);
lifecycle.notify_unmounted(node_id);
lifecycle.notify_mounted(node_id);
assert_eq!(*mount_count.lock().unwrap(), 3);
assert_eq!(*unmount_count.lock().unwrap(), 2);
}
#[test]
fn test_callback_without_registration_does_nothing() {
let lifecycle = ComponentLifecycle::new();
let node_id = test_node_id();
lifecycle.notify_mounted(node_id);
lifecycle.notify_unmounted(node_id);
}
#[test]
fn test_lifecycle_event_equality() {
let mounted1 = ComponentLifecycleEvent::Mounted;
let mounted2 = ComponentLifecycleEvent::Mounted;
let unmounted = ComponentLifecycleEvent::Unmounted;
assert_eq!(mounted1, mounted2);
assert_ne!(mounted1, unmounted);
}
#[test]
fn test_lifecycle_event_clone() {
let event = ComponentLifecycleEvent::Mounted;
let cloned = event;
assert_eq!(event, cloned);
}
#[test]
fn test_lifecycle_event_copy() {
let event = ComponentLifecycleEvent::Unmounted;
let copied = event;
assert_eq!(event, copied);
assert_eq!(event, ComponentLifecycleEvent::Unmounted);
}