hydration.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. use dioxus::prelude::*;
  2. #[test]
  3. fn root_ids() {
  4. fn app(cx: Scope) -> Element {
  5. render! { div { width: "100px" } }
  6. }
  7. let mut dom = VirtualDom::new(app);
  8. _ = dom.rebuild();
  9. assert_eq!(
  10. dioxus_ssr::pre_render(&dom),
  11. r#"<div style="width:100px;" data-node-hydration="0"></div>"#
  12. );
  13. }
  14. #[test]
  15. fn dynamic_attributes() {
  16. fn app(cx: Scope) -> Element {
  17. let dynamic = 123;
  18. render! {
  19. div { width: "100px", div { width: "{dynamic}px" } }
  20. }
  21. }
  22. let mut dom = VirtualDom::new(app);
  23. _ = dom.rebuild();
  24. assert_eq!(
  25. dioxus_ssr::pre_render(&dom),
  26. r#"<div style="width:100px;" data-node-hydration="0"><div style="width:123px;" data-node-hydration="1"></div></div>"#
  27. );
  28. }
  29. #[test]
  30. fn listeners() {
  31. fn app(cx: Scope) -> Element {
  32. render! {
  33. div { width: "100px", div { onclick: |_| {} } }
  34. }
  35. }
  36. let mut dom = VirtualDom::new(app);
  37. _ = dom.rebuild();
  38. assert_eq!(
  39. dioxus_ssr::pre_render(&dom),
  40. r#"<div style="width:100px;" data-node-hydration="0"><div data-node-hydration="1,click:1"></div></div>"#
  41. );
  42. fn app2(cx: Scope) -> Element {
  43. let dynamic = 123;
  44. render! {
  45. div { width: "100px", div { width: "{dynamic}px", onclick: |_| {} } }
  46. }
  47. }
  48. let mut dom = VirtualDom::new(app2);
  49. _ = dom.rebuild();
  50. assert_eq!(
  51. dioxus_ssr::pre_render(&dom),
  52. r#"<div style="width:100px;" data-node-hydration="0"><div style="width:123px;" data-node-hydration="1,click:1"></div></div>"#
  53. );
  54. }
  55. #[test]
  56. fn text_nodes() {
  57. fn app(cx: Scope) -> Element {
  58. let dynamic_text = "hello";
  59. render! {
  60. div { dynamic_text }
  61. }
  62. }
  63. let mut dom = VirtualDom::new(app);
  64. _ = dom.rebuild();
  65. assert_eq!(
  66. dioxus_ssr::pre_render(&dom),
  67. r#"<div data-node-hydration="0"><!--node-id1-->hello<!--#--></div>"#
  68. );
  69. fn app2(cx: Scope) -> Element {
  70. let dynamic = 123;
  71. render! {
  72. div { "{dynamic}", "{1234}" }
  73. }
  74. }
  75. let mut dom = VirtualDom::new(app2);
  76. _ = dom.rebuild();
  77. assert_eq!(
  78. dioxus_ssr::pre_render(&dom),
  79. r#"<div data-node-hydration="0"><!--node-id1-->123<!--#--><!--node-id2-->1234<!--#--></div>"#
  80. );
  81. }
  82. #[test]
  83. fn components_hydrate() {
  84. fn app(cx: Scope) -> Element {
  85. render! { Child {} }
  86. }
  87. fn Child(cx: Scope) -> Element {
  88. render! { div { "hello" } }
  89. }
  90. let mut dom = VirtualDom::new(app);
  91. _ = dom.rebuild();
  92. assert_eq!(
  93. dioxus_ssr::pre_render(&dom),
  94. r#"<div data-node-hydration="0">hello</div>"#
  95. );
  96. fn app2(cx: Scope) -> Element {
  97. render! { Child2 {} }
  98. }
  99. fn Child2(cx: Scope) -> Element {
  100. let dyn_text = "hello";
  101. render! {
  102. div { dyn_text }
  103. }
  104. }
  105. let mut dom = VirtualDom::new(app2);
  106. _ = dom.rebuild();
  107. assert_eq!(
  108. dioxus_ssr::pre_render(&dom),
  109. r#"<div data-node-hydration="0"><!--node-id1-->hello<!--#--></div>"#
  110. );
  111. fn app3(cx: Scope) -> Element {
  112. render! { Child3 {} }
  113. }
  114. fn Child3(cx: Scope) -> Element {
  115. render! { div { width: "{1}" } }
  116. }
  117. let mut dom = VirtualDom::new(app3);
  118. _ = dom.rebuild();
  119. assert_eq!(
  120. dioxus_ssr::pre_render(&dom),
  121. r#"<div style="width:1;" data-node-hydration="0"></div>"#
  122. );
  123. fn app4(cx: Scope) -> Element {
  124. render! { Child4 {} }
  125. }
  126. fn Child4(cx: Scope) -> Element {
  127. render! {
  128. for _ in 0..2 {
  129. render! {
  130. render! {
  131. "{1}"
  132. }
  133. }
  134. }
  135. }
  136. }
  137. let mut dom = VirtualDom::new(app4);
  138. _ = dom.rebuild();
  139. assert_eq!(
  140. dioxus_ssr::pre_render(&dom),
  141. r#"<!--node-id0-->1<!--#--><!--node-id1-->1<!--#-->"#
  142. );
  143. }
  144. #[test]
  145. fn hello_world_hydrates() {
  146. fn app(cx: Scope) -> Element {
  147. let mut count = use_state(cx, || 0);
  148. cx.render(rsx! {
  149. h1 { "High-Five counter: {count}" }
  150. button { onclick: move |_| count += 1, "Up high!" }
  151. button { onclick: move |_| count -= 1, "Down low!" }
  152. })
  153. }
  154. let mut dom = VirtualDom::new(app);
  155. _ = dbg!(dom.rebuild());
  156. assert_eq!(
  157. dioxus_ssr::pre_render(&dom),
  158. r#"<h1 data-node-hydration="0"><!--node-id1-->High-Five counter: 0<!--#--></h1><button data-node-hydration="2,click:1">Up high!</button><button data-node-hydration="3,click:1">Down low!</button>"#
  159. );
  160. }