peristant_iterator.rs 8.4 KB

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