lifecycle.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #![allow(unused, non_upper_case_globals)]
  2. #![allow(non_snake_case)]
  3. //! Tests for the lifecycle of components.
  4. use dioxus::core::{ElementId, Mutation::*};
  5. use dioxus::prelude::*;
  6. use std::rc::Rc;
  7. use std::sync::{Arc, Mutex};
  8. type Shared<T> = Arc<Mutex<T>>;
  9. #[test]
  10. fn manual_diffing() {
  11. struct AppProps {
  12. value: Shared<&'static str>,
  13. }
  14. fn app(cx: Scope<AppProps>) -> Element {
  15. let val = cx.props.value.lock().unwrap();
  16. cx.render(rsx! { div { "{val}" } })
  17. };
  18. let value = Arc::new(Mutex::new("Hello"));
  19. let mut dom = VirtualDom::new_with_props(app, AppProps { value: value.clone() });
  20. let _ = dom.rebuild();
  21. *value.lock().unwrap() = "goodbye";
  22. assert_eq!(
  23. dom.rebuild().santize().edits,
  24. [
  25. LoadTemplate { name: "template", index: 0, id: ElementId(3) },
  26. HydrateText { path: &[0], value: "goodbye", id: ElementId(4) },
  27. AppendChildren { m: 1, id: ElementId(0) }
  28. ]
  29. );
  30. }
  31. #[test]
  32. fn events_generate() {
  33. fn app(cx: Scope) -> Element {
  34. let count = cx.use_hook(|| 0);
  35. match *count {
  36. 0 => cx.render(rsx! {
  37. div { onclick: move |_| *count += 1,
  38. div { "nested" }
  39. "Click me!"
  40. }
  41. }),
  42. _ => cx.render(rsx!(())),
  43. }
  44. };
  45. let mut dom = VirtualDom::new(app);
  46. _ = dom.rebuild();
  47. dom.handle_event("click", Rc::new(MouseData::default()), ElementId(1), true);
  48. dom.mark_dirty(ScopeId(0));
  49. let edits = dom.render_immediate();
  50. assert_eq!(
  51. edits.edits,
  52. [
  53. CreatePlaceholder { id: ElementId(2) },
  54. ReplaceWith { id: ElementId(1), m: 1 }
  55. ]
  56. )
  57. }
  58. // #[test]
  59. // fn components_generate() {
  60. // fn app(cx: Scope) -> Element {
  61. // let render_phase = cx.use_hook(|| 0);
  62. // *render_phase += 1;
  63. // cx.render(match *render_phase {
  64. // 1 => rsx_without_templates!("Text0"),
  65. // 2 => rsx_without_templates!(div {}),
  66. // 3 => rsx_without_templates!("Text2"),
  67. // 4 => rsx_without_templates!(Child {}),
  68. // 5 => rsx_without_templates!({ None as Option<()> }),
  69. // 6 => rsx_without_templates!("text 3"),
  70. // 7 => rsx_without_templates!({ (0..2).map(|f| rsx_without_templates!("text {f}")) }),
  71. // 8 => rsx_without_templates!(Child {}),
  72. // _ => todo!(),
  73. // })
  74. // };
  75. // fn Child(cx: Scope) -> Element {
  76. // println!("Running child");
  77. // cx.render(rsx_without_templates! {
  78. // h1 {}
  79. // })
  80. // }
  81. // let mut dom = VirtualDom::new(app);
  82. // let edits = dom.rebuild();
  83. // assert_eq!(
  84. // edits.edits,
  85. // [
  86. // CreateTextNode { root: Some(1), text: "Text0" },
  87. // AppendChildren { root: Some(0), children: vec![1] }
  88. // ]
  89. // );
  90. // assert_eq!(
  91. // dom.hard_diff(ScopeId(0)).edits,
  92. // [
  93. // CreateElement { root: Some(2), tag: "div", children: 0 },
  94. // ReplaceWith { root: Some(1), nodes: vec![2] }
  95. // ]
  96. // );
  97. // assert_eq!(
  98. // dom.hard_diff(ScopeId(0)).edits,
  99. // [
  100. // CreateTextNode { root: Some(1), text: "Text2" },
  101. // ReplaceWith { root: Some(2), nodes: vec![1] }
  102. // ]
  103. // );
  104. // // child {}
  105. // assert_eq!(
  106. // dom.hard_diff(ScopeId(0)).edits,
  107. // [
  108. // CreateElement { root: Some(2), tag: "h1", children: 0 },
  109. // ReplaceWith { root: Some(1), nodes: vec![2] }
  110. // ]
  111. // );
  112. // // placeholder
  113. // assert_eq!(
  114. // dom.hard_diff(ScopeId(0)).edits,
  115. // [
  116. // CreatePlaceholder { root: Some(1) },
  117. // ReplaceWith { root: Some(2), nodes: vec![1] }
  118. // ]
  119. // );
  120. // assert_eq!(
  121. // dom.hard_diff(ScopeId(0)).edits,
  122. // [
  123. // CreateTextNode { root: Some(2), text: "text 3" },
  124. // ReplaceWith { root: Some(1), nodes: vec![2] }
  125. // ]
  126. // );
  127. // assert_eq!(
  128. // dom.hard_diff(ScopeId(0)).edits,
  129. // [
  130. // CreateTextNode { text: "text 0", root: Some(1) },
  131. // CreateTextNode { text: "text 1", root: Some(3) },
  132. // ReplaceWith { root: Some(2), nodes: vec![1, 3] },
  133. // ]
  134. // );
  135. // assert_eq!(
  136. // dom.hard_diff(ScopeId(0)).edits,
  137. // [
  138. // CreateElement { tag: "h1", root: Some(2), children: 0 },
  139. // ReplaceWith { root: Some(1), nodes: vec![2] },
  140. // Remove { root: Some(3) },
  141. // ]
  142. // );
  143. // }