From 662f58c8bc572258063b49d46818a47e1e9a98ed Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Tue, 22 Nov 2022 20:16:14 -0800 Subject: [PATCH] wip: add diffing tests --- packages/core/src/diff.rs | 11 ++++-- packages/core/src/scopes.rs | 4 ++ packages/core/src/virtual_dom.rs | 2 + packages/core/tests/.rustfmt.toml | 2 + packages/core/tests/diff_element.rs | 60 +++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 packages/core/tests/.rustfmt.toml create mode 100644 packages/core/tests/diff_element.rs diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index 9e187e74c..38cd517b9 100644 --- a/packages/core/src/diff.rs +++ b/packages/core/src/diff.rs @@ -195,10 +195,11 @@ impl<'b: 'static> VirtualDom { /// } /// ``` fn light_diff_templates(&mut self, left: &'b VNode<'b>, right: &'b VNode<'b>) { - if let Some(components) = matching_components(left, right) { - components + match matching_components(left, right) { + None => self.replace_template(left, right), + Some(components) => components .into_iter() - .for_each(|(l, r)| self.diff_vcomponent(l, r)) + .for_each(|(l, r)| self.diff_vcomponent(l, r)), } } @@ -654,6 +655,10 @@ impl<'b: 'static> VirtualDom { } } + fn replace_template(&mut self, left: &'b VNode<'b>, right: &'b VNode<'b>) { + todo!("replacing should work!") + } + fn replace( &mut self, left_template: &'b VNode<'b>, diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs index 35afefc1f..a1a35f69d 100644 --- a/packages/core/src/scopes.rs +++ b/packages/core/src/scopes.rs @@ -103,6 +103,10 @@ impl ScopeState { } } + pub fn generation(&self) -> usize { + self.render_cnt.get() + } + /// Get a handle to the currently active bump arena for this Scope /// /// This is a bump memory allocator. Be careful using this directly since the contents will be wiped on the next render. diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 95374cb50..7c051c824 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -553,6 +553,8 @@ impl VirtualDom { // Save the current mutations length so we can split them into boundary let mutations_to_this_point = self.mutations.len(); + // Run the scope and get the mutations + self.run_scope(dirty.id); self.diff_scope(dirty.id); // If suspended leaves are present, then we should find the boundary for this scope and attach things diff --git a/packages/core/tests/.rustfmt.toml b/packages/core/tests/.rustfmt.toml new file mode 100644 index 000000000..01c43e05f --- /dev/null +++ b/packages/core/tests/.rustfmt.toml @@ -0,0 +1,2 @@ +struct_variant_width = 100 +struct_lit_width = 80 diff --git a/packages/core/tests/diff_element.rs b/packages/core/tests/diff_element.rs new file mode 100644 index 000000000..241adabe8 --- /dev/null +++ b/packages/core/tests/diff_element.rs @@ -0,0 +1,60 @@ +use dioxus::core::Mutation::*; +use dioxus::prelude::*; +use dioxus_core::ElementId; + +#[test] +fn text_diff() { + fn app(cx: Scope) -> Element { + let gen = cx.generation(); + cx.render(rsx!( h1 { "hello {gen}" } )) + } + + let mut vdom = VirtualDom::new(app); + vdom.rebuild(); + + vdom.mark_dirty_scope(ScopeId(0)); + assert_eq!( + vdom.render_immediate().edits, + [SetText { value: "hello 1", id: ElementId(2) }] + ); + + vdom.mark_dirty_scope(ScopeId(0)); + assert_eq!( + vdom.render_immediate().edits, + [SetText { value: "hello 2", id: ElementId(2) }] + ); + + vdom.mark_dirty_scope(ScopeId(0)); + assert_eq!( + vdom.render_immediate().edits, + [SetText { value: "hello 3", id: ElementId(2) }] + ); +} + +#[test] +fn element_swap() { + fn app(cx: Scope) -> Element { + let gen = cx.generation(); + + match gen % 2 { + 0 => cx.render(rsx!( h1 { "hello 1" } )), + 1 => cx.render(rsx!( h2 { "hello 2" } )), + _ => unreachable!(), + } + } + + let mut vdom = VirtualDom::new(app); + vdom.rebuild(); + + vdom.mark_dirty_scope(ScopeId(0)); + dbg!(vdom.render_immediate()); + + vdom.mark_dirty_scope(ScopeId(0)); + dbg!(vdom.render_immediate()); + + vdom.mark_dirty_scope(ScopeId(0)); + dbg!(vdom.render_immediate()); + + vdom.mark_dirty_scope(ScopeId(0)); + dbg!(vdom.render_immediate()); +}