#![cfg(all(feature = "desktop", not(alloc_frugal)))]
use rust_widgets::core::Rect;
use rust_widgets::signal::CustomSignalHub;
use rust_widgets::widget::capability::WidgetFactory;
#[test]
fn every_published_event_name_is_subscribable() {
let factory = WidgetFactory::new_with_defaults();
let hub = CustomSignalHub::new();
let mut total = 0usize;
let mut refused: Vec<(&str, &str)> = Vec::new();
for capability in factory.capabilities() {
for event in capability.events {
total += 1;
if factory.event_is_subscribable(capability.canonical_name, event, &hub).is_err() {
refused.push((capability.canonical_name, event));
}
}
}
assert!(
total > 0,
"no capability publishes events, so this test proves nothing — the schema field or its \
wiring has stopped reaching the property layer"
);
assert!(
refused.is_empty(),
"a capability publishes events no consumer can subscribe to, so the published list is \
inert data (control, event): {refused:?}"
);
}
#[test]
fn an_unpublished_event_name_is_refused() {
let factory = WidgetFactory::new_with_defaults();
let hub = CustomSignalHub::new();
assert!(
factory.event_is_subscribable("button", "clicked", &hub).is_ok(),
"button publishes `clicked`, so the bridge must accept it"
);
assert!(
factory.event_is_subscribable("button", "definitely_not_an_event", &hub).is_err(),
"the bridge accepted an event name the control does not publish, so a subscriber \
would wait for a signal that can never fire"
);
assert!(
factory.event_is_subscribable("button", "selection_changed", &hub).is_err(),
"the bridge accepted an event another control publishes, so the check is looking \
at the wrong list"
);
}
#[test]
fn an_unknown_control_has_no_events() {
let factory = WidgetFactory::new_with_defaults();
let hub = CustomSignalHub::new();
assert!(
factory.event_is_subscribable("no_such_control", "clicked", &hub).is_err(),
"an unknown control name was accepted, so the bridge is not resolving the control"
);
let _ = Rect::new(0, 0, 1, 1);
}
#[test]
fn a_published_event_subscription_actually_delivers() {
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
let factory = WidgetFactory::new_with_defaults();
let hub = CustomSignalHub::new();
let delivered = Arc::new(AtomicUsize::new(0));
let counter = Arc::clone(&delivered);
factory
.connect_event("list_box", "selection_changed", &hub, move || {
counter.fetch_add(1, Ordering::SeqCst);
})
.expect("list_box publishes `selection_changed`");
assert_eq!(delivered.load(Ordering::SeqCst), 0, "the slot must not run before an emit");
hub.emit("selection_changed");
assert_eq!(
delivered.load(Ordering::SeqCst),
1,
"an event subscribed to through its published name did not receive the emit, so the \
bridge validated the name without connecting the slot"
);
}
#[test]
fn a_published_event_with_a_payload_is_reachable_by_name() {
let factory = WidgetFactory::new_with_defaults();
let hub = CustomSignalHub::new();
assert!(
factory.event_is_subscribable("slider", "value_changed", &hub).is_ok(),
"a payload-carrying event published by `slider` was not accepted by the bridge"
);
assert!(
factory.connect_event("slider", "value_changed", &hub, || {}).is_ok(),
"the payload-carrying event could be probed but not subscribed to"
);
}