sink.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. use dioxus_autofmt::*;
  2. use proc_macro2::TokenStream as TokenStream2;
  3. use syn::{Attribute, Meta};
  4. fn test_block(wrong: &str, right: &str) {
  5. let formatted = fmt_block(wrong).unwrap();
  6. assert_eq!(formatted, right);
  7. }
  8. fn print_block(wrong: &str) {
  9. let formatted = fmt_block(wrong).unwrap();
  10. println!("{}", formatted);
  11. }
  12. #[test]
  13. fn formats_block() {
  14. let block = r#"
  15. div {
  16. div {
  17. class: "asd",
  18. class: "asd",class: "asd",class: "asd",class: "asd",class: "asd",
  19. key: "ddd",
  20. onclick: move |_| {
  21. let blah = 120;
  22. true
  23. },
  24. blah: 123,
  25. onclick: move |_| {
  26. let blah = 120;
  27. true
  28. },
  29. onclick: move |_| {
  30. let blah = 120;
  31. true
  32. },
  33. onclick: move |_| {
  34. let blah = 120;
  35. true
  36. },
  37. div {
  38. div {
  39. "hi"
  40. }
  41. h2 {
  42. class: "asd",
  43. }
  44. }
  45. Component {}
  46. Component<Generic> {}
  47. }
  48. }
  49. "#;
  50. let formatted = fmt_block(block).unwrap();
  51. println!("{formatted}");
  52. }
  53. #[test]
  54. fn parse_comment() {
  55. let block = r#"
  56. div {
  57. adsasd: "asd", // this is a comment
  58. }
  59. "#;
  60. let parsed: TokenStream2 = syn::parse_str(block).unwrap();
  61. dbg!(parsed);
  62. }
  63. #[test]
  64. fn print_cases() {
  65. print_block(
  66. r#"
  67. div {
  68. adsasd: "asd",
  69. h1 {"asd"}
  70. div {
  71. div {
  72. "hello"
  73. }
  74. div {
  75. "goodbye"
  76. }
  77. div { class: "broccoli",
  78. div {
  79. "hi"
  80. }
  81. }
  82. div { class: "broccolibroccolibroccolibroccolibroccolibroccolibroccolibroccolibroccolibroccoli",
  83. div {
  84. "hi"
  85. }
  86. }
  87. div { class: "alksdjasd", onclick: move |_| {
  88. // hi!
  89. liberty!();
  90. },
  91. div {
  92. "hi"
  93. }
  94. }
  95. commented {
  96. // is unparalled
  97. class: "asdasd",
  98. // My genius
  99. div {
  100. "hi"
  101. }
  102. div {
  103. }
  104. }
  105. }
  106. }
  107. "#,
  108. );
  109. }
  110. #[test]
  111. fn format_comments() {
  112. let block = r#"
  113. div {
  114. adsasd: "asd", block: "asd",
  115. // this is a comment
  116. "hello"
  117. // this is a comment 1
  118. // this is a comment 2
  119. "hello"
  120. div {
  121. // this is a comment
  122. "hello"
  123. }
  124. div {
  125. // empty space
  126. }
  127. }
  128. "#;
  129. let formatted = fmt_block(block).unwrap();
  130. println!("{formatted}");
  131. }
  132. #[test]
  133. fn formats_component() {
  134. let block = r#"
  135. Component {
  136. adsasd: "asd", // this is a comment
  137. onclick: move |_| {
  138. let blah = 120;
  139. let blah = 120;
  140. },
  141. }
  142. "#;
  143. let formatted = fmt_block(block).unwrap();
  144. println!("{formatted}");
  145. }
  146. #[test]
  147. fn formats_element() {
  148. let block = r#"
  149. div {
  150. a: "1234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910",
  151. a: "123",
  152. a: "123",
  153. a: "123",
  154. a: "123",
  155. a: "123",
  156. a: "123",
  157. a: "123",
  158. a: "123",
  159. }
  160. "#;
  161. let formatted = fmt_block(block).unwrap();
  162. println!("{formatted}");
  163. }
  164. #[test]
  165. fn formats_element_short() {
  166. let block = r#"
  167. div {
  168. a: "123",
  169. a: "123",
  170. a: "123",
  171. a: "123",
  172. a: "123",
  173. a: "123",
  174. a: "123",
  175. a: "123",
  176. a: "123",
  177. }
  178. "#;
  179. let formatted = fmt_block(block).unwrap();
  180. println!("{formatted}");
  181. }
  182. #[test]
  183. fn formats_element_nested() {
  184. let block = r#"
  185. h3 {
  186. class: "mb-2 text-xl font-bold",
  187. "Invite Member"
  188. }
  189. "#;
  190. let formatted = fmt_block(block).unwrap();
  191. assert_eq!(
  192. formatted,
  193. r#"h3 { class: "mb-2 text-xl font-bold", "Invite Member" }"#
  194. );
  195. }
  196. #[test]
  197. fn formats_element_props_on_top() {
  198. let block = r#"
  199. h3 {
  200. class: "mb-2 text-xl font-bold mb-2 text-xl font-bold mb-2 text-xl font-bold mb-2 text-xl font-bold mb-2 text-xl font-bold",
  201. "Invite Member"
  202. }
  203. "#;
  204. let formatted = fmt_block(block).unwrap();
  205. println!("{formatted}");
  206. }
  207. #[test]
  208. fn formats_element_nested_no_trailing_tabs() {
  209. let block = r#"
  210. img { class: "mb-6 mx-auto h-24", src: "artemis-assets/images/friends.png", alt: "", }
  211. "#;
  212. let formatted = fmt_block(block).unwrap();
  213. assert_eq!(
  214. formatted,
  215. r#"img { class: "mb-6 mx-auto h-24", src: "artemis-assets/images/friends.png", alt: "" }"#
  216. );
  217. }
  218. #[test]
  219. fn formats_element_with_correct_indent() {
  220. let block = r###"
  221. div {
  222. a { class: "py-2 px-3 bg-indigo-500 hover:bg-indigo-600 rounded text-xs text-white", href: "#",
  223. "Send invitation"
  224. }
  225. }
  226. "###;
  227. let formatted = fmt_block(block).unwrap();
  228. println!("{formatted}");
  229. }
  230. #[test]
  231. fn small_elements_and_text_are_small() {
  232. let block = r###"
  233. a { class: "text-white",
  234. "Send invitation"
  235. }
  236. "###;
  237. let formatted = fmt_block(block).unwrap();
  238. assert_eq!(formatted, r#"a { class: "text-white", "Send invitation" }"#);
  239. }
  240. #[test]
  241. fn formats_component_man_props() {
  242. let block = r#"
  243. Component {
  244. ..MyProps {
  245. val: 123
  246. },
  247. adsasd: "asd", // this is a comment
  248. onclick: move |_| {
  249. let blah = 120;
  250. },
  251. }
  252. "#;
  253. let formatted = fmt_block(block).unwrap();
  254. println!("{formatted}");
  255. }
  256. #[test]
  257. fn formats_component_tiny() {
  258. let block = r#"
  259. Component { a: 123
  260. }
  261. "#;
  262. let formatted = fmt_block(block).unwrap();
  263. println!("{formatted}");
  264. }
  265. #[test]
  266. fn formats_exprs() {
  267. let block = r#"
  268. ul {
  269. div {}
  270. (0..10).map(|f| rsx! {
  271. li { "hi" }
  272. })
  273. div {}
  274. }
  275. "#;
  276. let formatted = fmt_block(block).unwrap();
  277. println!("{formatted}");
  278. }
  279. #[test]
  280. fn formats_exprs_neg_indent() {
  281. let block = r#"
  282. ul {
  283. (0..10).map(|f| rsx!{
  284. li {
  285. "hi"
  286. }
  287. })
  288. }
  289. "#;
  290. let formatted = fmt_block(block).unwrap();
  291. println!("{formatted}");
  292. }
  293. #[test]
  294. fn formats_exprs_handlers() {
  295. let block = r#"
  296. button {
  297. class: "flex items-center pl-3 py-3 pr-2 text-gray-500 hover:bg-indigo-50 rounded",
  298. onclick: move |evt| {
  299. show_user_menu.set(!show_user_menu.get()); evt.cancel_bubble(); },
  300. onclick: move |evt|
  301. show_user_menu.set(!show_user_menu.get()),
  302. span { class: "inline-block mr-4",
  303. icons::icon_14 {}
  304. }
  305. span { "Settings" }
  306. }
  307. "#;
  308. let formatted = fmt_block(block).unwrap();
  309. println!("{formatted}");
  310. }
  311. #[test]
  312. fn formats_complex() {
  313. let block = r#"
  314. li {
  315. Link {
  316. class: "flex items-center pl-3 py-3 pr-4 {active_class} rounded",
  317. to: "{to}",
  318. span { class: "inline-block mr-3",
  319. icons::icon_0 {}
  320. }
  321. span { "{name}" }
  322. children.is_some().then(|| rsx!{
  323. span {
  324. class: "inline-block ml-auto hover:bg-gray-500",
  325. onclick: move |evt| {
  326. // open.set(!open.get());
  327. evt.cancel_bubble();
  328. },
  329. icons::icon_8 {}
  330. }
  331. })
  332. }
  333. div {
  334. class: "px-4",
  335. is_current.then(|| rsx!{ children })
  336. // open.then(|| rsx!{ children })
  337. }
  338. }
  339. "#;
  340. let formatted = fmt_block(block).unwrap();
  341. println!("{formatted}");
  342. }
  343. #[test]
  344. fn formats_document() {
  345. let block = r#"
  346. rsx!{
  347. Component {
  348. adsasd: "asd", // this is a comment
  349. onclick: move |_| {
  350. let blah = 120;
  351. },
  352. }
  353. }
  354. "#;
  355. let formatted = fmt_file(block);
  356. println!("{formatted:?}");
  357. }
  358. #[test]
  359. fn component_path_mod_style() {
  360. let block = r#"
  361. rsx!{
  362. my::thing::Component {
  363. adsasd: "asd", // this is a comment
  364. onclick: move |_| {
  365. let blah = 120;
  366. },
  367. }
  368. }
  369. "#;
  370. let formatted = fmt_file(block);
  371. println!("{formatted:?}");
  372. }
  373. #[test]
  374. fn formats_valid_rust_src() {
  375. let src = r#"
  376. //
  377. rsx! {
  378. div {}
  379. div {
  380. h3 {"asd"
  381. }
  382. }
  383. }
  384. "#;
  385. let formatted = fmt_file(src);
  386. println!("{formatted:?}");
  387. }
  388. #[test]
  389. fn formats_valid_rust_src_with_indents() {
  390. let mut src = r#"
  391. #[inline_props]
  392. fn NavItem<'a>(cx: Scope, to: &'static str, children: Element<'a>, icon: Shape) -> Element {
  393. const ICON_SIZE: u32 = 36;
  394. rsx! {
  395. div {
  396. h1 {"thing"}
  397. }
  398. }
  399. }
  400. "#
  401. .to_string();
  402. let formatted = fmt_file(&src);
  403. let block = formatted.into_iter().next().unwrap();
  404. src.replace_range(
  405. block.start - 1..block.end + 1,
  406. &format!("{{ {} }}", &block.formatted),
  407. );
  408. }
  409. #[test]
  410. fn formats_multiple_blocks() {
  411. let mut src = r#"
  412. #[inline_props]
  413. fn NavItem<'a>(cx: Scope, to: &'static str, children: Element<'a>, icon: Shape) -> Element {
  414. const ICON_SIZE: u32 = 36;
  415. rsx! {
  416. div {
  417. h1 {"thing"}
  418. }
  419. }
  420. rsx! {
  421. div {
  422. Ball {
  423. a: rsx!{
  424. "asdasd"
  425. }
  426. }
  427. }
  428. }
  429. }
  430. #[inline_props]
  431. fn NavItem<'a>(cx: Scope, to: &'static str, children: Element<'a>, icon: Shape) -> Element {
  432. const ICON_SIZE: u32 = 36;
  433. rsx! {
  434. div {
  435. h1 {"thing"}
  436. }
  437. }
  438. rsx! {
  439. div {
  440. Ball {
  441. a: rsx!{
  442. "asdasd"
  443. }
  444. }
  445. }
  446. }
  447. }
  448. "#
  449. .to_string();
  450. let formatted = fmt_file(&src);
  451. dbg!(&formatted);
  452. let block = formatted.into_iter().next().unwrap();
  453. src.replace_range(
  454. block.start - 1..block.end + 1,
  455. &format!("{{ {} }}", &block.formatted),
  456. );
  457. }
  458. #[test]
  459. fn empty_blocks() {
  460. let mut src = r###"
  461. pub fn Alert(cx: Scope) -> Element {
  462. cx.render(rsx! {
  463. div { }
  464. })
  465. }
  466. "###
  467. .to_string();
  468. let formatted = fmt_file(&src);
  469. dbg!(&formatted);
  470. }