use forc_tracing::{println_green, println_red};
use paste::paste;
use prettydiff::{basic::DiffOp, diff_lines};
macro_rules! fmt_test {
($scope:ident $desired_output:expr, $($name:ident $y:expr),+) => {
fmt_test_inner!($scope $desired_output,
$($name $y)+
,
remove_trailing_whitespace format!("{} \n\n\t ", $desired_output).as_str(),
remove_beginning_whitespace format!(" \n\t{}", $desired_output).as_str(),
identity $desired_output,
remove_beginning_and_trailing_whitespace format!(" \n\t {} \n\t ", $desired_output).as_str()
);
};
}
macro_rules! fmt_test_inner {
($scope:ident $desired_output:expr, $($name:ident $y:expr),+) => {
$(
paste! {
#[test]
fn [<$scope _ $name>] () {
let formatted_code = crate::parse::parse_format::<sway_ast::Expr>($y);
let changeset = diff_lines(&formatted_code, $desired_output);
let count_of_updates = changeset.diff().len();
if count_of_updates != 0 {
println!("FAILED: {count_of_updates} diff items.");
}
for diff in changeset.diff() {
match diff {
DiffOp::Equal(old) => {
for o in old {
println!("{}", o)
}
}
DiffOp::Insert(new) => {
for n in new {
println_green(&format!("+{}", n));
}
}
DiffOp::Remove(old) => {
for o in old {
println_red(&format!("-{}", o));
}
}
DiffOp::Replace(old, new) => {
for o in old {
println_red(&format!("-{}", o));
}
for n in new {
println_green(&format!("+{}", n));
}
}
}
}
println!("{formatted_code}");
assert_eq!(&formatted_code, $desired_output)
}
}
)+
}
}
fmt_test!( literal "5", extra_whitespace " 5 "
);
fmt_test!( path_foo_bar "foo::bar::baz::quux::quuz",
intermediate_whitespace "foo :: bar :: baz :: quux :: quuz");
fmt_test!( field_proj_foobar "foo.bar.baz.quux",
intermediate_whitespace "foo . bar . baz . quux");
fmt_test!( abi_cast "abi(MyAbi, 0x1111111111111111111111111111111111111111111111111111111111111111)",
intermediate_whitespace " abi (
MyAbi
,
0x1111111111111111111111111111111111111111111111111111111111111111
) "
);
fmt_test!( basic_func_app "foo()",
intermediate_whitespace " foo (
) "
);
fmt_test!( nested_args_func_app "foo(a_struct { hello: \"hi\" }, a_var, foo.bar.baz.quux)",
intermediate_whitespace "foo(a_struct {
hello : \"hi\"
}, a_var , foo . bar . baz . quux)"
);
fmt_test!( multiline_tuple "(\n \"reallyreallylongstring\",\n \"yetanotherreallyreallyreallylongstring\",\n \"okaynowthatsjustaridiculouslylongstringrightthere\",\n)",
intermediate_whitespace "(\"reallyreallylongstring\", \"yetanotherreallyreallyreallylongstring\",
\"okaynowthatsjustaridiculouslylongstringrightthere\")"
);
fmt_test!( nested_tuple
"(
(
0x0000000000000000000000000000000000000000000000000000000000,
0x0000000000000000000000000000000000000000000000000000000000,
),
(
0x0000000000000000000000000000000000000000000000000000000000,
0x0000000000000000000000000000000000000000000000000000000000,
),
)",
intermediate_whitespace
" (
(
0x0000000000000000000000000000000000000000000000000000000000 ,
0x0000000000000000000000000000000000000000000000000000000000 ,
) ,
(
0x0000000000000000000000000000000000000000000000000000000000 ,
0x0000000000000000000000000000000000000000000000000000000000 ,
) ,
)"
);
fmt_test!( multiline_match_stmt "match foo {\n Foo::foo => {}\n Foo::bar => {}\n}",
intermediate_whitespace " match \n foo { \n\n Foo :: foo => { }\n Foo :: bar => { } \n}\n"
);
fmt_test!( if_else_block "if foo {\n foo();\n} else if bar { bar(); } else { baz(); }",
intermediate_whitespace " if foo { \n foo( ) ; \n } else if bar { \n bar( ) ; \n } else { \n baz(\n) ; \n }\n\n"
);
fmt_test!( long_conditional_stmt
"if really_long_var_name > other_really_long_var
|| really_long_var_name <= 0
&& other_really_long_var != 0
{
foo();
} else {
bar();
}",
intermediate_whitespace
" if really_long_var_name >
other_really_long_var
|| really_long_var_name <=
0 && other_really_long_var != 0 { foo(); }else{bar();}"
);
fmt_test!( if_else_inline_1 "if foo { break; } else { continue; }",
intermediate_whitespace "if foo { \n break; \n} else {\n continue; \n}");
fmt_test!( if_else_inline_2
"if foo { let x = 1; } else { bar(y); }"
,
intermediate_whitespace
" if foo {
let x = 1;
} else {
bar(y) ;
} ");
fmt_test!( if_else_multiline
"if foo {
let really_long_variable = 1;
} else {
bar(y);
}",
intermediate_whitespace
" if foo {
let really_long_variable = 1;
} else {
bar(y) ;
} ");
fmt_test!( small_if_let "if let Result::Ok(x) = x { 100 } else { 1 }",
intermediate_whitespace "if let Result :: Ok( x ) = x { 100 } else { 1 }"
);
fmt_test!( match_nested_conditional
"match foo {
Foo::foo => {
if really_long_var > other_really_long_var {
foo();
} else if really_really_long_var_name > really_really_really_really_long_var_name111111111111
{
bar();
} else {
baz();
}
}
}",
intermediate_whitespace
" match foo {
Foo::foo => {
if really_long_var > other_really_long_var {
foo();
} else if really_really_long_var_name > really_really_really_really_long_var_name111111111111
{
bar();
} else {
baz() ;
}
}
}"
);
fmt_test!( match_branch_kind
"match foo {
Foo::foo => {
foo();
bar();
}
Foo::bar => {
baz();
quux();
}
}",
intermediate_whitespace
"match foo
\n{\n\n Foo::foo
=> {\n foo()
; \n bar(
); \n } \n Foo::\nbar =>
{\n baz();\n
quux();\n }\n\n\n}"
);
fmt_test!( basic_array "[1, 2, 3, 4, 5]",
intermediate_whitespace " \n [ 1 , 2 , 3 , 4 , 5 ] \n"
);
fmt_test!( long_array
"[
\"hello_there_this_is_a_very_long_string\",
\"and_yet_another_very_long_string_just_because\",
\"would_you_look_at_that_another_long_string\",
]",
intermediate_whitespace
" [
\"hello_there_this_is_a_very_long_string\",
\"and_yet_another_very_long_string_just_because\"\n,
\"would_you_look_at_that_another_long_string\",
] \n"
);
fmt_test!( nested_array
"[
[
0x0000000000000000000000000000000000000000000000000000000000,
0x0000000000000000000000000000000000000000000000000000000000,
],
[
0x0000000000000000000000000000000000000000000000000000000000,
0x0000000000000000000000000000000000000000000000000000000000,
],
]",
intermediate_whitespace
" [
[
0x0000000000000000000000000000000000000000000000000000000000 ,
0x0000000000000000000000000000000000000000000000000000000000 ,
] ,
[
0x0000000000000000000000000000000000000000000000000000000000 ,
0x0000000000000000000000000000000000000000000000000000000000 ,
] ,
]"
);