#![deny(warnings)]
use sauron::html::attributes::{styles, Style};
use sauron::*;
#[test]
fn nodes_with_event_must_be_replaced() {
let elem_id = "input-remove-event-test";
let event1 = on_input(move |_event: InputEvent| {
println!("input event is triggered");
});
let old: Node<()> = input(
vec![
// On input we'll set our Rc> value to the input elements value
id(elem_id),
value("End Text"),
event1.clone(),
],
vec![],
);
let new = input(
vec![
// On input we'll set our Rc> value to the input elements value
id(elem_id),
value("End Text"),
],
vec![],
);
let patch = diff(&old, &new);
println!("patch: {:#?}", patch);
assert_eq!(
patch,
vec![Patch::remove_attributes(
&"input",
TreePath::new(vec![]),
vec![&event1]
)]
);
}
#[test]
fn change_class_attribute() {
let old: Node<()> = div(vec![classes(["class1", "class2"])], vec![]);
let new = div(vec![classes(["class1", "difference_class"])], vec![]);
assert_eq!(
diff(&old, &new),
vec![Patch::add_attributes(
&"div",
TreePath::new(vec![]),
vec![&Attribute::with_multiple_values(
None,
"class",
vec![
AttributeValue::from("class1".to_string()),
AttributeValue::from("difference_class".to_string())
]
)]
)],
"Should add the new attributes"
);
}
#[test]
fn truncate_children() {
let old: Node<()> = div(
vec![],
vec![
div(vec![class("class1")], vec![]),
div(vec![class("class2")], vec![]),
div(vec![class("class3")], vec![]),
div(vec![class("class4")], vec![]),
div(vec![class("class5")], vec![]),
div(vec![class("class6")], vec![]),
div(vec![class("class7")], vec![]),
],
);
let new = div(
vec![],
vec![
div(vec![class("class1")], vec![]),
div(vec![class("class2")], vec![]),
div(vec![class("class3")], vec![]),
],
);
assert_eq!(
dbg!(diff(&old, &new)),
vec![
Patch::remove_node(Some(&"div"), TreePath::new(vec![3]),),
Patch::remove_node(Some(&"div"), TreePath::new(vec![4]),),
Patch::remove_node(Some(&"div"), TreePath::new(vec![5]),),
Patch::remove_node(Some(&"div"), TreePath::new(vec![6]),),
],
"Should truncate children"
);
}
#[test]
fn truncate_children_different_attributes() {
let old: Node<()> = div(
vec![],
vec![
div(vec![class("class1")], vec![]),
div(vec![class("class2")], vec![]),
div(vec![class("class3")], vec![]),
div(vec![class("class4")], vec![]),
div(vec![class("class5")], vec![]),
div(vec![class("class6")], vec![]),
div(vec![class("class7")], vec![]),
],
);
let new = div(
vec![],
vec![
div(vec![class("class5")], vec![]),
div(vec![class("class6")], vec![]),
div(vec![class("class7")], vec![]),
],
);
let patch = diff(&old, &new);
dbg!(&patch);
assert_eq!(
patch,
vec![
Patch::add_attributes(&"div", TreePath::new(vec![0]), vec![&class("class5")]),
Patch::add_attributes(&"div", TreePath::new(vec![1]), vec![&class("class6")]),
Patch::add_attributes(&"div", TreePath::new(vec![2]), vec![&class("class7")]),
Patch::remove_node(Some(&"div"), TreePath::new(vec![3]),),
Patch::remove_node(Some(&"div"), TreePath::new(vec![4]),),
Patch::remove_node(Some(&"div"), TreePath::new(vec![5]),),
Patch::remove_node(Some(&"div"), TreePath::new(vec![6]),),
],
"Should truncate children"
);
}
#[test]
fn replace_node2() {
let old: Node<()> = div(vec![], vec![b(vec![], vec![text("1")]), b(vec![], vec![])]);
let new = div(vec![], vec![i(vec![], vec![text("1")]), i(vec![], vec![])]);
let patch = diff(&old, &new);
dbg!(&patch);
assert_eq!(
patch,
vec![
Patch::replace_node(
Some(&"b"),
TreePath::new(vec![0]),
vec![&i(vec![], vec![text("1")])]
),
Patch::replace_node(Some(&"b"), TreePath::new(vec![1]), vec![&i(vec![], vec![])]),
],
"ReplaceNode node with a child",
)
}
#[test]
fn remove_nodes1() {
let old: Node<()> = div(vec![], vec![b(vec![], vec![]), span(vec![], vec![])]); //{
},
let new = div(vec![], vec![]); //{
},
assert_eq!(
dbg!(diff(&old, &new)),
vec![Patch::clear_children(Some(&"div"), TreePath::new(vec![]),),],
"Remove all child nodes at and after child sibling index 1",
);
}
#[test]
fn remove_nodes2() {
let old: Node<()> = div(
vec![],
vec![
span(
vec![],
vec![
b(vec![], vec![]),
// This `i` tag will get removed
i(vec![], vec![]),
],
),
// This `strong` tag will get removed
strong(vec![], vec![]),
],
);
let new: Node<()> = div(vec![], vec![span(vec![], vec![b(vec![], vec![])])]);
assert_eq!(
dbg!(diff(&old, &new)),
vec![
Patch::remove_node(Some(&"i"), TreePath::new(vec![0, 1]),),
Patch::remove_node(Some(&"strong"), TreePath::new(vec![1]),),
],
"Remove a child and a grandchild node",
);
}
#[test]
fn remove_nodes3() {
let old: Node<()> = div(
vec![],
vec![
b(vec![], vec![i(vec![], vec![]), i(vec![], vec![])]),
b(vec![], vec![]),
],
); //{
},
let new = div(
vec![],
vec![b(vec![], vec![i(vec![], vec![])]), i(vec![], vec![])],
); //{
},
assert_eq!(
dbg!(diff(&old, &new)),
vec![
Patch::remove_node(Some(&"i"), TreePath::new(vec![0, 1]),),
Patch::replace_node(Some(&"b"), TreePath::new(vec![1]), vec![&i(vec![], vec![])]),
],
"Removing child and change next node after parent",
)
}
#[test]
fn add_attributes() {
let old: Node<()> = div(vec![], vec![]); //{
},
let new = div(vec![id("hello")], vec![]); //{
},
assert_eq!(
diff(&old, &new),
vec![Patch::add_attributes(
&"div",
TreePath::new(vec![]),
vec![&id("hello")]
)],
"Add attributes",
);
let old: Node<()> = div(vec![id("foobar")], vec![]); //{
},
let new = div(vec![id("hello")], vec![]); //{
},
assert_eq!(
diff(&old, &new),
vec![Patch::add_attributes(
&"div",
TreePath::new(vec![]),
vec![&id("hello")]
)],
"Change attribute",
);
}
#[test]
fn add_style_attributes() {
let old: Node<()> = div(vec![style!("display": "block")], vec![]);
let new = div(vec![style!("display": "none")], vec![]);
assert_eq!(
diff(&old, &new),
vec![Patch::add_attributes(
&"div",
TreePath::new(vec![]),
vec![&style!("display": "none")]
)],
"Add attributes",
);
}
#[test]
fn add_style_attributes_1_change() {
let old: Node<()> = div(
vec![styles([("display", "block"), ("position", "absolute")])],
vec![],
);
let new = div(
vec![styles([("display", "none"), ("position", "absolute")])],
vec![],
);
assert_eq!(
diff(&old, &new),
vec![Patch::add_attributes(
&"div",
TreePath::new(vec![]),
vec![&Attribute::with_multiple_values(
None,
"style",
vec![AttributeValue::Style(vec![
Style::new("display", "none"),
Style::new("position", "absolute")
])]
)]
)],
);
}
#[test]
fn add_style_attributes_no_changes() {
let old: Node<()> = div(
vec![styles([("display", "block"), ("position", "absolute")])],
vec![],
);
let new = div(
vec![styles([("display", "block"), ("position", "absolute")])],
vec![],
);
assert_eq!(diff(&old, &new), vec![],);
}
#[test]
fn remove_style_attributes() {
let old: Node<()> = div(vec![style!("display": "block")], vec![]);
let new = div(vec![], vec![]);
assert_eq!(
diff(&old, &new),
vec![Patch::remove_attributes(
&"div",
TreePath::new(vec![]),
vec![&style!("display": "block")]
)],
"Add attributes",
);
}
#[test]
fn remove_events_will_become_replace_node() {
let event1 = on_click(|_| println!("hi"));
let old: Node<()> = div(vec![event1.clone()], vec![]);
let new = div(vec![], vec![]);
assert_eq!(
diff(&old, &new),
vec![Patch::remove_attributes(
&"div",
TreePath::new(vec![]),
vec![&event1]
)],
"Remove events",
);
}
#[test]
fn text_changed_in_keyed_elements() {
let old: Node<()> = main(
vec![class("test4")],
vec![section(
vec![class("todo")],
vec![
article(vec![key(1)], vec![text("item1")]),
article(vec![key(2)], vec![text("item2")]),
article(vec![key(3)], vec![text("item3")]),
],
)],
);
// we remove the key1
let update1: Node<()> = main(
vec![class("test4")],
vec![section(
vec![class("todo")],
vec![
article(vec![key(2)], vec![text("item2")]),
article(vec![key(3)], vec![text("item3 with changes")]),
],
)],
);
let patch = diff(&old, &update1);
dbg!(&patch);
assert_eq!(
patch,
vec![
Patch::replace_node(
None,
TreePath::new(vec![0, 2, 0]),
vec![&text("item3 with changes")]
),
Patch::remove_node(Some(&"article"), TreePath::new(vec![0, 0]),),
]
);
}
#[test]
fn multiple_style_calls() {
let old: Node<&'static str> = div(
vec![
styles_flag([
("font-family", "monospace", true),
("user-select", "none", false),
]),
styles([("display", "flex")]),
],
vec![],
);
let new: Node<&'static str> = div(
vec![
style!("font-family": "monospace1"),
style!("display": "flex"),
],
vec![],
);
let patches = diff(&old, &new);
println!("patches: {:#?}", patches);
assert_eq!(
patches,
vec![Patch::add_attributes(
&"div",
TreePath::new(vec![]),
vec![
&style!("font-family": "monospace1"),
&style!("display": "flex")
]
)]
);
}