#[cfg(test)]
mod tests {
use super::super::*;
fn text(content: &str) -> Element {
let mut el = Element::new("Text");
el.props
.insert("0".to_string(), Value::Static(serde_json::json!(content)));
el
}
#[test]
fn test_simple_children_slot() {
let component = Component::new("Card", |_props| {
let mut container = Element::new("Container");
container
.children
.push_back(std::sync::Arc::new(text("Card Header")));
let children_slot = Element::new("Children");
container
.children
.push_back(std::sync::Arc::new(children_slot));
container
.children
.push_back(std::sync::Arc::new(text("Card Footer")));
container
});
let mut registry = ComponentRegistry::new();
registry.register(component);
let mut card_instance = Element::new("Card");
card_instance
.children
.push_back(std::sync::Arc::new(text("Child 1")));
card_instance
.children
.push_back(std::sync::Arc::new(text("Child 2")));
let expanded = registry.expand(&card_instance);
assert_eq!(expanded.element_type, "Container");
assert_eq!(expanded.children.len(), 4);
assert_eq!(expanded.children[0].element_type, "Text"); assert_eq!(expanded.children[1].element_type, "Text"); assert_eq!(expanded.children[2].element_type, "Text"); assert_eq!(expanded.children[3].element_type, "Text"); }
#[test]
fn test_named_slot() {
let component = Component::new("Dialog", |_props| {
let mut container = Element::new("Column");
let mut header = Element::new("Container");
let mut header_slot = Element::new("Children");
header_slot.props.insert(
"slot.0".to_string(),
Value::Static(serde_json::json!("header")),
);
header.children.push_back(std::sync::Arc::new(header_slot));
container.children.push_back(std::sync::Arc::new(header));
let mut body = Element::new("Container");
let mut body_slot = Element::new("Children");
body_slot.props.insert(
"slot.0".to_string(),
Value::Static(serde_json::json!("body")),
);
body.children.push_back(std::sync::Arc::new(body_slot));
container.children.push_back(std::sync::Arc::new(body));
container
});
let mut registry = ComponentRegistry::new();
registry.register(component);
let mut dialog = Element::new("Dialog");
let mut header_child = text("Dialog Title");
header_child.props.insert(
"slot.0".to_string(),
Value::Static(serde_json::json!("header")),
);
dialog.children.push_back(std::sync::Arc::new(header_child));
let mut body_child = text("Dialog Content");
body_child.props.insert(
"slot.0".to_string(),
Value::Static(serde_json::json!("body")),
);
dialog.children.push_back(std::sync::Arc::new(body_child));
let expanded = registry.expand(&dialog);
assert_eq!(expanded.element_type, "Column");
assert_eq!(expanded.children.len(), 2);
assert_eq!(expanded.children[0].children.len(), 1);
assert_eq!(expanded.children[0].children[0].element_type, "Text");
assert_eq!(expanded.children[1].children.len(), 1);
assert_eq!(expanded.children[1].children[0].element_type, "Text");
}
#[test]
fn test_default_slot_without_applicator() {
let component = Component::new("Panel", |_props| {
let mut container = Element::new("Column");
let mut header = Element::new("Container");
let mut header_slot = Element::new("Children");
header_slot.props.insert(
"slot.0".to_string(),
Value::Static(serde_json::json!("header")),
);
header.children.push_back(std::sync::Arc::new(header_slot));
container.children.push_back(std::sync::Arc::new(header));
let mut body = Element::new("Container");
let default_slot = Element::new("Children");
body.children.push_back(std::sync::Arc::new(default_slot));
container.children.push_back(std::sync::Arc::new(body));
container
});
let mut registry = ComponentRegistry::new();
registry.register(component);
let mut panel = Element::new("Panel");
let mut header_child = text("Panel Header");
header_child.props.insert(
"slot.0".to_string(),
Value::Static(serde_json::json!("header")),
);
panel.children.push_back(std::sync::Arc::new(header_child));
panel
.children
.push_back(std::sync::Arc::new(text("Default Content 1")));
panel
.children
.push_back(std::sync::Arc::new(text("Default Content 2")));
let expanded = registry.expand(&panel);
assert_eq!(expanded.children[0].children.len(), 1);
assert_eq!(expanded.children[1].children.len(), 2);
}
#[test]
fn test_nested_children_slots() {
let outer = Component::new("Outer", |_props| {
let mut container = Element::new("Container");
container
.children
.push_back(std::sync::Arc::new(text("Outer Start")));
let mut inner = Element::new("Inner");
let children_slot = Element::new("Children");
inner.children.push_back(std::sync::Arc::new(children_slot));
container.children.push_back(std::sync::Arc::new(inner));
container
.children
.push_back(std::sync::Arc::new(text("Outer End")));
container
});
let inner = Component::new("Inner", |_props| {
let mut wrapper = Element::new("Container");
wrapper
.children
.push_back(std::sync::Arc::new(text("Inner Start")));
wrapper
.children
.push_back(std::sync::Arc::new(Element::new("Children")));
wrapper
.children
.push_back(std::sync::Arc::new(text("Inner End")));
wrapper
});
let mut registry = ComponentRegistry::new();
registry.register(outer);
registry.register(inner);
let mut outer_instance = Element::new("Outer");
outer_instance
.children
.push_back(std::sync::Arc::new(text("Actual Content")));
let expanded = registry.expand(&outer_instance);
assert_eq!(expanded.children.len(), 3);
assert_eq!(expanded.children[0].element_type, "Text"); assert_eq!(expanded.children[1].element_type, "Container"); assert_eq!(expanded.children[2].element_type, "Text");
let inner_expanded = &expanded.children[1];
assert_eq!(inner_expanded.children.len(), 3);
assert_eq!(inner_expanded.children[0].element_type, "Text"); assert_eq!(inner_expanded.children[1].element_type, "Text"); assert_eq!(inner_expanded.children[2].element_type, "Text"); }
#[test]
fn test_multiple_children_of_same_slot() {
let component = Component::new("Section", |_props| {
let mut container = Element::new("Column");
let mut actions = Element::new("Row");
let mut actions_slot = Element::new("Children");
actions_slot.props.insert(
"slot.0".to_string(),
Value::Static(serde_json::json!("actions")),
);
actions
.children
.push_back(std::sync::Arc::new(actions_slot));
container.children.push_back(std::sync::Arc::new(actions));
container
});
let mut registry = ComponentRegistry::new();
registry.register(component);
let mut section = Element::new("Section");
let mut action1 = Element::new("Button");
action1.props.insert(
"slot.0".to_string(),
Value::Static(serde_json::json!("actions")),
);
action1
.children
.push_back(std::sync::Arc::new(text("Action 1")));
let mut action2 = Element::new("Button");
action2.props.insert(
"slot.0".to_string(),
Value::Static(serde_json::json!("actions")),
);
action2
.children
.push_back(std::sync::Arc::new(text("Action 2")));
section.children.push_back(std::sync::Arc::new(action1));
section.children.push_back(std::sync::Arc::new(action2));
let expanded = registry.expand(§ion);
assert_eq!(expanded.children[0].children.len(), 2);
assert_eq!(expanded.children[0].children[0].element_type, "Button");
assert_eq!(expanded.children[0].children[1].element_type, "Button");
}
#[test]
fn test_empty_children_slot() {
let component = Component::new("Optional", |_props| {
let mut container = Element::new("Container");
container
.children
.push_back(std::sync::Arc::new(text("Before")));
container
.children
.push_back(std::sync::Arc::new(Element::new("Children")));
container
.children
.push_back(std::sync::Arc::new(text("After")));
container
});
let mut registry = ComponentRegistry::new();
registry.register(component);
let instance = Element::new("Optional");
let expanded = registry.expand(&instance);
assert_eq!(expanded.children.len(), 2);
assert_eq!(expanded.children[0].element_type, "Text"); assert_eq!(expanded.children[1].element_type, "Text"); }
#[test]
fn test_children_slot_deep_in_tree() {
let component = Component::new("DeepCard", |_props| {
let mut root = Element::new("Container");
let mut column = Element::new("Column");
let mut row = Element::new("Row");
let mut inner = Element::new("Container");
inner
.children
.push_back(std::sync::Arc::new(Element::new("Children")));
row.children.push_back(std::sync::Arc::new(inner));
column.children.push_back(std::sync::Arc::new(row));
root.children.push_back(std::sync::Arc::new(column));
root
});
let mut registry = ComponentRegistry::new();
registry.register(component);
let mut instance = Element::new("DeepCard");
instance
.children
.push_back(std::sync::Arc::new(text("Deep Child")));
let expanded = registry.expand(&instance);
let deep_child = &expanded.children[0].children[0].children[0].children[0];
assert_eq!(deep_child.element_type, "Text");
}
}