♻️ (html): API para id's en Props y componentes
This commit is contained in:
parent
8d0103c257
commit
62219584b0
31 changed files with 541 additions and 405 deletions
|
|
@ -7,7 +7,7 @@ use pagetop::prelude::*;
|
|||
|
||||
#[derive(AutoDefault, Clone)]
|
||||
struct TestComp {
|
||||
id: AttrId,
|
||||
props: Props,
|
||||
text: String,
|
||||
}
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ impl Component for TestComp {
|
|||
}
|
||||
|
||||
fn id(&self) -> Option<String> {
|
||||
self.id.get()
|
||||
self.props.get_id()
|
||||
}
|
||||
|
||||
fn prepare(&self, _cx: &mut Context) -> Result<Markup, ComponentError> {
|
||||
|
|
@ -29,7 +29,7 @@ impl TestComp {
|
|||
/// Crea un componente con id y texto de salida fijos.
|
||||
fn tagged(id: &str, text: &str) -> Self {
|
||||
let mut c = Self::default();
|
||||
c.id.alter_id(id);
|
||||
c.props.alter_prop(PropsOp::set_id(id.to_string()));
|
||||
c.text = text.to_string();
|
||||
c
|
||||
}
|
||||
|
|
@ -303,7 +303,8 @@ async fn embed_get_allows_mutating_component() {
|
|||
let embed = Embed::with(TestComp::tagged("orig", "texto"));
|
||||
// El `;` final convierte el `if let` en sentencia y libera el guard antes que `embed`.
|
||||
if let Some(mut comp) = embed.get() {
|
||||
comp.id.alter_id("modificado");
|
||||
comp.props
|
||||
.alter_prop(PropsOp::set_id("modificado".to_string()));
|
||||
};
|
||||
assert_eq!(embed.id(), Some("modificado".to_string()));
|
||||
}
|
||||
|
|
@ -331,7 +332,8 @@ async fn embed_clone_is_deep() {
|
|||
let clone = original.clone();
|
||||
// Mutar el clon no debe afectar al original.
|
||||
if let Some(mut comp) = clone.get() {
|
||||
comp.id.alter_id("clone-id");
|
||||
comp.props
|
||||
.alter_prop(PropsOp::set_id("clone-id".to_string()));
|
||||
}
|
||||
assert_eq!(original.id(), Some("orig".to_string()));
|
||||
assert_eq!(clone.id(), Some("clone-id".to_string()));
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ async fn props_default_renders_nothing() {
|
|||
#[pagetop::test]
|
||||
async fn props_new_creates_first_attr() {
|
||||
let p = Props::new("hx-get", "/api");
|
||||
assert_eq!(p.get_prop("hx-get"), Some("/api"));
|
||||
assert_eq!(p.get_prop("hx-get"), Some("/api".to_string()));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
|
|
@ -59,14 +59,14 @@ async fn props_set_adds_new_attrs() {
|
|||
let p = Props::default()
|
||||
.with_prop(PropsOp::set("hx-get", "/api"))
|
||||
.with_prop(PropsOp::set("hx-swap", "outerHTML"));
|
||||
assert_eq!(p.get_prop("hx-get"), Some("/api"));
|
||||
assert_eq!(p.get_prop("hx-swap"), Some("outerHTML"));
|
||||
assert_eq!(p.get_prop("hx-get"), Some("/api".to_string()));
|
||||
assert_eq!(p.get_prop("hx-swap"), Some("outerHTML".to_string()));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn props_set_replaces_existing_value() {
|
||||
let p = Props::new("hx-get", "/old").with_prop(PropsOp::set("hx-get", "/new"));
|
||||
assert_eq!(p.get_prop("hx-get"), Some("/new"));
|
||||
assert_eq!(p.get_prop("hx-get"), Some("/new".to_string()));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
|
|
@ -98,13 +98,13 @@ async fn props_remove_existing_attr() {
|
|||
.with_prop(PropsOp::set("b", "2"))
|
||||
.with_prop(PropsOp::remove("a"));
|
||||
assert_eq!(p.get_prop("a"), None);
|
||||
assert_eq!(p.get_prop("b"), Some("2"));
|
||||
assert_eq!(p.get_prop("b"), Some("2".to_string()));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn props_remove_nonexistent_key_is_noop() {
|
||||
let p = Props::new("a", "1").with_prop(PropsOp::remove("missing"));
|
||||
assert_eq!(p.get_prop("a"), Some("1"));
|
||||
assert_eq!(p.get_prop("a"), Some("1".to_string()));
|
||||
assert_eq!(p.get_prop("missing"), None);
|
||||
}
|
||||
|
||||
|
|
@ -222,22 +222,42 @@ async fn props_splice_empty_string_emits_nothing() {
|
|||
assert_eq!(html! { span ("") { "x" } }.into_string(), "<span>x</span>");
|
||||
}
|
||||
|
||||
// **< is_props_empty / is_classes_empty >**********************************************************
|
||||
// **< is_attrs_empty / is_classes_empty / is_empty >***********************************************
|
||||
|
||||
#[pagetop::test]
|
||||
async fn props_is_props_empty_on_default() {
|
||||
assert!(Props::default().is_props_empty());
|
||||
async fn props_is_attrs_empty_on_default() {
|
||||
assert!(Props::default().is_attrs_empty());
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn props_is_props_empty_false_after_set() {
|
||||
assert!(!Props::new("hx-get", "/api").is_props_empty());
|
||||
async fn props_is_attrs_empty_false_after_set() {
|
||||
assert!(!Props::new("hx-get", "/api").is_attrs_empty());
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn props_is_props_empty_true_after_removing_last_attr() {
|
||||
async fn props_is_attrs_empty_true_after_removing_last_attr() {
|
||||
let p = Props::new("only", "one").with_prop(PropsOp::remove("only"));
|
||||
assert!(p.is_props_empty());
|
||||
assert!(p.is_attrs_empty());
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn props_is_empty_on_default() {
|
||||
assert!(Props::default().is_empty());
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn props_is_empty_false_with_id() {
|
||||
assert!(!Props::default().with_id("main").is_empty());
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn props_is_empty_false_with_attr() {
|
||||
assert!(!Props::new("hx-get", "/api").is_empty());
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn props_is_empty_false_with_class() {
|
||||
assert!(!Props::classes("btn").is_empty());
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
|
|
@ -256,6 +276,45 @@ async fn props_is_classes_empty_true_after_remove_class() {
|
|||
assert!(p.is_classes_empty());
|
||||
}
|
||||
|
||||
// **< get_prop("id") / get_prop("class") >*********************************************************
|
||||
|
||||
#[pagetop::test]
|
||||
async fn get_prop_id_returns_none_by_default() {
|
||||
assert_eq!(Props::default().get_prop("id"), None);
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn get_prop_id_returns_normalized_value() {
|
||||
let p = Props::default().with_id("My Button");
|
||||
assert_eq!(p.get_prop("id"), Some("my_button".to_string()));
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn get_prop_id_matches_get_id() {
|
||||
let p = Props::default().with_id("Header");
|
||||
assert_eq!(p.get_prop("id"), p.get_id());
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn get_prop_class_returns_none_by_default() {
|
||||
assert_eq!(Props::default().get_prop("class"), None);
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn get_prop_class_returns_joined_classes() {
|
||||
let p = Props::classes("btn btn-primary").with_prop(PropsOp::add_classes("active"));
|
||||
assert_eq!(
|
||||
p.get_prop("class"),
|
||||
Some("btn btn-primary active".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[pagetop::test]
|
||||
async fn get_prop_class_matches_get_classes() {
|
||||
let p = Props::classes("btn active");
|
||||
assert_eq!(p.get_prop("class"), p.get_classes());
|
||||
}
|
||||
|
||||
// **< Regression & edge cases >********************************************************************
|
||||
|
||||
#[pagetop::test]
|
||||
|
|
@ -284,9 +343,9 @@ async fn props_chained_set_and_remove_yields_expected_state() {
|
|||
.with_prop(PropsOp::set("c", "3"))
|
||||
.with_prop(PropsOp::remove("b"))
|
||||
.with_prop(PropsOp::set("a", "updated"));
|
||||
assert_eq!(p.get_prop("a"), Some("updated"));
|
||||
assert_eq!(p.get_prop("a"), Some("updated".to_string()));
|
||||
assert_eq!(p.get_prop("b"), None);
|
||||
assert_eq!(p.get_prop("c"), Some("3"));
|
||||
assert_eq!(p.get_prop("c"), Some("3".to_string()));
|
||||
assert_eq!(
|
||||
html! { span (p) {} }.into_string(),
|
||||
r#"<span a="updated" c="3"></span>"#
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue