소스 검색

wip: add diffing tests

Jonathan Kelley 2 년 전
부모
커밋
662f58c8bc
5개의 변경된 파일76개의 추가작업 그리고 3개의 파일을 삭제
  1. 8 3
      packages/core/src/diff.rs
  2. 4 0
      packages/core/src/scopes.rs
  3. 2 0
      packages/core/src/virtual_dom.rs
  4. 2 0
      packages/core/tests/.rustfmt.toml
  5. 60 0
      packages/core/tests/diff_element.rs

+ 8 - 3
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>,

+ 4 - 0
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.

+ 2 - 0
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

+ 2 - 0
packages/core/tests/.rustfmt.toml

@@ -0,0 +1,2 @@
+struct_variant_width = 100
+struct_lit_width = 80

+ 60 - 0
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());
+}