chore: more tests passing
This commit is contained in:
1 parent
f614cbb401
commit
565df11f7b
8 files changed
+364
-707
No files matched your search
+32
-11
@@ -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 {
|
||||
|
||||
@@ -189,4 +189,8 @@ pub enum Mutation<'a> {
|
||||
Remove {
|
||||
id: ElementId,
|
||||
},
|
||||
|
||||
PushRoot {
|
||||
id: ElementId,
|
||||
},
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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,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>>;
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in new issue
Block a user