#![cfg(all(feature = "desktop", not(alloc_frugal)))]
use rust_widgets::core::Rect;
use rust_widgets::widget::capability::WidgetFactory;
use std::collections::HashMap;
fn normalize_key(value: &str) -> String {
value
.chars()
.filter(|ch| !matches!(*ch, '_' | '-' | ' '))
.flat_map(char::to_lowercase)
.collect()
}
#[test]
fn no_alias_is_inert_under_normalisation() {
let factory = WidgetFactory::new_with_defaults();
let mut inert: Vec<(&str, &str)> = Vec::new();
for capability in factory.capabilities() {
for alias in capability.aliases {
if normalize_key(alias) == normalize_key(capability.canonical_name) {
inert.push((capability.canonical_name, alias));
}
}
}
assert!(
inert.is_empty(),
"these aliases normalise to their own canonical name, so `normalize_key` already \
reached them and the row changes nothing — it only inflates the published alias \
list and hides the aliases that carry information (control, alias): {inert:?}"
);
}
#[test]
fn no_name_shadows_another_control() {
let factory = WidgetFactory::new_with_defaults();
let mut claims: HashMap<String, Vec<(&str, &str)>> = HashMap::new();
for capability in factory.capabilities() {
claims
.entry(normalize_key(capability.canonical_name))
.or_default()
.push(("canonical", capability.canonical_name));
for alias in capability.aliases {
claims
.entry(normalize_key(alias))
.or_default()
.push((alias, capability.canonical_name));
}
}
let mut shadowed: Vec<(String, Vec<(&str, &str)>)> = Vec::new();
for (key, entries) in claims {
let owners: std::collections::HashSet<&str> = entries.iter().map(|e| e.1).collect();
if owners.len() > 1 {
shadowed.push((key, entries));
}
}
shadowed.sort_by(|a, b| a.0.cmp(&b.0));
assert!(
shadowed.is_empty(),
"these names are claimed by more than one capability, so asking for the name \
answers by registration order rather than by meaning (key, claimants): {shadowed:?}"
);
}
#[test]
fn every_declared_alias_resolves_and_constructs() {
let factory = WidgetFactory::new_with_defaults();
let mut unresolved: Vec<(&str, &str)> = Vec::new();
let mut unconstructible: Vec<(&str, &str)> = Vec::new();
for capability in factory.capabilities() {
for alias in capability.aliases {
match factory.capability(alias) {
Some(resolved) if resolved.canonical_name == capability.canonical_name => {}
_ => {
unresolved.push((capability.canonical_name, alias));
continue;
}
}
if factory.create(alias, Rect::new(0, 0, 32, 32), "").is_none() {
unconstructible.push((capability.canonical_name, alias));
}
}
}
assert!(
unresolved.is_empty(),
"a capability advertises aliases the factory does not resolve back to it \
(control, alias): {unresolved:?}"
);
assert!(
unconstructible.is_empty(),
"a capability advertises aliases that construct nothing (control, alias): \
{unconstructible:?}"
);
}