create_dom.rs 6.4 KB

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