lifecycle.rs 4.8 KB

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