create_dom.rs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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: 'static + Send>(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 {
  33. root: 0,
  34. tag: "div"
  35. },
  36. CreateElement {
  37. root: 1,
  38. tag: "div"
  39. },
  40. CreateTextNode {
  41. root: 2,
  42. text: "Hello, world!"
  43. },
  44. AppendChildren { many: 1 },
  45. AppendChildren { many: 1 },
  46. AppendChildren { many: 1 },
  47. ]
  48. );
  49. }
  50. #[test]
  51. fn create() {
  52. static APP: FC<()> = |(cx, props)| {
  53. cx.render(rsx! {
  54. div {
  55. div {
  56. "Hello, world!"
  57. div {
  58. div {
  59. Fragment {
  60. "hello"
  61. "world"
  62. }
  63. }
  64. }
  65. }
  66. }
  67. })
  68. };
  69. let mut dom = new_dom(APP, ());
  70. let mutations = dom.rebuild();
  71. assert_eq!(
  72. mutations.edits,
  73. [
  74. CreateElement {
  75. root: 0,
  76. tag: "div"
  77. },
  78. CreateElement {
  79. root: 1,
  80. tag: "div"
  81. },
  82. CreateTextNode {
  83. root: 2,
  84. text: "Hello, world!"
  85. },
  86. CreateElement {
  87. root: 3,
  88. tag: "div"
  89. },
  90. CreateElement {
  91. root: 4,
  92. tag: "div"
  93. },
  94. CreateTextNode {
  95. root: 5,
  96. text: "hello"
  97. },
  98. CreateTextNode {
  99. root: 6,
  100. text: "world"
  101. },
  102. AppendChildren { many: 2 },
  103. AppendChildren { many: 1 },
  104. AppendChildren { many: 2 },
  105. AppendChildren { many: 1 },
  106. AppendChildren { many: 1 },
  107. ]
  108. );
  109. }
  110. #[test]
  111. fn create_list() {
  112. static APP: FC<()> = |(cx, props)| {
  113. cx.render(rsx! {
  114. {(0..3).map(|f| rsx!{ div {
  115. "hello"
  116. }})}
  117. })
  118. };
  119. let mut dom = new_dom(APP, ());
  120. let mutations = dom.rebuild();
  121. // copilot wrote this test :P
  122. assert_eq!(
  123. mutations.edits,
  124. [
  125. CreateElement {
  126. root: 0,
  127. tag: "div"
  128. },
  129. CreateTextNode {
  130. root: 1,
  131. text: "hello"
  132. },
  133. AppendChildren { many: 1 },
  134. CreateElement {
  135. root: 2,
  136. tag: "div"
  137. },
  138. CreateTextNode {
  139. root: 3,
  140. text: "hello"
  141. },
  142. AppendChildren { many: 1 },
  143. CreateElement {
  144. root: 4,
  145. tag: "div"
  146. },
  147. CreateTextNode {
  148. root: 5,
  149. text: "hello"
  150. },
  151. AppendChildren { many: 1 },
  152. AppendChildren { many: 3 },
  153. ]
  154. );
  155. }
  156. #[test]
  157. fn create_simple() {
  158. static APP: FC<()> = |(cx, props)| {
  159. cx.render(rsx! {
  160. div {}
  161. div {}
  162. div {}
  163. div {}
  164. })
  165. };
  166. let mut dom = new_dom(APP, ());
  167. let mutations = dom.rebuild();
  168. // copilot wrote this test :P
  169. assert_eq!(
  170. mutations.edits,
  171. [
  172. CreateElement {
  173. root: 0,
  174. tag: "div"
  175. },
  176. CreateElement {
  177. root: 1,
  178. tag: "div"
  179. },
  180. CreateElement {
  181. root: 2,
  182. tag: "div"
  183. },
  184. CreateElement {
  185. root: 3,
  186. tag: "div"
  187. },
  188. AppendChildren { many: 4 },
  189. ]
  190. );
  191. }
  192. #[test]
  193. fn create_components() {
  194. static App: FC<()> = |(cx, props)| {
  195. cx.render(rsx! {
  196. Child { "abc1" }
  197. Child { "abc2" }
  198. Child { "abc3" }
  199. })
  200. };
  201. static Child: FC<()> = |(cx, props)| {
  202. cx.render(rsx! {
  203. h1 {}
  204. div { {cx.children()} }
  205. p {}
  206. })
  207. };
  208. let mut dom = new_dom(App, ());
  209. let mutations = dom.rebuild();
  210. assert_eq!(
  211. mutations.edits,
  212. [
  213. CreateElement { root: 0, tag: "h1" },
  214. CreateElement {
  215. root: 1,
  216. tag: "div"
  217. },
  218. CreateTextNode {
  219. root: 2,
  220. text: "abc1"
  221. },
  222. AppendChildren { many: 1 },
  223. CreateElement { root: 3, tag: "p" },
  224. CreateElement { root: 4, tag: "h1" },
  225. CreateElement {
  226. root: 5,
  227. tag: "div"
  228. },
  229. CreateTextNode {
  230. root: 6,
  231. text: "abc2"
  232. },
  233. AppendChildren { many: 1 },
  234. CreateElement { root: 7, tag: "p" },
  235. CreateElement { root: 8, tag: "h1" },
  236. CreateElement {
  237. root: 9,
  238. tag: "div"
  239. },
  240. CreateTextNode {
  241. root: 10,
  242. text: "abc3"
  243. },
  244. AppendChildren { many: 1 },
  245. CreateElement { root: 11, tag: "p" },
  246. AppendChildren { many: 9 },
  247. ]
  248. );
  249. }
  250. #[test]
  251. fn anchors() {
  252. static App: FC<()> = |(cx, props)| {
  253. cx.render(rsx! {
  254. {true.then(|| rsx!{ div { "hello" } })}
  255. {false.then(|| rsx!{ div { "goodbye" } })}
  256. })
  257. };
  258. let mut dom = new_dom(App, ());
  259. let mutations = dom.rebuild();
  260. assert_eq!(
  261. mutations.edits,
  262. [
  263. CreateElement {
  264. root: 0,
  265. tag: "div"
  266. },
  267. CreateTextNode {
  268. root: 1,
  269. text: "hello"
  270. },
  271. AppendChildren { many: 1 },
  272. CreatePlaceholder { root: 2 },
  273. AppendChildren { many: 2 },
  274. ]
  275. );
  276. }
  277. #[test]
  278. fn suspended() {
  279. static App: FC<()> = |(cx, props)| {
  280. let val = use_suspense(
  281. cx,
  282. || async {
  283. //
  284. },
  285. |cx, p| cx.render(rsx! { "hi "}),
  286. );
  287. cx.render(rsx! { {val} })
  288. };
  289. let mut dom = new_dom(App, ());
  290. let mutations = dom.rebuild();
  291. assert_eq!(
  292. mutations.edits,
  293. [CreatePlaceholder { root: 0 }, AppendChildren { many: 1 },]
  294. );
  295. }