create_dom.rs 6.5 KB

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