#![cfg(all(
any(feature = "desktop", feature = "tablet", feature = "mobile"),
not(any(feature = "mini", feature = "embedded"))
))]
use rust_widgets::core::{ObjectId, Orientation, Rect};
use rust_widgets::widget::{runtime, WidgetFactory};
fn mount(kind: &str, text: &str) -> ObjectId {
let factory = WidgetFactory::new_with_defaults();
let widget = factory
.create(kind, Rect::new(0, 0, 120, 30), text)
.unwrap_or_else(|| panic!("{kind} must be a registered control"));
runtime::register(widget).unwrap_or_else(|| panic!("{kind} must register on the UI thread"))
}
#[test]
fn label_text_round_trips_through_the_accessor() {
let id = mount("label", "hello");
assert_eq!(rust_widgets::get_widget_text(id), "hello");
rust_widgets::set_widget_text(id, "world");
assert_eq!(rust_widgets::get_widget_text(id), "world");
}
#[test]
fn visibility_and_enabled_round_trip_through_the_accessors() {
let id = mount("button", "ok");
assert!(rust_widgets::is_widget_visible(id));
rust_widgets::hide_widget(id);
assert!(!rust_widgets::is_widget_visible(id));
rust_widgets::show_widget(id);
assert!(rust_widgets::is_widget_visible(id));
assert!(rust_widgets::is_widget_enabled(id));
rust_widgets::set_widget_enabled(id, false);
assert!(!rust_widgets::is_widget_enabled(id));
}
#[test]
fn geometry_returns_to_the_control() {
let id = mount("label", "x");
rust_widgets::set_widget_geometry(id, 10, 20, 80, 24);
assert_eq!(
rust_widgets::widget_geometry(id),
Some((10, 20, 80, 24)),
"the accessor must read back the rectangle it just wrote"
);
}
#[test]
fn slider_value_range_step_and_orientation_round_trip() {
let id = mount("slider", "");
assert!(rust_widgets::set_widget_range(id, 0.0, 100.0), "range must be writable");
assert_eq!(rust_widgets::widget_range(id), Some((0.0, 100.0)));
assert!(rust_widgets::set_widget_value(id, 42.0), "value must be writable");
assert_eq!(rust_widgets::widget_value(id), Some(42.0));
assert!(rust_widgets::set_widget_step(id, 5.0), "step must be writable");
assert_eq!(rust_widgets::widget_step(id), Some(5.0));
assert!(
rust_widgets::set_slider_orientation(id, Orientation::Vertical),
"orientation must be writable"
);
assert_eq!(rust_widgets::slider_orientation(id), Some(Orientation::Vertical));
}
#[test]
fn progress_bar_value_round_trips() {
let id = mount("progress_bar", "");
assert!(rust_widgets::set_widget_value(id, 25.0));
assert_eq!(rust_widgets::widget_value(id), Some(25.0));
}
#[test]
fn spin_box_value_and_step_round_trip() {
let id = mount("spin_box", "");
assert!(rust_widgets::set_widget_value(id, 7.0));
assert_eq!(rust_widgets::widget_value(id), Some(7.0));
assert!(rust_widgets::set_widget_step(id, 2.0));
assert_eq!(rust_widgets::widget_step(id), Some(2.0));
}
#[test]
fn numeric_accessors_refuse_a_control_without_a_value() {
let id = mount("label", "x");
assert!(!rust_widgets::set_widget_value(id, 1.0));
assert_eq!(rust_widgets::widget_value(id), None);
}
#[test]
fn accessors_refuse_an_unknown_id() {
let unknown = 0xdead_beef_u64;
assert!(!rust_widgets::set_widget_value(unknown, 1.0));
assert_eq!(rust_widgets::widget_value(unknown), None);
assert!(!rust_widgets::set_widget_checked(unknown, true));
assert_eq!(rust_widgets::is_widget_checked(unknown), None);
assert_eq!(rust_widgets::get_widget_text(unknown), "");
}
#[test]
fn checkbox_checked_and_tristate_round_trip() {
let id = mount("checkbox", "cb");
assert_eq!(rust_widgets::is_widget_checked(id), Some(false));
assert!(rust_widgets::set_widget_checked(id, true));
assert_eq!(rust_widgets::is_widget_checked(id), Some(true));
assert_eq!(rust_widgets::is_widget_tristate(id), Some(false));
assert!(rust_widgets::set_widget_tristate(id, true));
assert_eq!(rust_widgets::is_widget_tristate(id), Some(true));
}
#[test]
fn radio_button_group_round_trips() {
let id = mount("radio_button", "r");
assert!(rust_widgets::set_widget_group(id, "size"));
assert_eq!(rust_widgets::widget_group(id), Some("size".to_string()));
assert!(rust_widgets::set_widget_group(id, ""));
assert_eq!(rust_widgets::widget_group(id), None, "an empty group clears the membership");
}
#[test]
fn checkable_accessors_refuse_a_non_checkable_control() {
let id = mount("label", "x");
assert!(!rust_widgets::set_widget_checked(id, true));
assert_eq!(rust_widgets::is_widget_checked(id), None);
assert_eq!(rust_widgets::is_widget_tristate(id), None);
}
#[test]
fn line_edit_read_only_placeholder_and_max_length_round_trip() {
let id = mount("line_edit", "");
assert_eq!(rust_widgets::is_widget_read_only(id), Some(false));
assert!(rust_widgets::set_widget_read_only(id, true));
assert_eq!(rust_widgets::is_widget_read_only(id), Some(true));
assert!(rust_widgets::set_widget_placeholder(id, "type here"));
assert_eq!(rust_widgets::widget_placeholder(id), Some("type here".to_string()));
assert!(rust_widgets::set_widget_max_length(id, 12));
assert_eq!(rust_widgets::widget_max_length(id), Some(12));
}
#[test]
fn scroll_area_position_is_accepted_and_clamped_by_the_control() {
let id = mount("scroll_area", "");
assert!(rust_widgets::set_widget_scroll_position(id, 5, 9));
assert_eq!(rust_widgets::widget_scroll_position(id), Some((0, 0)));
}
#[test]
fn combo_box_item_operations_round_trip() {
let id = mount("combo_box", "");
assert!(rust_widgets::combo_box_add_item(id, "alpha"));
assert!(rust_widgets::combo_box_add_item(id, "beta"));
assert_eq!(rust_widgets::combo_box_item_count(id), 2);
assert_eq!(rust_widgets::combo_box_item_text(id, 1), Some("beta".to_string()));
assert!(rust_widgets::combo_box_set_current_index(id, 1));
assert_eq!(rust_widgets::combo_box_current_index(id), Some(1));
assert!(rust_widgets::combo_box_clear_items(id));
assert_eq!(rust_widgets::combo_box_item_count(id), 0);
}
#[test]
fn list_box_item_operations_round_trip() {
let id = mount("list_box", "");
assert!(rust_widgets::list_box_add_item(id, "one"));
assert!(rust_widgets::list_box_add_item(id, "two"));
assert_eq!(rust_widgets::list_box_item_count(id), 2);
assert_eq!(rust_widgets::list_box_item_text(id, 0), Some("one".to_string()));
assert!(rust_widgets::list_box_set_current_index(id, 1));
assert_eq!(rust_widgets::list_box_current_index(id), Some(1));
assert!(rust_widgets::list_box_remove_item(id, 0));
assert_eq!(rust_widgets::list_box_item_count(id), 1);
assert_eq!(rust_widgets::list_box_item_text(id, 0), Some("two".to_string()));
assert!(!rust_widgets::list_box_remove_item(id, 9));
assert!(rust_widgets::list_box_clear_items(id));
assert_eq!(rust_widgets::list_box_item_count(id), 0);
}
#[test]
fn item_operations_refuse_a_control_without_items() {
let id = mount("label", "x");
assert!(!rust_widgets::combo_box_add_item(id, "alpha"));
assert!(!rust_widgets::list_box_add_item(id, "alpha"));
assert_eq!(rust_widgets::combo_box_item_text(id, 0), None);
}
#[test]
fn item_count_matches_the_published_property() {
let id = mount("list_box", "");
rust_widgets::list_box_add_item(id, "only");
let published = rust_widgets::read_widget_property_by_id(id, "item_count");
assert_eq!(published, Ok(rust_widgets::widget::capability::CapabilityValue::UInt(1)));
}
#[test]
fn selection_index_round_trips_and_can_be_cleared() {
let id = mount("combo_box", "");
rust_widgets::combo_box_add_item(id, "alpha");
rust_widgets::combo_box_add_item(id, "beta");
assert!(rust_widgets::set_widget_selected_index(id, Some(1)));
assert_eq!(rust_widgets::widget_selected_index(id), Some(1));
assert!(
rust_widgets::set_widget_selected_index(id, None),
"clearing the selection must be accepted"
);
assert_eq!(
rust_widgets::widget_selected_index(id),
None,
"a cleared selection reads as no selection, not as index 0"
);
}
#[test]
fn trigger_queue_is_shared_between_its_two_readers() {
let id = mount("button", "ok");
assert!(rust_widgets::inject_widget_trigger_event(
id,
rust_widgets::WidgetTriggerKind::Clicked
));
assert_eq!(
rust_widgets::poll_widget_triggered(),
Some(id),
"the id-level reader must see the injected event"
);
assert_eq!(
rust_widgets::poll_widget_triggered(),
None,
"an answered event is consumed, so the queue does not repeat it"
);
}
#[test]
fn native_handle_reports_the_host_window_handle() {
rust_widgets::init();
let platform = rust_widgets::platform::get_platform();
let host = platform.create_window("handle probe", 0, 0, 200, 120);
assert_ne!(host, 0, "the host must create a window");
for probe in [host, 0xdead_beef_u64] {
assert_eq!(
rust_widgets::native_handle(probe),
platform.get_native_handle(probe),
"the accessor and the backend must agree for id {probe:#x}"
);
}
assert_eq!(
rust_widgets::native_handle(0xdead_beef_u64),
None,
"an id that addresses nothing must not produce a handle"
);
}
#[test]
fn menu_entries_are_addressable_and_round_trip() {
let window = mount("window", "w");
let menu_bar = rust_widgets::create_menu_bar(window, 0, 0, 200, 20);
assert_ne!(menu_bar, 0, "a menu bar must be creatable under the window");
assert!(
rust_widgets::attach_menu_bar_to_window(window, menu_bar),
"attaching a real menu bar to a real window must succeed"
);
let menu = rust_widgets::create_menu(menu_bar, "file", 0, 0, 100, 20);
assert_ne!(menu, 0, "a menu must be creatable under the menu bar");
let open = rust_widgets::menu_add_item(menu, "open", Some("Ctrl+O"));
assert_ne!(
open, 0,
"a menu entry must be addressable by the id it returns, not return a fixed sentinel"
);
let second = rust_widgets::menu_add_item(menu, "save", Some("Ctrl+S"));
assert_ne!(second, open, "each entry must get its own id");
assert_eq!(rust_widgets::menu_item_shortcut(open), Some("Ctrl+O".to_string()));
assert_eq!(rust_widgets::menu_item_shortcut(second), Some("Ctrl+S".to_string()));
assert_eq!(rust_widgets::menu_item_shortcut(0xdead_beef_u64), None);
assert!(rust_widgets::inject_menu_trigger(open));
assert_eq!(rust_widgets::poll_menu_triggered(), Some(open));
}
#[test]
fn attach_menu_bar_refuses_unknown_ids() {
assert!(!rust_widgets::attach_menu_bar_to_window(0xdead_beef_u64, 0xdead_beee_u64));
let window = mount("window", "w");
assert!(!rust_widgets::attach_menu_bar_to_window(window, 0xdead_beee_u64));
}
#[test]
fn echo_mode_reports_unsupported_until_a_control_publishes_it() {
let id = mount("line_edit", "");
assert!(
!rust_widgets::set_widget_echo_mode(id, rust_widgets::platform::EchoMode::Password),
"no control publishes `echo_mode` yet, so the write must be reported as refused"
);
assert_eq!(rust_widgets::widget_echo_mode(id), None);
}
#[test]
fn selection_range_reports_unsupported_until_a_control_publishes_it() {
let id = mount("line_edit", "");
assert!(
!rust_widgets::set_widget_selection(id, 0, 3),
"no control publishes `selection` yet, so the write must be reported as refused"
);
assert_eq!(rust_widgets::widget_selection(id), None);
}