diffing.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. use bumpalo::Bump;
  2. use anyhow::{Context, Result};
  3. use dioxus::{
  4. arena::SharedResources,
  5. diff::{CreateMeta, DiffMachine},
  6. prelude::*,
  7. util::DebugDom,
  8. DomEdit,
  9. };
  10. use dioxus_core as dioxus;
  11. use dioxus_html as dioxus_elements;
  12. struct TestDom {
  13. bump: Bump,
  14. resources: SharedResources,
  15. }
  16. impl TestDom {
  17. fn new() -> TestDom {
  18. let bump = Bump::new();
  19. let resources = SharedResources::new();
  20. TestDom { bump, resources }
  21. }
  22. fn new_factory<'a>(&'a self) -> NodeFactory<'a> {
  23. NodeFactory::new(&self.bump)
  24. }
  25. fn render<'a, F>(&'a self, lazy_nodes: LazyNodes<'a, F>) -> VNode<'a>
  26. where
  27. F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
  28. {
  29. use dioxus_core::nodes::{IntoVNode, IntoVNodeList};
  30. lazy_nodes.into_vnode(NodeFactory::new(&self.bump))
  31. }
  32. fn diff<'a>(&'a self, old: &'a VNode<'a>, new: &'a VNode<'a>) -> Vec<DomEdit<'a>> {
  33. let mut edits = Vec::new();
  34. let dom = DebugDom::new();
  35. let mut machine = DiffMachine::new_headless(&mut edits, &dom, &self.resources);
  36. machine.diff_node(old, new);
  37. edits
  38. }
  39. fn create<'a, F1>(&'a self, left: LazyNodes<'a, F1>) -> (CreateMeta, Vec<DomEdit<'a>>)
  40. where
  41. F1: FnOnce(NodeFactory<'a>) -> VNode<'a>,
  42. {
  43. let old = self.bump.alloc(self.render(left));
  44. let mut edits = Vec::new();
  45. let dom = DebugDom::new();
  46. let mut machine = DiffMachine::new_headless(&mut edits, &dom, &self.resources);
  47. let meta = machine.create_vnode(old);
  48. (meta, edits)
  49. }
  50. fn lazy_diff<'a, F1, F2>(
  51. &'a self,
  52. left: LazyNodes<'a, F1>,
  53. right: LazyNodes<'a, F2>,
  54. ) -> Vec<DomEdit<'a>>
  55. where
  56. F1: FnOnce(NodeFactory<'a>) -> VNode<'a>,
  57. F2: FnOnce(NodeFactory<'a>) -> VNode<'a>,
  58. {
  59. let old = self.bump.alloc(self.render(left));
  60. let new = self.bump.alloc(self.render(right));
  61. let mut edits = Vec::new();
  62. let dom = DebugDom::new();
  63. let mut machine = DiffMachine::new_headless(&mut edits, &dom, &self.resources);
  64. machine.create_vnode(old);
  65. edits.clear();
  66. let mut machine = DiffMachine::new_headless(&mut edits, &dom, &self.resources);
  67. machine.diff_node(old, new);
  68. edits
  69. }
  70. }
  71. #[test]
  72. fn diffing_works() {}
  73. #[test]
  74. fn html_and_rsx_generate_the_same_output() {
  75. let dom = TestDom::new();
  76. let edits = dom.lazy_diff(
  77. rsx! ( div { "Hello world" } ),
  78. rsx! ( div { "Goodbye world" } ),
  79. );
  80. dbg!(edits);
  81. }
  82. #[test]
  83. fn fragments_create_properly() {
  84. let dom = TestDom::new();
  85. let (meta, edits) = dom.create(rsx! {
  86. div { "Hello a" }
  87. div { "Hello b" }
  88. div { "Hello c" }
  89. });
  90. assert!(&edits[0].is("CreateElement"));
  91. assert!(&edits[3].is("CreateElement"));
  92. assert!(&edits[6].is("CreateElement"));
  93. assert_eq!(meta.added_to_stack, 3);
  94. dbg!(edits);
  95. }