parsing.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. // Component path
  104. my::thing::Component {
  105. adsasd: "asd",
  106. onclick: move |_| {
  107. let blah = 120;
  108. }
  109. }
  110. for i in 0..10 {
  111. Component { key: "{i}", blah: 120 }
  112. }
  113. for i in 0..10 {
  114. Component { key: "{i}" }
  115. }
  116. for i in 0..10 {
  117. div { key: "{i}", blah: 120 }
  118. }
  119. for i in 0..10 {
  120. div { key: "{i}" }
  121. }
  122. div {
  123. "asdbascasdbasd"
  124. "asbdasbdabsd"
  125. {asbdabsdbasdbas}
  126. }
  127. };
  128. let _cb: CallBody = syn::parse2(item).unwrap();
  129. }
  130. #[test]
  131. fn key_must_be_formatted() {
  132. let item = quote::quote! {
  133. div {
  134. key: value
  135. }
  136. };
  137. let parsed = syn::parse2::<CallBody>(item).unwrap();
  138. println!("{:?}", parsed.body.diagnostics);
  139. assert!(!parsed.body.diagnostics.is_empty());
  140. }
  141. #[test]
  142. fn key_cannot_be_static() {
  143. let item = quote::quote! {
  144. div {
  145. key: "hello world"
  146. }
  147. };
  148. let parsed = syn::parse2::<CallBody>(item).unwrap();
  149. println!("{:?}", parsed.body.diagnostics);
  150. assert!(!parsed.body.diagnostics.is_empty());
  151. }
  152. #[test]
  153. fn braced_expressions() {
  154. let item = quote::quote! {
  155. div {
  156. width: {100} - 50,
  157. width: {"100%"}.to_string(),
  158. width: {|| "100%"}(),
  159. }
  160. // Partial expressions in braces rsx should be allowed and output as-is
  161. // for autocomplete
  162. {partial.}
  163. div {}
  164. {partial.}
  165. // Comments should be ignored
  166. div {}
  167. {partial.}
  168. "hello world"
  169. {partial.}
  170. if true {}
  171. };
  172. let _cb: CallBody = syn::parse2(item).unwrap();
  173. }