Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SsrNode remove_child #218

Merged
merged 2 commits into from
Aug 29, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Fix SsrNode remove_child
lukechu10 committed Aug 29, 2021

Verified

This commit was signed with the committer’s verified signature.
commit 728fb09eeaebac591cd672a6dc4904ee2d2a07d5
92 changes: 83 additions & 9 deletions packages/sycamore/src/generic_node/ssr_node.rs
Original file line number Diff line number Diff line change
@@ -93,7 +93,7 @@ impl SsrNode {
.children
.clone()
.into_iter()
.filter(|node| node == child)
.filter(|node| node != child)
.collect();
e.borrow_mut().children = children;
}
@@ -185,15 +185,12 @@ impl GenericNode for SsrNode {
fn remove_child(&self, child: &Self) {
match self.0.ty.as_ref() {
SsrNodeType::Element(e) => {
let initial_children_len = e.borrow().children.len();
if child.parent_node().as_ref() != Some(self) {
panic!("the node to be removed is not a child of this node");
}
child.set_parent(Weak::new());
let index = e
.borrow()
.children
.iter()
.enumerate()
.find_map(|(i, c)| (c == child).then(|| i))
.expect("the node to be removed is not a child of this node");
e.borrow_mut().children.remove(index);
debug_assert_eq!(e.borrow().children.len(), initial_children_len - 1);
}
_ => panic!("node type cannot have children"),
}
@@ -369,3 +366,80 @@ pub fn render_to_string(template: impl FnOnce() -> Template<SsrNode>) -> String

ret
}

#[cfg(test)]
mod tests {
use super::*;
use crate::prelude::*;

#[test]
fn render_hello_world() {
assert_eq!(
render_to_string(|| template! {
"Hello World!"
}),
"Hello World!"
);
}

#[test]
fn append_child() {
let node = SsrNode::element("div");
let p = SsrNode::element("p");
let p2 = SsrNode::element("p");

node.append_child(&p);
node.append_child(&p2);

// p and p2 parents should be updated
assert_eq!(p.parent_node().as_ref(), Some(&node));
assert_eq!(p2.parent_node().as_ref(), Some(&node));

// node.first_child should be p
assert_eq!(node.first_child().as_ref(), Some(&p));

// p.next_sibling should be p2
assert_eq!(p.next_sibling().as_ref(), Some(&p2));
}

#[test]
fn remove_child() {
let node = SsrNode::element("div");
let p = SsrNode::element("p");

node.append_child(&p);
// p parent should be updated
assert_eq!(p.parent_node().as_ref(), Some(&node));
// node.first_child should be p
assert_eq!(node.first_child().as_ref(), Some(&p));

// remove p from node
node.remove_child(&p);
// p parent should be updated
assert_eq!(p.parent_node().as_ref(), None);
// node.first_child should be None
assert_eq!(node.first_child().as_ref(), None);
}

#[test]
fn remove_child_2() {
let node = SsrNode::element("div");
let p = SsrNode::element("p");
let p2 = SsrNode::element("p");
let p3 = SsrNode::element("p");

node.append_child(&p);
node.append_child(&p2);
node.append_child(&p3);

// node.first_child should be p
assert_eq!(node.first_child().as_ref(), Some(&p));

// remove p from node
node.remove_child(&p);
// p parent should be updated
assert_eq!(p.parent_node().as_ref(), None);
// node.first_child should be p2
assert_eq!(node.first_child().as_ref(), Some(&p2));
}
}
27 changes: 27 additions & 0 deletions packages/sycamore/tests/ssr/main.rs
Original file line number Diff line number Diff line change
@@ -71,3 +71,30 @@ fn fragments() {
"<p>1</p><p>2</p><p>3</p>"
);
}

#[test]
fn indexed() {
let count = Signal::new(vec![1, 2]);

let node = cloned!((count) => template! {
ul {
Indexed(IndexedProps {
iterable: count.handle(),
template: |item| template! {
li { (item) }
},
})
}
});

let actual = sycamore::render_to_string(|| node.clone());
assert_eq!(actual, "<ul><li>1</li><li>2</li></ul>");

count.set(count.get().iter().cloned().chain(Some(3)).collect());
let actual = sycamore::render_to_string(|| node.clone());
assert_eq!(actual, "<ul><li>1</li><li>2</li><li>3</li></ul>");

count.set(count.get()[1..].into());
let actual = sycamore::render_to_string(|| node.clone());
assert_eq!(actual, "<ul><li>2</li><li>3</li></ul>");
}