use super::normalization::format_rust_content;
const LONG_EXPRESSION_SOURCE: &str = "fn f() {\n let total = alpha_value + bravo_value + charlie_value + \
delta_value + echo_value + foxtrot_value + golf_value;\n}\n";
const UNWRAPPED_LINE: &str =
"let total = alpha_value + bravo_value + charlie_value + delta_value + echo_value + foxtrot_value + golf_value;";
const WIDE_CONFIG: &str = "max_width = 150\n";
const NARROW_CONFIG: &str = "max_width = 40\n";
fn write_rustfmt_toml(dir: &std::path::Path, content: &str) {
std::fs::create_dir_all(dir).expect("create rustfmt.toml's directory");
std::fs::write(dir.join("rustfmt.toml"), content).expect("write rustfmt.toml");
}
fn contains_unwrapped_line(output: &str) -> bool {
output.lines().any(|line| line.trim() == UNWRAPPED_LINE)
}
#[test]
fn format_rust_content_falls_back_to_rustfmt_defaults_when_the_project_has_no_config() {
if !crate::cli::pipeline::is_tool_available("rustfmt") {
return;
}
let project_root = tempfile::tempdir().expect("tempdir");
let content = "fn x(){let y=1;}\n";
let formatted = format_rust_content(project_root.path(), &project_root.path().join("lib.rs"), content);
assert_ne!(
formatted.trim_end(),
content.trim_end(),
"a project with no rustfmt.toml anywhere must still get rustfmt's own default \
formatting, not a hard-error fallback to the raw, unformatted input; got: {formatted:?}"
);
assert!(
formatted.contains("let y = 1;"),
"rustfmt's default formatting must have run (spaced-out assignment), got: {formatted:?}"
);
}
#[test]
fn format_rust_content_honours_a_rustfmt_toml_at_the_project_root_from_an_unrelated_cwd() {
if !crate::cli::pipeline::is_tool_available("rustfmt") {
return;
}
let project_root = tempfile::tempdir().expect("tempdir");
write_rustfmt_toml(project_root.path(), WIDE_CONFIG);
let unrelated_cwd = tempfile::tempdir().expect("unrelated tempdir");
let _cwd = crate::test_support::CwdGuard::enter(unrelated_cwd.path());
let formatted = format_rust_content(
project_root.path(),
&project_root.path().join("src/lib.rs"),
LONG_EXPRESSION_SOURCE,
);
assert!(
contains_unwrapped_line(&formatted),
"the project root's max_width = 150 must be honoured even though the process cwd is a \
completely unrelated directory with no config of its own, got: {formatted:?}"
);
}
#[test]
fn format_rust_content_prefers_a_nearer_rustfmt_toml_over_the_project_root() {
if !crate::cli::pipeline::is_tool_available("rustfmt") {
return;
}
let project_root = tempfile::tempdir().expect("tempdir");
write_rustfmt_toml(project_root.path(), WIDE_CONFIG);
let nested = project_root.path().join("pkg/sub");
write_rustfmt_toml(&nested, NARROW_CONFIG);
let formatted = format_rust_content(project_root.path(), &nested.join("lib.rs"), LONG_EXPRESSION_SOURCE);
assert!(
!contains_unwrapped_line(&formatted),
"the nearer, narrower rustfmt.toml (max_width = 40) must win over the project root's \
wider one (max_width = 150), got: {formatted:?}"
);
}
#[test]
fn format_rust_content_does_not_escape_the_project_root() {
if !crate::cli::pipeline::is_tool_available("rustfmt") {
return;
}
let project_root = tempfile::tempdir().expect("tempdir");
let unrelated_tree = tempfile::tempdir().expect("unrelated tempdir");
write_rustfmt_toml(unrelated_tree.path(), WIDE_CONFIG);
let foreign_path = unrelated_tree.path().join("lib.rs");
let formatted = format_rust_content(project_root.path(), &foreign_path, LONG_EXPRESSION_SOURCE);
assert!(
!contains_unwrapped_line(&formatted),
"a file outside `project_root` must not pick up a foreign tree's rustfmt.toml -- the \
lookup must fall back to rustfmt's own defaults instead, got: {formatted:?}"
);
}