chore: more tests passing

This commit is contained in:
Jonathan Kelley committed 2022-11-27 02:06:04 -05:00
1 parent f614cbb401
commit 565df11f7b
8 files changed
+364 -707

No files matched your search

+32 -11
View File
@@ -605,7 +605,7 @@ impl<'b: 'static> VirtualDom {
// only valid of the if there are no trailing elements
// self.create_and_append_children(new);
todo!()
todo!("we should never be appending - just creating N");
}
return;
}
@@ -615,8 +615,7 @@ impl<'b: 'static> VirtualDom {
for child in old {
let key = child.key.unwrap();
if !shared_keys.contains(&key) {
todo!("remove node");
// self.remove_nodes( [child]);
self.remove_node(child);
}
}
@@ -719,13 +718,6 @@ impl<'b: 'static> VirtualDom {
}
}
fn insert_after(&mut self, node: &'b VNode<'b>, nodes_created: usize) {
todo!()
}
fn insert_before(&mut self, node: &'b VNode<'b>, nodes_created: usize) {
todo!()
}
fn replace_node_with_on_stack(&mut self, old: &'b VNode<'b>, m: usize) {
todo!()
}
@@ -775,7 +767,36 @@ impl<'b: 'static> VirtualDom {
/// Push all the real nodes on the stack
fn push_all_real_nodes(&mut self, node: &VNode) -> usize {
todo!()
let mut onstack = 0;
for (idx, _) in node.template.roots.iter().enumerate() {
match node.dynamic_root(idx) {
Some(Text(t)) => {
self.mutations.push(Mutation::PushRoot { id: t.id.get() });
onstack += 1;
}
Some(Fragment(VFragment::Empty(t))) => {
self.mutations.push(Mutation::PushRoot { id: t.get() });
onstack += 1;
}
Some(Fragment(VFragment::NonEmpty(t))) => {
for node in *t {
onstack += self.push_all_real_nodes(node);
}
}
Some(Component(comp)) => {
todo!()
}
None => {
self.mutations.push(Mutation::PushRoot {
id: node.root_ids[idx].get(),
});
onstack += 1;
}
};
}
onstack
}
fn create_children(&mut self, nodes: &'b [VNode<'b>]) -> usize {
+4
View File
@@ -189,4 +189,8 @@ pub enum Mutation<'a> {
Remove {
id: ElementId,
},
PushRoot {
id: ElementId,
},
}
+2
View File
@@ -483,6 +483,7 @@ impl VirtualDom {
///
/// apply_edits(edits);
/// ```
#[must_use]
pub fn rebuild<'a>(&'a mut self) -> Mutations<'a> {
match unsafe { self.run_scope(ScopeId(0)).extend_lifetime_ref() } {
// Rebuilding implies we append the created elements to the root
@@ -500,6 +501,7 @@ impl VirtualDom {
/// Render whatever the VirtualDom has ready as fast as possible without requiring an executor to progress
/// suspended subtrees.
#[must_use]
pub fn render_immediate(&mut self) -> Mutations {
// Build a waker that won't wake up since our deadline is already expired when it's polled
let waker = futures_util::task::noop_waker();
+29
View File
@@ -0,0 +1,29 @@
use dioxus::core::Mutation::*;
use dioxus::prelude::*;
#[test]
fn multiroot() {
let mut dom = VirtualDom::new(|cx| {
cx.render(rsx! {
div { "Hello a" }
div { "Hello b" }
div { "Hello c" }
})
});
assert_eq!(
dom.rebuild().santize().template_mutations,
[
CreateElement { name: "div" },
CreateStaticText { value: "Hello a" },
AppendChildren { m: 1 },
CreateElement { name: "div" },
CreateStaticText { value: "Hello b" },
AppendChildren { m: 1 },
CreateElement { name: "div" },
CreateStaticText { value: "Hello c" },
AppendChildren { m: 1 },
SaveTemplate { name: "template", m: 3 }
]
)
}
File diff suppressed because it is too large. Load diff
+107
View File
@@ -270,3 +270,110 @@ fn removes_one_by_one_multiroot() {
]
);
}
#[test]
fn two_equal_fragments_are_equal_static() {
let mut dom = VirtualDom::new(|cx| {
cx.render(rsx! {
(0..5).map(|_| rsx! {
div { "hello" }
})
})
});
_ = dom.rebuild();
assert!(dom.render_immediate().edits.is_empty());
}
#[test]
fn two_equal_fragments_are_equal() {
let mut dom = VirtualDom::new(|cx| {
cx.render(rsx! {
(0..5).map(|i| rsx! {
div { "hello {i}" }
})
})
});
_ = dom.rebuild();
assert!(dom.render_immediate().edits.is_empty());
}
#[test]
fn remove_many() {
let mut dom = VirtualDom::new(|cx| {
let num = match cx.generation() % 3 {
0 => 0,
1 => 1,
2 => 5,
_ => unreachable!(),
};
cx.render(rsx! {
(0..num).map(|i| rsx! { div { "hello {i}" } })
})
});
let edits = dom.rebuild().santize();
assert!(edits.template_mutations.is_empty());
assert_eq!(
edits.edits,
[
CreatePlaceholder { id: ElementId(1,) },
AppendChildren { m: 1 },
]
);
dom.mark_dirty_scope(ScopeId(0));
let edits = dom.render_immediate().santize();
assert_eq!(
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
HydrateText { path: &[0,], value: "hello 0", id: ElementId(3,) },
ReplaceWith { id: ElementId(1,), m: 1 },
]
);
dom.mark_dirty_scope(ScopeId(0));
let edits = dom.render_immediate().santize();
assert_eq!(
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
HydrateText { path: &[0,], value: "hello 1", id: ElementId(4,) },
LoadTemplate { name: "template", index: 0, id: ElementId(5,) },
HydrateText { path: &[0,], value: "hello 2", id: ElementId(6,) },
LoadTemplate { name: "template", index: 0, id: ElementId(7,) },
HydrateText { path: &[0,], value: "hello 3", id: ElementId(8,) },
LoadTemplate { name: "template", index: 0, id: ElementId(9,) },
HydrateText { path: &[0,], value: "hello 4", id: ElementId(10,) },
InsertAfter { id: ElementId(2,), m: 4 },
]
);
dom.mark_dirty_scope(ScopeId(0));
let edits = dom.render_immediate().santize();
assert_eq!(
edits.edits,
[
Remove { id: ElementId(1,) },
Remove { id: ElementId(5,) },
Remove { id: ElementId(7,) },
Remove { id: ElementId(9,) },
CreatePlaceholder { id: ElementId(9,) },
ReplaceWith { id: ElementId(2,), m: 1 },
]
);
dom.mark_dirty_scope(ScopeId(0));
let edits = dom.render_immediate().santize();
assert_eq!(
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
HydrateText { path: &[0,], value: "hello 0", id: ElementId(10,) },
ReplaceWith { id: ElementId(9,), m: 1 },
]
)
}
+2 -2
View File
@@ -2,8 +2,8 @@
#![allow(non_snake_case)]
//! Tests for the lifecycle of components.
use dioxus::{core_macro::rsx_without_templates, prelude::*};
use dioxus_core::DomEdit::*;
use dioxus::core::{ElementId, Mutation::*};
use dioxus::prelude::*;
use std::sync::{Arc, Mutex};
type Shared<T> = Arc<Mutex<T>>;
+2 -7
View File
@@ -11,11 +11,6 @@ Specifically:
*/
use dioxus::prelude::*;
use dioxus_core::SchedulerMsg;
fn new_dom<P: 'static + Send>(app: Component<P>, props: P) -> VirtualDom {
VirtualDom::new_with_props(app, props)
}
/// This test ensures that if a component aborts early, it is replaced with a placeholder.
/// In debug, this should also toss a warning.
@@ -28,7 +23,7 @@ fn test_memory_leak() {
*val += 1;
if *val == 2 || *val == 4 {
return None;
return cx.render(rsx!(()));
}
let name = cx.use_hook(|| String::from("asd"));
@@ -66,7 +61,7 @@ fn test_memory_leak() {
render!(div { "goodbye world" })
}
let mut dom = new_dom(app, ());
let mut dom = VirtualDom::new(app);
dom.rebuild();
dom.hard_diff(ScopeId(0));