peristant_iterator.rs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. use dioxus_native_core::{
  2. real_dom::{NodeType, RealDom},
  3. state::State,
  4. utils::PersistantElementIter,
  5. };
  6. use dioxus_native_core_macro::State;
  7. #[derive(State, Default, Clone)]
  8. struct Empty {}
  9. #[test]
  10. #[allow(unused_variables)]
  11. fn traverse() {
  12. use dioxus_core::*;
  13. use dioxus_core_macro::*;
  14. use dioxus_html as dioxus_elements;
  15. #[allow(non_snake_case)]
  16. fn Base(cx: Scope) -> Element {
  17. rsx!(cx, div {})
  18. }
  19. let vdom = VirtualDom::new(Base);
  20. let mutations = vdom.create_vnodes(rsx! {
  21. div{
  22. div{
  23. "hello"
  24. p{
  25. "world"
  26. }
  27. "hello world"
  28. }
  29. }
  30. });
  31. let mut rdom: RealDom<Empty> = RealDom::new();
  32. let _to_update = rdom.apply_mutations(vec![mutations]);
  33. let mut iter = PersistantElementIter::new();
  34. let div_tag = "div".to_string();
  35. assert!(matches!(
  36. &rdom[iter.next(&rdom).id()].node_type,
  37. NodeType::Element { tag: div_tag, .. }
  38. ));
  39. assert!(matches!(
  40. &rdom[iter.next(&rdom).id()].node_type,
  41. NodeType::Element { tag: div_tag, .. }
  42. ));
  43. let text1 = "hello".to_string();
  44. assert!(matches!(
  45. &rdom[iter.next(&rdom).id()].node_type,
  46. NodeType::Text { text: text1, .. }
  47. ));
  48. let p_tag = "p".to_string();
  49. assert!(matches!(
  50. &rdom[iter.next(&rdom).id()].node_type,
  51. NodeType::Element { tag: p_tag, .. }
  52. ));
  53. let text2 = "world".to_string();
  54. assert!(matches!(
  55. &rdom[iter.next(&rdom).id()].node_type,
  56. NodeType::Text { text: text2, .. }
  57. ));
  58. let text3 = "hello world".to_string();
  59. assert!(matches!(
  60. &rdom[iter.next(&rdom).id()].node_type,
  61. NodeType::Text { text: text3, .. }
  62. ));
  63. assert!(matches!(
  64. &rdom[iter.next(&rdom).id()].node_type,
  65. NodeType::Element { tag: div_tag, .. }
  66. ));
  67. assert!(matches!(
  68. &rdom[iter.prev(&rdom).id()].node_type,
  69. NodeType::Text { text: text3, .. }
  70. ));
  71. assert!(matches!(
  72. &rdom[iter.prev(&rdom).id()].node_type,
  73. NodeType::Text { text: text2, .. }
  74. ));
  75. assert!(matches!(
  76. &rdom[iter.prev(&rdom).id()].node_type,
  77. NodeType::Element { tag: p_tag, .. }
  78. ));
  79. assert!(matches!(
  80. &rdom[iter.prev(&rdom).id()].node_type,
  81. NodeType::Text { text: text1, .. }
  82. ));
  83. assert!(matches!(
  84. &rdom[iter.prev(&rdom).id()].node_type,
  85. NodeType::Element { tag: div_tag, .. }
  86. ));
  87. assert!(matches!(
  88. &rdom[iter.prev(&rdom).id()].node_type,
  89. NodeType::Element { tag: div_tag, .. }
  90. ));
  91. assert!(matches!(
  92. &rdom[iter.prev(&rdom).id()].node_type,
  93. NodeType::Element { tag: div_tag, .. }
  94. ));
  95. assert!(matches!(
  96. &rdom[iter.prev(&rdom).id()].node_type,
  97. NodeType::Text { text: text3, .. }
  98. ));
  99. }
  100. #[test]
  101. #[allow(unused_variables)]
  102. fn persist_removes() {
  103. use dioxus_core::VNode;
  104. use dioxus_core::*;
  105. use dioxus_core_macro::*;
  106. use dioxus_html as dioxus_elements;
  107. #[allow(non_snake_case)]
  108. fn Base(cx: Scope) -> Element {
  109. rsx!(cx, div {})
  110. }
  111. let vdom = VirtualDom::new(Base);
  112. let (build, update) = vdom.diff_lazynodes(
  113. rsx! {
  114. div{
  115. p{
  116. key: "1",
  117. "hello"
  118. }
  119. p{
  120. key: "2",
  121. "world"
  122. }
  123. p{
  124. key: "3",
  125. "hello world"
  126. }
  127. }
  128. },
  129. rsx! {
  130. div{
  131. p{
  132. key: "1",
  133. "hello"
  134. }
  135. p{
  136. key: "3",
  137. "hello world"
  138. }
  139. }
  140. },
  141. );
  142. let mut rdom: RealDom<Empty> = RealDom::new();
  143. let _to_update = rdom.apply_mutations(vec![build]);
  144. // this will end on the node that is removed
  145. let mut iter1 = PersistantElementIter::new();
  146. // this will end on the after node that is removed
  147. let mut iter2 = PersistantElementIter::new();
  148. // div
  149. iter1.next(&rdom).id();
  150. iter2.next(&rdom).id();
  151. // p
  152. iter1.next(&rdom).id();
  153. iter2.next(&rdom).id();
  154. // "hello"
  155. iter1.next(&rdom).id();
  156. iter2.next(&rdom).id();
  157. // p
  158. iter1.next(&rdom).id();
  159. iter2.next(&rdom).id();
  160. // "world"
  161. iter1.next(&rdom).id();
  162. iter2.next(&rdom).id();
  163. // p
  164. iter2.next(&rdom).id();
  165. // "hello world"
  166. iter2.next(&rdom).id();
  167. iter1.prune(&update, &rdom);
  168. iter2.prune(&update, &rdom);
  169. let _to_update = rdom.apply_mutations(vec![update]);
  170. let p_tag = "p".to_string();
  171. let idx = iter1.next(&rdom).id();
  172. assert!(matches!(
  173. &rdom[idx].node_type,
  174. NodeType::Element { tag: p_tag, .. }
  175. ));
  176. let text = "hello world".to_string();
  177. let idx = iter1.next(&rdom).id();
  178. assert!(matches!(&rdom[idx].node_type, NodeType::Text { text, .. }));
  179. let div_tag = "div".to_string();
  180. let idx = iter2.next(&rdom).id();
  181. assert!(matches!(
  182. &rdom[idx].node_type,
  183. NodeType::Element { tag: div_tag, .. }
  184. ));
  185. }
  186. #[test]
  187. #[allow(unused_variables)]
  188. fn persist_instertions_before() {
  189. use dioxus_core::*;
  190. use dioxus_core_macro::*;
  191. use dioxus_html as dioxus_elements;
  192. #[allow(non_snake_case)]
  193. fn Base(cx: Scope) -> Element {
  194. rsx!(cx, div {})
  195. }
  196. let vdom = VirtualDom::new(Base);
  197. let (build, update) = vdom.diff_lazynodes(
  198. rsx! {
  199. div{
  200. p{
  201. key: "1",
  202. "hello"
  203. }
  204. p{
  205. key: "3",
  206. "hello world"
  207. }
  208. }
  209. },
  210. rsx! {
  211. div{
  212. p{
  213. key: "1",
  214. "hello"
  215. }
  216. p{
  217. key: "2",
  218. "world"
  219. }
  220. p{
  221. key: "3",
  222. "hello world"
  223. }
  224. }
  225. },
  226. );
  227. let mut rdom: RealDom<Empty> = RealDom::new();
  228. let _to_update = rdom.apply_mutations(vec![build]);
  229. let mut iter = PersistantElementIter::new();
  230. // div
  231. iter.next(&rdom).id();
  232. // p
  233. iter.next(&rdom).id();
  234. // "hello"
  235. iter.next(&rdom).id();
  236. // p
  237. iter.next(&rdom).id();
  238. // "hello world"
  239. iter.next(&rdom).id();
  240. iter.prune(&update, &rdom);
  241. let _to_update = rdom.apply_mutations(vec![update]);
  242. let p_tag = "div".to_string();
  243. let idx = iter.next(&rdom).id();
  244. assert!(matches!(
  245. &rdom[idx].node_type,
  246. NodeType::Element { tag: p_tag, .. }
  247. ));
  248. }
  249. #[test]
  250. #[allow(unused_variables)]
  251. fn persist_instertions_after() {
  252. use dioxus_core::*;
  253. use dioxus_core_macro::*;
  254. use dioxus_html as dioxus_elements;
  255. #[allow(non_snake_case)]
  256. fn Base(cx: Scope) -> Element {
  257. rsx!(cx, div {})
  258. }
  259. let vdom = VirtualDom::new(Base);
  260. let (build, update) = vdom.diff_lazynodes(
  261. rsx! {
  262. div{
  263. p{
  264. key: "1",
  265. "hello"
  266. }
  267. p{
  268. key: "2",
  269. "world"
  270. }
  271. }
  272. },
  273. rsx! {
  274. div{
  275. p{
  276. key: "1",
  277. "hello"
  278. }
  279. p{
  280. key: "2",
  281. "world"
  282. }
  283. p{
  284. key: "3",
  285. "hello world"
  286. }
  287. }
  288. },
  289. );
  290. let mut rdom: RealDom<Empty> = RealDom::new();
  291. let _to_update = rdom.apply_mutations(vec![build]);
  292. let mut iter = PersistantElementIter::new();
  293. // div
  294. iter.next(&rdom).id();
  295. // p
  296. iter.next(&rdom).id();
  297. // "hello"
  298. iter.next(&rdom).id();
  299. // p
  300. iter.next(&rdom).id();
  301. // "world"
  302. iter.next(&rdom).id();
  303. iter.prune(&update, &rdom);
  304. let _to_update = rdom.apply_mutations(vec![update]);
  305. let p_tag = "p".to_string();
  306. let idx = iter.next(&rdom).id();
  307. assert!(matches!(
  308. &rdom[idx].node_type,
  309. NodeType::Element { tag: p_tag, .. }
  310. ));
  311. let text = "hello world".to_string();
  312. let idx = iter.next(&rdom).id();
  313. assert!(matches!(&rdom[idx].node_type, NodeType::Text { text, .. }));
  314. }