feat: more tests and spans
This commit is contained in:
1 parent
804d9af1c7
commit
284860f470
3 files changed
+194
-31
No files matched your search
@@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = { version = "1.0.6" }
|
||||
proc-macro2 = { version = "1.0.6", features = ["span-locations"] }
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0.11", features = ["full", "extra-traits"] }
|
||||
dioxus-rsx = { path = "../rsx" }
|
||||
|
||||
+85
-29
@@ -41,20 +41,6 @@ pub fn get_format_blocks(contents: &str) -> Vec<FormattedBlock> {
|
||||
continue;
|
||||
}
|
||||
|
||||
// match cur_match {
|
||||
// Some(ref this_match) => {
|
||||
// // abort nested matches - these get handled automatically
|
||||
// if start < this_match.end {
|
||||
// continue;
|
||||
// } else {
|
||||
// cur_match = Some(item);
|
||||
// }
|
||||
// }
|
||||
// None => {
|
||||
// cur_match = Some(item);
|
||||
// }
|
||||
// }
|
||||
|
||||
let remaining = &contents[end - 1..];
|
||||
|
||||
if let Some(bracket_end) = find_bracket_end(remaining) {
|
||||
@@ -67,6 +53,14 @@ pub fn get_format_blocks(contents: &str) -> Vec<FormattedBlock> {
|
||||
|
||||
if let Some(new) = fmt_block(sub_string) {
|
||||
if !new.is_empty() {
|
||||
println!("{}", &contents[end + 1..bracket_end + end - 1]);
|
||||
println!("{}", new);
|
||||
|
||||
let stripped = &contents[end + 1..bracket_end + end - 1];
|
||||
if stripped == new {
|
||||
println!("no changes necessary");
|
||||
}
|
||||
|
||||
// if we have code to push, we want the code to end up on the right lines with the right indentation
|
||||
|
||||
let mut output = String::new();
|
||||
@@ -94,18 +88,25 @@ pub fn get_format_blocks(contents: &str) -> Vec<FormattedBlock> {
|
||||
}
|
||||
|
||||
pub fn fmt_block(block: &str) -> Option<String> {
|
||||
let mut raw_lines = block.split('\n').collect::<Vec<_>>();
|
||||
|
||||
let parsed: CallBody = syn::parse_str(block).ok()?;
|
||||
|
||||
let mut buf = String::new();
|
||||
|
||||
for node in parsed.roots.iter() {
|
||||
write_ident(&mut buf, node, 0).ok()?;
|
||||
write_ident(&mut buf, &raw_lines, node, 0).ok()?;
|
||||
}
|
||||
|
||||
Some(buf)
|
||||
}
|
||||
|
||||
pub fn write_ident(buf: &mut String, node: &BodyNode, indent: usize) -> fmt::Result {
|
||||
pub fn write_ident(
|
||||
buf: &mut String,
|
||||
lines: &[&str],
|
||||
node: &BodyNode,
|
||||
indent: usize,
|
||||
) -> fmt::Result {
|
||||
match node {
|
||||
BodyNode::Element(el) => {
|
||||
let Element {
|
||||
@@ -168,7 +169,7 @@ pub fn write_ident(buf: &mut String, node: &BodyNode, indent: usize) -> fmt::Res
|
||||
ElementAttr::CustomAttrText { name, value } => {
|
||||
write!(
|
||||
buf,
|
||||
"{name}: \"{value}\"",
|
||||
"\"{name}\": \"{value}\"",
|
||||
name = name.value(),
|
||||
value = value.value()
|
||||
)?;
|
||||
@@ -176,22 +177,32 @@ pub fn write_ident(buf: &mut String, node: &BodyNode, indent: usize) -> fmt::Res
|
||||
|
||||
ElementAttr::CustomAttrExpression { name, value } => {
|
||||
let out = prettyplease::unparse_expr(value);
|
||||
write!(buf, "{}: {}", name.value(), out)?;
|
||||
write!(buf, "\"{}\": {}", name.value(), out)?;
|
||||
}
|
||||
|
||||
ElementAttr::EventTokens { name, tokens } => {
|
||||
let out = prettyplease::unparse_expr(tokens);
|
||||
|
||||
dbg!(&out);
|
||||
|
||||
let mut lines = out.split('\n').peekable();
|
||||
let first = lines.next().unwrap();
|
||||
write!(buf, "{}: {}", name, first)?;
|
||||
|
||||
while let Some(line) = lines.next() {
|
||||
write_tabs(buf, indent + 1)?;
|
||||
write!(buf, "{}", line)?;
|
||||
// write!(buf, "{}", line)?;
|
||||
if lines.peek().is_none() {
|
||||
write!(buf, "")?;
|
||||
// a one-liner for whatever reason
|
||||
// Does not need a new line
|
||||
if lines.peek().is_none() {
|
||||
write!(buf, "{}: {}", name, first)?;
|
||||
} else {
|
||||
writeln!(buf, "{}: {}", name, first)?;
|
||||
|
||||
while let Some(line) = lines.next() {
|
||||
write_tabs(buf, indent + 1)?;
|
||||
write!(buf, "{}", line)?;
|
||||
if lines.peek().is_none() {
|
||||
write!(buf, "")?;
|
||||
} else {
|
||||
writeln!(buf)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,7 +232,7 @@ pub fn write_ident(buf: &mut String, node: &BodyNode, indent: usize) -> fmt::Res
|
||||
}
|
||||
|
||||
for child in children {
|
||||
write_ident(buf, child, indent + 1)?;
|
||||
write_ident(buf, lines, child, indent + 1)?;
|
||||
}
|
||||
|
||||
if is_long_attr_list || !children.is_empty() {
|
||||
@@ -260,7 +271,7 @@ pub fn write_ident(buf: &mut String, node: &BodyNode, indent: usize) -> fmt::Res
|
||||
writeln!(buf, "{}: {},", name, out)?;
|
||||
}
|
||||
ContentField::Formatted(s) => {
|
||||
writeln!(buf, "{}: {},", name, s.value())?;
|
||||
writeln!(buf, "{}: \"{}\",", name, s.value())?;
|
||||
}
|
||||
ContentField::OnHandlerRaw(exp) => {
|
||||
let out = prettyplease::unparse_expr(exp);
|
||||
@@ -292,7 +303,7 @@ pub fn write_ident(buf: &mut String, node: &BodyNode, indent: usize) -> fmt::Res
|
||||
}
|
||||
|
||||
for child in children {
|
||||
write_ident(buf, child, indent + 1)?;
|
||||
write_ident(buf, lines, child, indent + 1)?;
|
||||
}
|
||||
|
||||
if !body.is_empty() || !children.is_empty() {
|
||||
@@ -310,7 +321,52 @@ pub fn write_ident(buf: &mut String, node: &BodyNode, indent: usize) -> fmt::Res
|
||||
write_tabs(buf, indent)?;
|
||||
writeln!(buf, "\"{}\"", t.value())?;
|
||||
}
|
||||
BodyNode::RawExpr(_) => {
|
||||
BodyNode::RawExpr(exp) => {
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
let placement = exp.span();
|
||||
|
||||
let start = placement.start();
|
||||
let end = placement.end();
|
||||
|
||||
let num_spaces_desired = (indent * 4) as isize;
|
||||
let first = lines[start.line - 1];
|
||||
let num_spaces_real = first.chars().take_while(|c| c.is_whitespace()).count() as isize;
|
||||
let offset = num_spaces_real - num_spaces_desired;
|
||||
|
||||
for line_id in start.line - 1..end.line {
|
||||
let line = lines[line_id];
|
||||
|
||||
// trim the leading whitespace
|
||||
|
||||
if offset < 0 {
|
||||
for _ in 0..-offset {
|
||||
write!(buf, " ")?;
|
||||
}
|
||||
|
||||
writeln!(buf, "{}", line)?;
|
||||
} else {
|
||||
let offset = offset as usize;
|
||||
|
||||
let right = &line[offset..];
|
||||
writeln!(buf, "{}", right)?;
|
||||
}
|
||||
}
|
||||
|
||||
// let toks = exp.to_token_stream();
|
||||
|
||||
// let out = prettyplease::unparse_expr(exp);
|
||||
// let mut lines = out.split('\n').peekable();
|
||||
// for line in lines {
|
||||
// write_tabs(buf, indent)?;
|
||||
// writeln!(buf, "{}", line)?;
|
||||
// // writeln!(buf)?;
|
||||
// }
|
||||
// write_tabs(buf, indent)?;
|
||||
// let first = lines.next().unwrap();
|
||||
// write!(buf, "{}", name, first)?;
|
||||
// writeln!(buf)?;
|
||||
|
||||
//
|
||||
// write!(buf, "{}", " ".repeat(ident))
|
||||
}
|
||||
|
||||
@@ -203,6 +203,98 @@ fn formats_component_tiny() {
|
||||
print!("{formatted}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formats_exprs() {
|
||||
let block = r#"
|
||||
ul {
|
||||
(0..10).map(|f| rsx!{
|
||||
li {
|
||||
"hi"
|
||||
}
|
||||
})
|
||||
}
|
||||
"#;
|
||||
|
||||
let formatted = fmt_block(block).unwrap();
|
||||
|
||||
print!("{formatted}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formats_exprs_neg_indent() {
|
||||
let block = r#"
|
||||
ul {
|
||||
(0..10).map(|f| rsx!{
|
||||
li {
|
||||
"hi"
|
||||
}
|
||||
})
|
||||
}
|
||||
"#;
|
||||
|
||||
let formatted = fmt_block(block).unwrap();
|
||||
|
||||
print!("{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();
|
||||
|
||||
print!("{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();
|
||||
|
||||
print!("{formatted}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn formats_document() {
|
||||
let block = r#"
|
||||
@@ -321,7 +413,6 @@ fn NavItem<'a>(cx: Scope, to: &'static str, children: Element<'a>, icon: Shape)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
fn NavItem<'a>(cx: Scope, to: &'static str, children: Element<'a>, icon: Shape) -> Element {
|
||||
const ICON_SIZE: u32 = 36;
|
||||
@@ -362,3 +453,19 @@ fn NavItem<'a>(cx: Scope, to: &'static str, children: Element<'a>, icon: Shape)
|
||||
&format!("{{ {} }}", &block.formatted),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_blocks() {
|
||||
let mut src = r###"
|
||||
pub fn Alert(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
div { }
|
||||
})
|
||||
}
|
||||
"###
|
||||
.to_string();
|
||||
|
||||
let formatted = get_format_blocks(&src);
|
||||
|
||||
dbg!(&formatted);
|
||||
}
|
||||
Reference in new issue
Block a user