18c0369688
Fixes 5167 When ``a.rs`` and ``a/mod.rs`` are both present we would emit an error message telling the user that the module couldn't be found. However, this behavior is misleading because we're dealing with an ambiguous module path, not a "file not found" error. Is the file ``a.rs`` or is it ``a/mod.rs``? Rustfmt can't decide, and the user needs to resolve this ambiguity themselves. Now, the error message displayed to the user is in line with what they would see if they went to compile their code with these conflicting module names.
160 lines
4.9 KiB
Rust
160 lines
4.9 KiB
Rust
//! Integration tests for rustfmt.
|
|
|
|
use std::env;
|
|
use std::fs::remove_file;
|
|
use std::path::Path;
|
|
use std::process::Command;
|
|
|
|
/// Run the rustfmt executable and return its output.
|
|
fn rustfmt(args: &[&str]) -> (String, String) {
|
|
let mut bin_dir = env::current_exe().unwrap();
|
|
bin_dir.pop(); // chop off test exe name
|
|
if bin_dir.ends_with("deps") {
|
|
bin_dir.pop();
|
|
}
|
|
let cmd = bin_dir.join(format!("rustfmt{}", env::consts::EXE_SUFFIX));
|
|
|
|
// Ensure the rustfmt binary runs from the local target dir.
|
|
let path = env::var_os("PATH").unwrap_or_default();
|
|
let mut paths = env::split_paths(&path).collect::<Vec<_>>();
|
|
paths.insert(0, bin_dir);
|
|
let new_path = env::join_paths(paths).unwrap();
|
|
|
|
match Command::new(&cmd).args(args).env("PATH", new_path).output() {
|
|
Ok(output) => (
|
|
String::from_utf8(output.stdout).expect("utf-8"),
|
|
String::from_utf8(output.stderr).expect("utf-8"),
|
|
),
|
|
Err(e) => panic!("failed to run `{:?} {:?}`: {}", cmd, args, e),
|
|
}
|
|
}
|
|
|
|
macro_rules! assert_that {
|
|
($args:expr, $($check:ident $check_args:tt)&&+) => {
|
|
let (stdout, stderr) = rustfmt($args);
|
|
if $(!stdout.$check$check_args && !stderr.$check$check_args)||* {
|
|
panic!(
|
|
"Output not expected for rustfmt {:?}\n\
|
|
expected: {}\n\
|
|
actual stdout:\n{}\n\
|
|
actual stderr:\n{}",
|
|
$args,
|
|
stringify!($( $check$check_args )&&*),
|
|
stdout,
|
|
stderr
|
|
);
|
|
}
|
|
};
|
|
}
|
|
|
|
#[ignore]
|
|
#[test]
|
|
fn print_config() {
|
|
assert_that!(
|
|
&["--print-config", "unknown"],
|
|
starts_with("Unknown print-config option")
|
|
);
|
|
assert_that!(&["--print-config", "default"], contains("max_width = 100"));
|
|
assert_that!(&["--print-config", "minimal"], contains("PATH required"));
|
|
assert_that!(
|
|
&["--print-config", "minimal", "minimal-config"],
|
|
contains("doesn't work with standard input.")
|
|
);
|
|
|
|
let (stdout, stderr) = rustfmt(&[
|
|
"--print-config",
|
|
"minimal",
|
|
"minimal-config",
|
|
"src/shape.rs",
|
|
]);
|
|
assert!(
|
|
Path::new("minimal-config").exists(),
|
|
"stdout:\n{}\nstderr:\n{}",
|
|
stdout,
|
|
stderr
|
|
);
|
|
remove_file("minimal-config").unwrap();
|
|
}
|
|
|
|
#[ignore]
|
|
#[test]
|
|
fn inline_config() {
|
|
// single invocation
|
|
assert_that!(
|
|
&[
|
|
"--print-config",
|
|
"current",
|
|
".",
|
|
"--config=color=Never,edition=2018"
|
|
],
|
|
contains("color = \"Never\"") && contains("edition = \"2018\"")
|
|
);
|
|
|
|
// multiple overriding invocations
|
|
assert_that!(
|
|
&[
|
|
"--print-config",
|
|
"current",
|
|
".",
|
|
"--config",
|
|
"color=never,edition=2018",
|
|
"--config",
|
|
"color=always,format_strings=true"
|
|
],
|
|
contains("color = \"Always\"")
|
|
&& contains("edition = \"2018\"")
|
|
&& contains("format_strings = true")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn rustfmt_usage_text() {
|
|
let args = ["--help"];
|
|
let (stdout, _) = rustfmt(&args);
|
|
assert!(stdout.contains("Format Rust code\n\nusage: rustfmt [options] <file>..."));
|
|
}
|
|
|
|
#[test]
|
|
fn mod_resolution_error_multiple_candidate_files() {
|
|
// See also https://github.com/rust-lang/rustfmt/issues/5167
|
|
let default_path = Path::new("tests/mod-resolver/issue-5167/src/a.rs");
|
|
let secondary_path = Path::new("tests/mod-resolver/issue-5167/src/a/mod.rs");
|
|
let error_message = format!(
|
|
"file for module found at both {:?} and {:?}",
|
|
default_path.canonicalize().unwrap(),
|
|
secondary_path.canonicalize().unwrap(),
|
|
);
|
|
|
|
let args = ["tests/mod-resolver/issue-5167/src/lib.rs"];
|
|
let (_stdout, stderr) = rustfmt(&args);
|
|
assert!(stderr.contains(&error_message))
|
|
}
|
|
|
|
#[test]
|
|
fn mod_resolution_error_sibling_module_not_found() {
|
|
let args = ["tests/mod-resolver/module-not-found/sibling_module/lib.rs"];
|
|
let (_stdout, stderr) = rustfmt(&args);
|
|
// Module resolution fails because we're unable to find `a.rs` in the same directory as lib.rs
|
|
assert!(stderr.contains("a.rs does not exist"))
|
|
}
|
|
|
|
#[test]
|
|
fn mod_resolution_error_relative_module_not_found() {
|
|
let args = ["tests/mod-resolver/module-not-found/relative_module/lib.rs"];
|
|
let (_stdout, stderr) = rustfmt(&args);
|
|
// The file `./a.rs` and directory `./a` both exist.
|
|
// Module resolution fails becuase we're unable to find `./a/b.rs`
|
|
#[cfg(not(windows))]
|
|
assert!(stderr.contains("a/b.rs does not exist"));
|
|
#[cfg(windows)]
|
|
assert!(stderr.contains("a\\b.rs does not exist"));
|
|
}
|
|
|
|
#[test]
|
|
fn mod_resolution_error_path_attribute_does_not_exist() {
|
|
let args = ["tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs"];
|
|
let (_stdout, stderr) = rustfmt(&args);
|
|
// The path attribute points to a file that does not exist
|
|
assert!(stderr.contains("does_not_exist.rs does not exist"));
|
|
}
|