diff --git a/examples/readme.rs b/examples/readme.rs index d7a2363c9..4f4250343 100644 --- a/examples/readme.rs +++ b/examples/readme.rs @@ -11,14 +11,6 @@ fn main() { fn app(cx: Scope) -> Element { let mut count = use_state(&cx, || 0); - let a = rsx! { - div { - - - key: "a" - } - }; - cx.render(rsx! { h1 { "High-Five counter: {count}" } button { onclick: move |_| count += 1, "Up high!" } diff --git a/packages/autofmt/src/lib.rs b/packages/autofmt/src/lib.rs index bae0b0bd1..5b95e989a 100644 --- a/packages/autofmt/src/lib.rs +++ b/packages/autofmt/src/lib.rs @@ -71,9 +71,9 @@ pub fn fmt_block(block: &str) -> Option { ..Buffer::default() }; - for node in syn::parse_str::(block).ok()?.roots { - buf.write_ident(&node).ok()?; - } + let body = syn::parse_str::(block).unwrap(); + + buf.write_body_indented(&body.roots).unwrap(); buf.consume() } diff --git a/packages/autofmt/tests/sample.rs b/packages/autofmt/tests/sample.rs new file mode 100644 index 000000000..6b6b7d244 --- /dev/null +++ b/packages/autofmt/tests/sample.rs @@ -0,0 +1,23 @@ +const SRC: &str = include_str!("./samples/all.rs"); + +fn body() -> &'static str { + &SRC[6..SRC.len() - 3] +} + +fn unindented_body() -> String { + body() + .lines() + .map(|line| match line.strip_prefix(" ") { + Some(line) => line, + None => line, + }) + .collect::>() + .join("\n") +} + +#[test] +fn way_and_back() { + let blocks = dioxus_autofmt::fmt_file(SRC).into_iter().next().unwrap(); + + println!("{}", blocks.formatted); +} diff --git a/packages/autofmt/tests/samples/all.rs b/packages/autofmt/tests/samples/all.rs new file mode 100644 index 000000000..b0899709c --- /dev/null +++ b/packages/autofmt/tests/samples/all.rs @@ -0,0 +1,225 @@ +rsx! { + // Simple case + div { key: "a", class: "ban", style: "color: red" } + + // Many attributes + div { + div { + key: "ddd", + class: "asd", + class: "asd", + class: "asd", + class: "asd", + class: "asd", + class: "asd", + blah: 123, + onclick: move |_| { + let blah = 120; + true + }, + onclick: move |_| { + let blah = 120; + true + }, + onclick: move |_| { + let blah = 120; + true + }, + onclick: move |_| { + let blah = 120; + true + }, + div { + div { "hi" } + h2 { class: "asd" } + } + Component {} + + // Generics + Component {} + } + } + + // Intertwined comments + div { adsasd: "asd", + h1 { "asd" } + div { + div { "hello" } + div { "goodbye" } + div { class: "broccoli", div { "hi" } } + div { class: "broccolibroccolibroccolibroccolibroccolibroccolibroccolibroccolibroccolibroccoli", + div { "hi" } + } + div { + class: "alksdjasd", + onclick: move |_| { + liberty!(); + }, + div { "hi" } + } + commented { + // is unparalled + class: "asdasd", + + // My genius + div { "hi" } + + div {} + } + } + } + + // Regular comments + div { adsasd: "asd", block: "asd", + // this is a comment + "hello" + + // this is a comment 1 + + // this is a comment 2 + "hello" + div { + // this is a comment + "hello" + } + div { key: "asd", class: "asdsda", + div {} + h3 {} + } + } + + // Components + Component { + adsasd: "asd", + + // this is a comment + onclick: move |_| { + let blah = 120; + let blah = 122; + } + } + + // Manual props + div { + Component { + adsasd: "asd", + onclick: move |_| { + let a = a; + }, + div { "thing" } + } + Component { + asdasd: "asdasd", + asdasd: "asdasdasdasdasdasdasdasdasdasd", + ..Props { + a: 10, + b: 20 + } + } + Component { + asdasd: "asdasd", + ..Props { + a: 10, + b: 20, + c: { + fn main() {} + }, + } + "content" + } + } + + // Long attributes + div { + a: "1234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910", + a: "123", + a: "123", + a: "123", + a: "123", + a: "123", + a: "123", + a: "123", + a: "123" + } + + // Short attributes + div { a: "123", a: "123", a: "123", a: "123", a: "123", a: "123", a: "123", a: "123", a: "123" } + + // Compression + h3 { class: "mb-2 text-xl font-bold", "Invite Member" } + a { class: "text-white", "Send invitation" } + + // Props on tops + h3 { 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", + "Invite Member" + } + + // No children, minimal props + img { class: "mb-6 mx-auto h-24", src: "artemis-assets/images/friends.png", alt: "" } + + // One level compression + div { + a { class: "py-2 px-3 bg-indigo-500 hover:bg-indigo-600 rounded text-xs text-white", href: "#", "Send invitation" } + } + + // Tiny component + Component { a: 123 } + + // Expressions + ul { + div {} + (0..10).map(|f| rsx! { + li { "hi" } + }) + div {} + } + + // Complex nesting with components + button { + class: "flex items-center pl-3 py-3 pr-2 text-gray-500 hover:bg-indigo-50 rounded", + onclick: move |evt| { + show_user_menu.set(!show_user_menu.get()); + evt.cancel_bubble(); + }, + onclick: move |evt| show_user_menu.set(!show_user_menu.get()), + span { class: "inline-block mr-4", icons::icon_14 {} } + span { "Settings" } + } + + // Complex nesting with handlers + li { + Link { class: "flex items-center pl-3 py-3 pr-4 {active_class} rounded", to: "{to}", + span { class: "inline-block mr-3", icons::icon_0 {} } + span { "{name}" } + children.is_some().then(|| rsx! { + span { + class: "inline-block ml-auto hover:bg-gray-500", + onclick: move |evt| { + // open.set(!open.get()); + evt.cancel_bubble(); + }, + icons::icon_8 {} + } + }) + } + div { class: "px-4", + is_current.then(|| rsx!{ children }) + } + } + + // No nesting + Component { + adsasd: "asd", + onclick: move |_| { + let blah = 120; + } + } + + // Component path + my::thing::Component { + adsasd: "asd", + onclick: move |_| { + let blah = 120; + } + } +} diff --git a/packages/autofmt/tests/sink.rs b/packages/autofmt/tests/sink.rs index ca1cb5c88..3654b794a 100644 --- a/packages/autofmt/tests/sink.rs +++ b/packages/autofmt/tests/sink.rs @@ -1,501 +1,4 @@ use dioxus_autofmt::*; -use proc_macro2::TokenStream as TokenStream2; - -fn print_block(wrong: &str) { - let formatted = fmt_block(wrong).unwrap(); - println!("{}", formatted); -} - -#[test] -fn formats_block() { - let block = r#" - div { - div { - class: "asd", - class: "asd",class: "asd",class: "asd",class: "asd",class: "asd", - key: "ddd", - onclick: move |_| { - let blah = 120; - true - }, - blah: 123, - onclick: move |_| { - let blah = 120; - true - }, - onclick: move |_| { - let blah = 120; - true - }, - onclick: move |_| { - let blah = 120; - true - }, - - div { - div { - "hi" - } - h2 { - class: "asd", - } - } - - Component {} - - Component {} - } - } - "#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn parse_comment() { - let block = r#" - div { - adsasd: "asd", // this is a comment - } - "#; - - let parsed: TokenStream2 = syn::parse_str(block).unwrap(); - - dbg!(parsed); -} - -#[test] -fn print_cases() { - print_block( - r#" - div { - adsasd: "asd", - h1 {"asd"} - div { - div { - "hello" - } - div { - "goodbye" - } - div { class: "broccoli", - div { - "hi" - } - } - div { class: "broccolibroccolibroccolibroccolibroccolibroccolibroccolibroccolibroccolibroccoli", - div { - "hi" - } - } - div { class: "alksdjasd", onclick: move |_| { - // hi! - liberty!(); - }, - div { - "hi" - } - } - - commented { - // is unparalled - class: "asdasd", - - // My genius - div { - "hi" - } - - div { - - } - } - } - } - "#, - ); -} - -#[test] -fn format_comments() { - let block = r#" - div { - adsasd: "asd", block: "asd", - - - // this is a comment - "hello" - - // this is a comment 1 - - // this is a comment 2 - "hello" - - div { - // this is a comment - "hello" - } - - div { - // empty space - } - - div { - key: "asd", class: "asdsda", - div {} - h3 {} - } - } - "#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_component() { - let block = r#" - Component { - adsasd: "asd", - - // this is a comment - onclick: move |_| { - let blah = 120; - let blah = 122; - }, - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_component_complex() { - let block = r#" - div { - Component { - adsasd: "asd", - onclick: move |_| { - let a = a; - } - div { - "thing" - } - } - Component { - asdasd: "asdasd", - asdasd: "asdasdasdasdasdasdasdasdasdasd", - ..Props { - a: 10, - b: 20 - } - } - Component { - // - asdasd: "asdasd", - ..Props { - a: 10, - b: 20, - c: { - fn main() { - // - } - } - } - "content" - } - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_element() { - let block = r#" - div { - a: "1234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910", - a: "123", - a: "123", - a: "123", - a: "123", - a: "123", - a: "123", - a: "123", - a: "123", - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_element_short() { - let block = r#" - div { - a: "123", - a: "123", - a: "123", - a: "123", - a: "123", - a: "123", - a: "123", - a: "123", - a: "123", - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_element_nested() { - let block = r#" - h3 { - class: "mb-2 text-xl font-bold", - "Invite Member" - } -"#; - - let formatted = fmt_block(block).unwrap(); - - assert_eq!( - formatted, - r#"h3 { class: "mb-2 text-xl font-bold", "Invite Member" }"# - ); -} - -#[test] -fn formats_element_props_on_top() { - // Gets compressed because there's no real comments - let block = r#" - h3 { - 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", - - "Invite Member" - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_element_nested_no_trailing_tabs() { - let block = r#" - img { class: "mb-6 mx-auto h-24", src: "artemis-assets/images/friends.png", alt: "", } -"#; - - let formatted = fmt_block(block).unwrap(); - - assert_eq!( - formatted, - r#"img { class: "mb-6 mx-auto h-24", src: "artemis-assets/images/friends.png", alt: "" }"# - ); -} - -#[test] -fn formats_element_with_correct_indent() { - let block = r###" - div { - - a { class: "py-2 px-3 bg-indigo-500 hover:bg-indigo-600 rounded text-xs text-white", href: "#", - "Send invitation" - } - } - -"###; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn small_elements_and_text_are_small() { - let block = r###" - a { class: "text-white", - "Send invitation" - } -"###; - - let formatted = fmt_block(block).unwrap(); - - assert_eq!(formatted, r#"a { class: "text-white", "Send invitation" }"#); -} - -#[test] -fn formats_component_man_props() { - let block = r#" - Component { - ..MyProps { - val: 123 - }, - adsasd: "asd", // this is a comment - onclick: move |_| { - let blah = 120; - }, - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_component_tiny() { - let block = r#" - Component { a: 123 - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_exprs() { - let block = r#" - ul { - div {} - (0..10).map(|f| rsx! { - li { "hi" } - }) - div {} - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_exprs_neg_indent() { - let block = r#" - ul { - (0..10).map(|f| rsx!{ - li { - "hi" - } - }) - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_exprs_handlers() { - let block = r#" - button { - class: "flex items-center pl-3 py-3 pr-2 text-gray-500 hover:bg-indigo-50 rounded", - onclick: move |evt| { - show_user_menu.set(!show_user_menu.get()); evt.cancel_bubble(); }, - - onclick: move |evt| - - show_user_menu.set(!show_user_menu.get()), - span { class: "inline-block mr-4", - icons::icon_14 {} - } - span { "Settings" } - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_complex() { - let block = r#" - li { - Link { - class: "flex items-center pl-3 py-3 pr-4 {active_class} rounded", - to: "{to}", - span { class: "inline-block mr-3", - icons::icon_0 {} - } - span { "{name}" } - children.is_some().then(|| rsx! { - span { - class: "inline-block ml-auto hover:bg-gray-500", - onclick: move |evt| { - // open.set(!open.get()); - evt.cancel_bubble(); - }, - icons::icon_8 {} - } - }) - } - div { - class: "px-4", - is_current.then(|| rsx!{ children }) - // open.then(|| rsx!{ children }) - } - } -"#; - - let formatted = fmt_block(block).unwrap(); - - println!("{formatted}"); -} - -#[test] -fn formats_document() { - let block = r#" -rsx!{ - Component { - adsasd: "asd", // this is a comment - onclick: move |_| { - let blah = 120; - }, - } -} - - -"#; - - let formatted = fmt_file(block); - - println!("{formatted:?}"); -} - -#[test] -fn component_path_mod_style() { - let block = r#" -rsx!{ - my::thing::Component { - adsasd: "asd", // this is a comment - onclick: move |_| { - let blah = 120; - }, - } -} -"#; - - let formatted = fmt_file(block); - - println!("{formatted:?}"); -} #[test] fn formats_valid_rust_src() {