1
0

parsing.rs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. use dioxus_rsx::CallBody;
  2. use quote::ToTokens;
  3. use prettier_please::PrettyUnparse;
  4. #[test]
  5. fn callbody_ctx() {
  6. let item = quote::quote! {
  7. div {
  8. h1 {
  9. id: "Some cool attribute {cool}"
  10. }
  11. for item in items {
  12. "Something {cool}"
  13. }
  14. Component {
  15. "Something {elseish}"
  16. }
  17. Component2 {
  18. "Something {Body}"
  19. Component3 {
  20. prop: "Something {Body3}",
  21. "Something {Body4}"
  22. }
  23. }
  24. something-cool {
  25. "Something {cool}ish"
  26. }
  27. if true {
  28. div {
  29. "hi! {cool}"
  30. }
  31. }
  32. "hi!"
  33. "goodbye!"
  34. }
  35. {some_expr}
  36. };
  37. let cb: CallBody = syn::parse2(item).unwrap();
  38. dbg!(cb.template_idx.get());
  39. }
  40. #[test]
  41. fn simple_case() {
  42. let item = quote::quote! {
  43. div {
  44. something: "cool",
  45. id: "Some cool attribute {cool}",
  46. class: "Some cool attribute {cool2}",
  47. "hi!"
  48. {some_expr}
  49. Component {
  50. boolish: true,
  51. otherish: 123,
  52. otherish2: 123.0,
  53. otherish3: "dang!",
  54. otherish3: "dang! {cool}",
  55. }
  56. }
  57. };
  58. let cb: CallBody = syn::parse2(item).unwrap();
  59. println!("{}", cb.to_token_stream().pretty_unparse());
  60. }
  61. #[test]
  62. fn complex_kitchen_sink() {
  63. let item = quote::quote! {
  64. // complex_carry
  65. button {
  66. class: "flex items-center pl-3 py-3 pr-2 text-gray-500 hover:bg-indigo-50 rounded",
  67. width: {"100%"}.to_string(),
  68. onclick: move |evt| {
  69. show_user_menu.set(!show_user_menu.get());
  70. evt.cancel_bubble();
  71. },
  72. onmousedown: move |evt| show_user_menu.set(!show_user_menu.get()),
  73. span { class: "inline-block mr-4", icons::icon_14 {} }
  74. span { "Settings" }
  75. }
  76. // Complex nesting with handlers
  77. li {
  78. Link {
  79. class: "flex items-center pl-3 py-3 pr-4 {active_class} rounded",
  80. to: "{to}",
  81. span { class: "inline-block mr-3", icons::icon_0 {} }
  82. span { "{name}" }
  83. {children.is_some().then(|| rsx! {
  84. span {
  85. class: "inline-block ml-auto hover:bg-gray-500",
  86. onclick: move |evt| {
  87. // open.set(!open.get());
  88. evt.cancel_bubble();
  89. },
  90. icons::icon_8 {}
  91. }
  92. })}
  93. }
  94. div { class: "px-4", {is_current.then(|| rsx! { children })} }
  95. }
  96. // No nesting
  97. Component {
  98. adsasd: "asd",
  99. onclick: move |_| {
  100. let blah = 120;
  101. }
  102. }
  103. // No nesting
  104. Component {
  105. adsasd: "asd",
  106. onclick: {
  107. let a = 1;
  108. move |_| {
  109. let blah = 120;
  110. }
  111. }
  112. }
  113. // Component path
  114. my::thing::Component {
  115. adsasd: "asd",
  116. onclick: move |_| {
  117. let blah = 120;
  118. }
  119. }
  120. for i in 0..10 {
  121. Component { key: "{i}", blah: 120 }
  122. }
  123. for i in 0..10 {
  124. Component { key: "{i}" }
  125. }
  126. for i in 0..10 {
  127. div { key: "{i}", blah: 120 }
  128. }
  129. for i in 0..10 {
  130. div { key: "{i}" }
  131. }
  132. div {
  133. "asdbascasdbasd"
  134. "asbdasbdabsd"
  135. {asbdabsdbasdbas}
  136. }
  137. };
  138. let _cb: CallBody = syn::parse2(item).unwrap();
  139. }
  140. #[test]
  141. fn key_must_be_formatted() {
  142. let item = quote::quote! {
  143. div {
  144. key: value
  145. }
  146. };
  147. let parsed = syn::parse2::<CallBody>(item).unwrap();
  148. println!("{:?}", parsed.body.diagnostics);
  149. assert!(!parsed.body.diagnostics.is_empty());
  150. }
  151. #[test]
  152. fn key_cannot_be_static() {
  153. let item = quote::quote! {
  154. div {
  155. key: "hello world"
  156. }
  157. };
  158. let parsed = syn::parse2::<CallBody>(item).unwrap();
  159. println!("{:?}", parsed.body.diagnostics);
  160. assert!(!parsed.body.diagnostics.is_empty());
  161. }
  162. #[test]
  163. fn braced_expressions() {
  164. let item = quote::quote! {
  165. div {
  166. width: {100} - 50,
  167. width: {"100%"}.to_string(),
  168. width: {|| "100%"}(),
  169. }
  170. // Partial expressions in braces rsx should be allowed and output as-is
  171. // for autocomplete
  172. {partial.}
  173. div {}
  174. {partial.}
  175. // Comments should be ignored
  176. div {}
  177. {partial.}
  178. "hello world"
  179. {partial.}
  180. if true {}
  181. };
  182. let _cb: CallBody = syn::parse2(item).unwrap();
  183. }