#![cfg(all(test, full_widgets))]
use crate::core::Rect;
#[test]
fn documented_widget_creation_path_compiles_and_runs() {
use crate::widget::WidgetFactory;
let factory = WidgetFactory::new_with_defaults();
let mut button = factory
.create("button", Rect::new(10, 10, 100, 30), "OK")
.expect("button is a registered widget kind");
factory
.write_property(button.as_mut(), "text", crate::CapabilityValue::String("Save".into()))
.expect("text is writable on a button");
let text = factory.read_property(button.as_ref(), "text").expect("text is readable");
assert_eq!(text, crate::CapabilityValue::String("Save".into()));
}
#[test]
fn documented_property_enumeration_paths_resolve() {
use crate::widget::{
widget_property_get, widget_property_names, widget_property_set, WidgetFactory,
};
let factory = WidgetFactory::new_with_defaults();
let mut widget =
factory.create("button", Rect::new(0, 0, 80, 24), "x").expect("button is registered");
let names = widget_property_names(widget.as_ref()).expect("migrated control has a contract");
assert!(
names.contains(&"enabled"),
"the shared four must be published, so a property editor sees them"
);
for name in names {
widget_property_get(widget.as_ref(), name)
.unwrap_or_else(|err| panic!("published {name:?} must be readable, got {err:?}"));
}
widget_property_set(widget.as_mut(), "enabled", crate::CapabilityValue::Bool(false))
.expect("enabled is writable");
}
#[test]
fn documented_id_level_accessors_resolve() {
use crate::widget::{read_widget_property_by_id, write_widget_property_by_id, WidgetFactory};
let factory = WidgetFactory::new_with_defaults();
let widget =
factory.create("slider", Rect::new(0, 0, 120, 24), "").expect("slider is registered");
let factory_id = widget.id();
assert_eq!(
read_widget_property_by_id(factory_id, "value"),
Err(crate::CapabilityAccessError::UnknownWidget)
);
let id = crate::widget::runtime::register(widget)
.expect("registering on the UI thread must succeed");
write_widget_property_by_id(id, "value", crate::CapabilityValue::Int(7))
.expect("slider value is writable by id once registered");
let value = read_widget_property_by_id(id, "value").expect("slider value is readable by id");
assert_eq!(value, crate::CapabilityValue::Int(7));
assert!(crate::widget::runtime::unregister(id), "the registered id must unregister");
}
#[test]
fn documented_readme_property_section_compiles() {
use crate::widget::{widget_property_get, widget_property_names, WidgetFactory};
use crate::CapabilityValue;
let factory = WidgetFactory::new_with_defaults();
let mut button = factory.create("button", Rect::new(10, 10, 100, 30), "OK").unwrap();
factory
.write_property(button.as_mut(), "text", CapabilityValue::String("Save".into()))
.unwrap();
let text = factory.read_property(button.as_ref(), "text").unwrap();
assert_eq!(text, CapabilityValue::String("Save".into()));
let names: Vec<&str> = widget_property_names(button.as_ref()).unwrap().to_vec();
assert!(names.contains(&"enabled"), "the shared four must appear");
assert!(names.contains(&"visible"));
assert!(names.contains(&"tooltip"));
assert!(names.contains(&"geometry"));
for name in &names {
widget_property_get(button.as_ref(), name)
.unwrap_or_else(|err| panic!("{name} must be readable, got {err:?}"));
}
}
#[test]
fn documented_error_semantics_hold() {
use crate::widget::WidgetFactory;
use crate::{CapabilityAccessError, CapabilityValue};
let factory = WidgetFactory::new_with_defaults();
let mut widget = factory.create("button", Rect::new(0, 0, 80, 24), "x").unwrap();
assert_eq!(
factory.read_property(widget.as_ref(), "definitely_not_a_property"),
Err(CapabilityAccessError::UnknownProperty)
);
assert_eq!(
factory.write_property(
widget.as_mut(),
"geometry",
CapabilityValue::String("1,2,3,4".into())
),
Err(CapabilityAccessError::ReadOnlyProperty)
);
assert_eq!(
factory.write_property(widget.as_mut(), "text", crate::CapabilityValue::Bool(true)),
Err(CapabilityAccessError::TypeMismatch)
);
}
#[test]
fn published_os_capability_matrix_matches_the_trait_default() {
use crate::core::PlatformFamily;
use crate::platform::{default_capabilities_for, PlatformCapabilities};
let documented: &[(&str, PlatformFamily, bool, bool, bool, bool)] = &[
("windows", PlatformFamily::Desktop, true, true, true, true),
("macos", PlatformFamily::Desktop, true, true, true, true),
("linux-gtk", PlatformFamily::Desktop, true, true, true, true),
("wayland", PlatformFamily::Desktop, true, true, true, false),
("ios", PlatformFamily::Mobile, true, true, true, false),
("android", PlatformFamily::Mobile, true, true, true, false),
("harmony", PlatformFamily::Desktop, true, true, true, false),
("wasm", PlatformFamily::Embedded, false, false, false, false),
("portable", PlatformFamily::Embedded, false, false, false, false),
];
let documented_overrides: &[&str] = &["wayland", "ios", "android", "harmony"];
for (name, family, dpi, ime, a11y, menu) in documented {
let expected = if documented_overrides.contains(name) {
assert!(
!menu,
"{name} overrides capabilities(); its documented native_menu must be the \
override's value, not the Desktop default"
);
PlatformCapabilities {
dpi_scaling: *dpi,
ime: *ime,
accessibility: *a11y,
native_menu: *menu,
typed_widget_trigger: true,
}
} else {
default_capabilities_for(*family)
};
assert_eq!(
(expected.dpi_scaling, expected.ime, expected.accessibility, expected.native_menu),
(*dpi, *ime, *a11y, *menu),
"the published row for {name} must match what a {family:?} backend reports"
);
assert!(
expected.typed_widget_trigger,
"{name}: typed triggers are implemented by the library, not the host"
);
}
let desktop_default = default_capabilities_for(PlatformFamily::Desktop);
assert!(
desktop_default.native_menu,
"the trait default must give Desktop native_menu, which is why the README must \
record the overrides rather than assume `false`"
);
let embedded_default = default_capabilities_for(PlatformFamily::Embedded);
assert_eq!(
(
embedded_default.dpi_scaling,
embedded_default.ime,
embedded_default.accessibility,
embedded_default.native_menu
),
(false, false, false, false),
"an Embedded-family backend must report no host capabilities"
);
}
#[test]
fn documented_capability_fields_exist() {
use crate::platform::PlatformCapabilities;
let caps = PlatformCapabilities {
dpi_scaling: true,
ime: true,
accessibility: true,
native_menu: false,
typed_widget_trigger: true,
};
assert!(caps.dpi_scaling && caps.ime && caps.accessibility && caps.typed_widget_trigger);
assert!(!caps.native_menu);
let alias: crate::platform::NativeCapabilityContract = caps;
assert_eq!(alias, caps, "the alias and the source must be the same type");
}
#[cfg(feature = "image")]
#[test]
fn documented_image_reexport_is_reachable() {
fn takes_image(_: crate::image::Image) {}
fn takes_format(_: crate::image::ImageFormat) {}
let _ = takes_image as fn(crate::image::Image);
let _ = takes_format as fn(crate::image::ImageFormat);
let _ = crate::widget::Image::default;
}
#[cfg(feature = "desktop")]
#[test]
fn documented_asset_paths_are_reachable() {
fn takes_watcher(_: &dyn Fn()) {}
let _ = takes_watcher;
let _ = std::marker::PhantomData::<crate::asset::AssetWatcher>;
let _ = std::marker::PhantomData::<crate::asset::AssetEvent>;
}