create_dom.rs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #![allow(unused, non_upper_case_globals, non_snake_case)]
  2. //! Prove that the dom works normally through virtualdom methods.
  3. //!
  4. //! This methods all use "rebuild" which completely bypasses the scheduler.
  5. //! Hard rebuilds don't consume any events from the event queue.
  6. use dioxus::prelude::*;
  7. use dioxus_core::DomEdit::*;
  8. fn new_dom<P: 'static + Send>(app: Component<P>, props: P) -> VirtualDom {
  9. VirtualDom::new_with_props(app, props)
  10. }
  11. #[test]
  12. fn test_original_diff() {
  13. static APP: Component = |cx| {
  14. cx.render(rsx! {
  15. div {
  16. div {
  17. "Hello, world!"
  18. }
  19. }
  20. })
  21. };
  22. let mut dom = new_dom(APP, ());
  23. let mutations = dom.rebuild();
  24. assert_eq!(
  25. mutations.edits,
  26. [
  27. // create template
  28. CreateElement { root: Some(1), tag: "template", children: 1 },
  29. CreateElement { root: None, tag: "div", children: 1 },
  30. CreateElement { root: None, tag: "div", children: 1 },
  31. CreateTextNode { root: None, text: "Hello, world!" },
  32. // clone template
  33. CloneNodeChildren { id: Some(1), new_ids: vec![2] },
  34. // add to root
  35. AppendChildren { root: Some(0), children: vec![2] },
  36. ]
  37. );
  38. }
  39. #[test]
  40. fn create() {
  41. static APP: Component = |cx| {
  42. cx.render(rsx! {
  43. div {
  44. div {
  45. "Hello, world!"
  46. div {
  47. div {
  48. Fragment {
  49. "hello"
  50. "world"
  51. }
  52. }
  53. }
  54. }
  55. }
  56. })
  57. };
  58. let mut dom = new_dom(APP, ());
  59. let mutations = dom.rebuild();
  60. assert_eq!(
  61. mutations.edits,
  62. [
  63. // create template
  64. CreateElement { root: Some(1), tag: "template", children: 1 },
  65. CreateElement { root: None, tag: "div", children: 1 },
  66. CreateElement { root: None, tag: "div", children: 2 },
  67. CreateTextNode { root: None, text: "Hello, world!" },
  68. CreateElement { root: None, tag: "div", children: 1 },
  69. CreateElement { root: None, tag: "div", children: 1 },
  70. CreatePlaceholder { root: None },
  71. // clone template
  72. CloneNodeChildren { id: Some(1), new_ids: vec![2] },
  73. CreateTextNode { root: Some(3), text: "hello" },
  74. CreateTextNode { root: Some(4), text: "world" },
  75. // update template
  76. SetLastNode { id: 2 },
  77. FirstChild {},
  78. FirstChild {},
  79. NextSibling {},
  80. FirstChild {},
  81. FirstChild {},
  82. ReplaceWith { root: None, nodes: vec![3, 4] },
  83. AppendChildren { root: Some(0), children: vec![2] }
  84. ]
  85. );
  86. }
  87. #[test]
  88. fn create_list() {
  89. static APP: Component = |cx| {
  90. cx.render(rsx! {
  91. {(0..3).map(|f| rsx!{ div {
  92. "hello"
  93. }})}
  94. })
  95. };
  96. let mut dom = new_dom(APP, ());
  97. let mutations = dom.rebuild();
  98. assert_eq!(
  99. mutations.edits,
  100. [
  101. // create template
  102. CreateElement { root: Some(1), tag: "template", children: 1 },
  103. CreateElement { root: None, tag: "div", children: 1 },
  104. CreateTextNode { root: None, text: "hello" },
  105. // clone template
  106. CloneNodeChildren { id: Some(1), new_ids: vec![2] },
  107. CloneNodeChildren { id: Some(1), new_ids: vec![3] },
  108. CloneNodeChildren { id: Some(1), new_ids: vec![4] },
  109. // add to root
  110. AppendChildren { root: Some(0), children: vec![2, 3, 4] },
  111. ]
  112. );
  113. }
  114. #[test]
  115. fn create_simple() {
  116. static APP: Component = |cx| {
  117. cx.render(rsx! {
  118. div {}
  119. div {}
  120. div {}
  121. div {}
  122. })
  123. };
  124. let mut dom = new_dom(APP, ());
  125. let mutations = dom.rebuild();
  126. assert_eq!(
  127. mutations.edits,
  128. [
  129. // create template
  130. CreateElement { root: Some(1), tag: "template", children: 4 },
  131. CreateElement { root: None, tag: "div", children: 0 },
  132. CreateElement { root: None, tag: "div", children: 0 },
  133. CreateElement { root: None, tag: "div", children: 0 },
  134. CreateElement { root: None, tag: "div", children: 0 },
  135. // clone template
  136. CloneNodeChildren { id: Some(1), new_ids: vec![2, 3, 4, 5] },
  137. // add to root
  138. AppendChildren { root: Some(0), children: vec![2, 3, 4, 5] },
  139. ]
  140. );
  141. }
  142. #[test]
  143. fn create_components() {
  144. static App: Component = |cx| {
  145. cx.render(rsx! {
  146. Child { "abc1" }
  147. Child { "abc2" }
  148. Child { "abc3" }
  149. })
  150. };
  151. #[derive(Props)]
  152. struct ChildProps<'a> {
  153. children: Element<'a>,
  154. }
  155. fn Child<'a>(cx: Scope<'a, ChildProps<'a>>) -> Element {
  156. cx.render(rsx! {
  157. h1 {}
  158. div { &cx.props.children }
  159. p {}
  160. })
  161. }
  162. let mut dom = new_dom(App, ());
  163. let mutations = dom.rebuild();
  164. assert_eq!(
  165. mutations.edits,
  166. [
  167. // create template
  168. CreateElement { root: Some(1), tag: "template", children: 3 },
  169. CreateElement { root: None, tag: "h1", children: 0 },
  170. CreateElement { root: None, tag: "div", children: 1 },
  171. CreatePlaceholder { root: None },
  172. CreateElement { root: None, tag: "p", children: 0 },
  173. // clone template
  174. CloneNodeChildren { id: Some(1), new_ids: vec![2, 3, 4] },
  175. // update template
  176. CreateTextNode { root: Some(5), text: "abc1" },
  177. SetLastNode { id: 3 },
  178. FirstChild {},
  179. ReplaceWith { root: None, nodes: vec![5] },
  180. // clone template
  181. CloneNodeChildren { id: Some(1), new_ids: vec![6, 7, 8] },
  182. // update template
  183. CreateTextNode { root: Some(9), text: "abc2" },
  184. SetLastNode { id: 7 },
  185. FirstChild {},
  186. ReplaceWith { root: None, nodes: vec![9] },
  187. // clone template
  188. CloneNodeChildren { id: Some(1), new_ids: vec![10, 11, 12] },
  189. // update template
  190. CreateTextNode { root: Some(13), text: "abc3" },
  191. SetLastNode { id: 11 },
  192. FirstChild {},
  193. ReplaceWith { root: None, nodes: vec![13] },
  194. // add to root
  195. AppendChildren { root: Some(0), children: vec![2, 3, 4, 6, 7, 8, 10, 11, 12] }
  196. ]
  197. );
  198. }
  199. #[test]
  200. fn anchors() {
  201. static App: Component = |cx| {
  202. cx.render(rsx! {
  203. {true.then(|| rsx!{ div { "hello" } })}
  204. {false.then(|| rsx!{ div { "goodbye" } })}
  205. })
  206. };
  207. let mut dom = new_dom(App, ());
  208. let mutations = dom.rebuild();
  209. assert_eq!(
  210. mutations.edits,
  211. [
  212. // create template
  213. CreateElement { root: Some(1), tag: "template", children: 1 },
  214. CreateElement { root: None, tag: "div", children: 1 },
  215. CreateTextNode { root: None, text: "hello" },
  216. // clone template
  217. CloneNodeChildren { id: Some(1), new_ids: vec![2] },
  218. CreatePlaceholder { root: Some(3) },
  219. // add to root
  220. AppendChildren { root: Some(0), children: vec![2, 3] },
  221. ]
  222. );
  223. }