Merge remote-tracking branch 'upstream/master' into subtree-sync-2022-01-23
This commit is contained in:
commit
9b454a5990
@ -74,14 +74,10 @@ pub enum OperationError {
|
||||
/// An io error during reading or writing.
|
||||
#[error("{0}")]
|
||||
IoError(IoError),
|
||||
/// Attempt to use --check with stdin, which isn't currently
|
||||
/// supported.
|
||||
#[error("The `--check` option is not supported with standard input.")]
|
||||
CheckWithStdin,
|
||||
/// Attempt to use --emit=json with stdin, which isn't currently
|
||||
/// supported.
|
||||
#[error("Using `--emit` other than stdout is not supported with standard input.")]
|
||||
EmitWithStdin,
|
||||
/// Attempt to use --emit with a mode which is not currently
|
||||
/// supported with stdandard input.
|
||||
#[error("Emit mode {0} not supported with standard output.")]
|
||||
StdinBadEmit(EmitMode),
|
||||
}
|
||||
|
||||
impl From<IoError> for OperationError {
|
||||
@ -255,15 +251,20 @@ fn format_string(input: String, options: GetOptsOptions) -> Result<i32> {
|
||||
let (mut config, _) = load_config(Some(Path::new(".")), Some(options.clone()))?;
|
||||
|
||||
if options.check {
|
||||
return Err(OperationError::CheckWithStdin.into());
|
||||
}
|
||||
if let Some(emit_mode) = options.emit_mode {
|
||||
if emit_mode != EmitMode::Stdout {
|
||||
return Err(OperationError::EmitWithStdin.into());
|
||||
config.set().emit_mode(EmitMode::Diff);
|
||||
} else {
|
||||
match options.emit_mode {
|
||||
// Emit modes which work with standard input
|
||||
// None means default, which is Stdout.
|
||||
None | Some(EmitMode::Stdout) | Some(EmitMode::Checkstyle) | Some(EmitMode::Json) => {}
|
||||
Some(emit_mode) => {
|
||||
return Err(OperationError::StdinBadEmit(emit_mode).into());
|
||||
}
|
||||
}
|
||||
config
|
||||
.set()
|
||||
.emit_mode(options.emit_mode.unwrap_or(EmitMode::Stdout));
|
||||
}
|
||||
// emit mode is always Stdout for Stdin.
|
||||
config.set().emit_mode(EmitMode::Stdout);
|
||||
config.set().verbose(Verbosity::Quiet);
|
||||
|
||||
// parse file_lines
|
||||
|
@ -387,8 +387,7 @@ fn get_targets_root_only(
|
||||
.unwrap_or_default()
|
||||
== current_dir_manifest
|
||||
})
|
||||
.map(|p| p.targets)
|
||||
.flatten()
|
||||
.flat_map(|p| p.targets)
|
||||
.collect(),
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@ impl fmt::Display for FileName {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
FileName::Real(p) => write!(f, "{}", p.to_str().unwrap()),
|
||||
FileName::Stdin => write!(f, "stdin"),
|
||||
FileName::Stdin => write!(f, "<stdin>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
use super::*;
|
||||
use crate::rustfmt_diff::{make_diff, DiffLine, Mismatch};
|
||||
use std::io::{self, Write};
|
||||
use std::path::Path;
|
||||
|
||||
mod xml;
|
||||
|
||||
@ -30,7 +29,6 @@ fn emit_formatted_file(
|
||||
}: FormattedFile<'_>,
|
||||
) -> Result<EmitterResult, io::Error> {
|
||||
const CONTEXT_SIZE: usize = 0;
|
||||
let filename = ensure_real_path(filename);
|
||||
let diff = make_diff(original_text, formatted_text, CONTEXT_SIZE);
|
||||
output_checkstyle_file(output, filename, diff)?;
|
||||
Ok(EmitterResult::default())
|
||||
@ -39,13 +37,13 @@ fn emit_formatted_file(
|
||||
|
||||
pub(crate) fn output_checkstyle_file<T>(
|
||||
mut writer: T,
|
||||
filename: &Path,
|
||||
filename: &FileName,
|
||||
diff: Vec<Mismatch>,
|
||||
) -> Result<(), io::Error>
|
||||
where
|
||||
T: Write,
|
||||
{
|
||||
write!(writer, r#"<file name="{}">"#, filename.display())?;
|
||||
write!(writer, r#"<file name="{}">"#, filename)?;
|
||||
for mismatch in diff {
|
||||
let begin_line = mismatch.line_number;
|
||||
let mut current_line;
|
||||
@ -77,7 +75,11 @@ mod tests {
|
||||
fn emits_empty_record_on_file_with_no_mismatches() {
|
||||
let file_name = "src/well_formatted.rs";
|
||||
let mut writer = Vec::new();
|
||||
let _ = output_checkstyle_file(&mut writer, &PathBuf::from(file_name), vec![]);
|
||||
let _ = output_checkstyle_file(
|
||||
&mut writer,
|
||||
&FileName::Real(PathBuf::from(file_name)),
|
||||
vec![],
|
||||
);
|
||||
assert_eq!(
|
||||
&writer[..],
|
||||
format!(r#"<file name="{}"></file>"#, file_name).as_bytes()
|
||||
|
@ -28,7 +28,7 @@ fn emit_formatted_file(
|
||||
|
||||
if has_diff {
|
||||
if self.config.print_misformatted_file_names() {
|
||||
writeln!(output, "{}", ensure_real_path(filename).display())?;
|
||||
writeln!(output, "{}", filename)?;
|
||||
} else {
|
||||
print_diff(
|
||||
mismatch,
|
||||
@ -40,8 +40,7 @@ fn emit_formatted_file(
|
||||
// This occurs when the only difference between the original and formatted values
|
||||
// is the newline style. This happens because The make_diff function compares the
|
||||
// original and formatted values line by line, independent of line endings.
|
||||
let file_path = ensure_real_path(filename);
|
||||
writeln!(output, "Incorrect newline style in {}", file_path.display())?;
|
||||
writeln!(output, "Incorrect newline style in {}", filename)?;
|
||||
return Ok(EmitterResult { has_diff: true });
|
||||
}
|
||||
|
||||
|
@ -3,14 +3,13 @@
|
||||
use serde::Serialize;
|
||||
use serde_json::to_string as to_json_string;
|
||||
use std::io::{self, Write};
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct JsonEmitter {
|
||||
num_files: u32,
|
||||
mismatched_files: Vec<MismatchedFile>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
#[derive(Debug, Default, PartialEq, Serialize)]
|
||||
struct MismatchedBlock {
|
||||
original_begin_line: u32,
|
||||
original_end_line: u32,
|
||||
@ -20,26 +19,20 @@ struct MismatchedBlock {
|
||||
expected: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
#[derive(Debug, Default, PartialEq, Serialize)]
|
||||
struct MismatchedFile {
|
||||
name: String,
|
||||
mismatches: Vec<MismatchedBlock>,
|
||||
}
|
||||
|
||||
impl Emitter for JsonEmitter {
|
||||
fn emit_header(&self, output: &mut dyn Write) -> Result<(), io::Error> {
|
||||
write!(output, "[")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn emit_footer(&self, output: &mut dyn Write) -> Result<(), io::Error> {
|
||||
write!(output, "]")?;
|
||||
Ok(())
|
||||
writeln!(output, "{}", &to_json_string(&self.mismatched_files)?)
|
||||
}
|
||||
|
||||
fn emit_formatted_file(
|
||||
&mut self,
|
||||
output: &mut dyn Write,
|
||||
_output: &mut dyn Write,
|
||||
FormattedFile {
|
||||
filename,
|
||||
original_text,
|
||||
@ -47,71 +40,67 @@ fn emit_formatted_file(
|
||||
}: FormattedFile<'_>,
|
||||
) -> Result<EmitterResult, io::Error> {
|
||||
const CONTEXT_SIZE: usize = 0;
|
||||
let filename = ensure_real_path(filename);
|
||||
let diff = make_diff(original_text, formatted_text, CONTEXT_SIZE);
|
||||
let has_diff = !diff.is_empty();
|
||||
|
||||
if has_diff {
|
||||
output_json_file(output, filename, diff, self.num_files)?;
|
||||
self.num_files += 1;
|
||||
self.add_misformatted_file(filename, diff)?;
|
||||
}
|
||||
|
||||
Ok(EmitterResult { has_diff })
|
||||
}
|
||||
}
|
||||
|
||||
fn output_json_file<T>(
|
||||
mut writer: T,
|
||||
filename: &Path,
|
||||
diff: Vec<Mismatch>,
|
||||
num_emitted_files: u32,
|
||||
) -> Result<(), io::Error>
|
||||
where
|
||||
T: Write,
|
||||
{
|
||||
let mut mismatches = vec![];
|
||||
for mismatch in diff {
|
||||
let original_begin_line = mismatch.line_number_orig;
|
||||
let expected_begin_line = mismatch.line_number;
|
||||
let mut original_end_line = original_begin_line;
|
||||
let mut expected_end_line = expected_begin_line;
|
||||
let mut original_line_counter = 0;
|
||||
let mut expected_line_counter = 0;
|
||||
let mut original_lines = vec![];
|
||||
let mut expected_lines = vec![];
|
||||
impl JsonEmitter {
|
||||
fn add_misformatted_file(
|
||||
&mut self,
|
||||
filename: &FileName,
|
||||
diff: Vec<Mismatch>,
|
||||
) -> Result<(), io::Error> {
|
||||
let mut mismatches = vec![];
|
||||
for mismatch in diff {
|
||||
let original_begin_line = mismatch.line_number_orig;
|
||||
let expected_begin_line = mismatch.line_number;
|
||||
let mut original_end_line = original_begin_line;
|
||||
let mut expected_end_line = expected_begin_line;
|
||||
let mut original_line_counter = 0;
|
||||
let mut expected_line_counter = 0;
|
||||
let mut original = String::new();
|
||||
let mut expected = String::new();
|
||||
|
||||
for line in mismatch.lines {
|
||||
match line {
|
||||
DiffLine::Expected(msg) => {
|
||||
expected_end_line = expected_begin_line + expected_line_counter;
|
||||
expected_line_counter += 1;
|
||||
expected_lines.push(msg)
|
||||
for line in mismatch.lines {
|
||||
match line {
|
||||
DiffLine::Expected(msg) => {
|
||||
expected_end_line = expected_begin_line + expected_line_counter;
|
||||
expected_line_counter += 1;
|
||||
expected.push_str(&msg);
|
||||
expected.push('\n');
|
||||
}
|
||||
DiffLine::Resulting(msg) => {
|
||||
original_end_line = original_begin_line + original_line_counter;
|
||||
original_line_counter += 1;
|
||||
original.push_str(&msg);
|
||||
original.push('\n');
|
||||
}
|
||||
DiffLine::Context(_) => continue,
|
||||
}
|
||||
DiffLine::Resulting(msg) => {
|
||||
original_end_line = original_begin_line + original_line_counter;
|
||||
original_line_counter += 1;
|
||||
original_lines.push(msg)
|
||||
}
|
||||
DiffLine::Context(_) => continue,
|
||||
}
|
||||
}
|
||||
|
||||
mismatches.push(MismatchedBlock {
|
||||
original_begin_line,
|
||||
original_end_line,
|
||||
expected_begin_line,
|
||||
expected_end_line,
|
||||
original: original_lines.join("\n"),
|
||||
expected: expected_lines.join("\n"),
|
||||
mismatches.push(MismatchedBlock {
|
||||
original_begin_line,
|
||||
original_end_line,
|
||||
expected_begin_line,
|
||||
expected_end_line,
|
||||
original,
|
||||
expected,
|
||||
});
|
||||
}
|
||||
self.mismatched_files.push(MismatchedFile {
|
||||
name: format!("{}", filename),
|
||||
mismatches,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
let json = to_json_string(&MismatchedFile {
|
||||
name: String::from(filename.to_str().unwrap()),
|
||||
mismatches,
|
||||
})?;
|
||||
let prefix = if num_emitted_files > 0 { "," } else { "" };
|
||||
write!(writer, "{}{}", prefix, &json)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -122,6 +111,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn expected_line_range_correct_when_single_line_split() {
|
||||
let mut emitter = JsonEmitter {
|
||||
mismatched_files: vec![],
|
||||
};
|
||||
let file = "foo/bar.rs";
|
||||
let mismatched_file = MismatchedFile {
|
||||
name: String::from(file),
|
||||
@ -130,8 +122,8 @@ fn expected_line_range_correct_when_single_line_split() {
|
||||
original_end_line: 79,
|
||||
expected_begin_line: 79,
|
||||
expected_end_line: 82,
|
||||
original: String::from("fn Foo<T>() where T: Bar {"),
|
||||
expected: String::from("fn Foo<T>()\nwhere\n T: Bar,\n{"),
|
||||
original: String::from("fn Foo<T>() where T: Bar {\n"),
|
||||
expected: String::from("fn Foo<T>()\nwhere\n T: Bar,\n{\n"),
|
||||
}],
|
||||
};
|
||||
let mismatch = Mismatch {
|
||||
@ -146,14 +138,19 @@ fn expected_line_range_correct_when_single_line_split() {
|
||||
],
|
||||
};
|
||||
|
||||
let mut writer = Vec::new();
|
||||
let exp_json = to_json_string(&mismatched_file).unwrap();
|
||||
let _ = output_json_file(&mut writer, &PathBuf::from(file), vec![mismatch], 0);
|
||||
assert_eq!(&writer[..], format!("{}", exp_json).as_bytes());
|
||||
let _ = emitter
|
||||
.add_misformatted_file(&FileName::Real(PathBuf::from(file)), vec![mismatch])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(emitter.mismatched_files.len(), 1);
|
||||
assert_eq!(emitter.mismatched_files[0], mismatched_file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn context_lines_ignored() {
|
||||
let mut emitter = JsonEmitter {
|
||||
mismatched_files: vec![],
|
||||
};
|
||||
let file = "src/lib.rs";
|
||||
let mismatched_file = MismatchedFile {
|
||||
name: String::from(file),
|
||||
@ -163,10 +160,10 @@ fn context_lines_ignored() {
|
||||
expected_begin_line: 5,
|
||||
expected_end_line: 5,
|
||||
original: String::from(
|
||||
"fn foo(_x: &u64) -> Option<&(dyn::std::error::Error + 'static)> {",
|
||||
"fn foo(_x: &u64) -> Option<&(dyn::std::error::Error + 'static)> {\n",
|
||||
),
|
||||
expected: String::from(
|
||||
"fn foo(_x: &u64) -> Option<&(dyn ::std::error::Error + 'static)> {",
|
||||
"fn foo(_x: &u64) -> Option<&(dyn ::std::error::Error + 'static)> {\n",
|
||||
),
|
||||
}],
|
||||
};
|
||||
@ -186,10 +183,12 @@ fn context_lines_ignored() {
|
||||
],
|
||||
};
|
||||
|
||||
let mut writer = Vec::new();
|
||||
let exp_json = to_json_string(&mismatched_file).unwrap();
|
||||
let _ = output_json_file(&mut writer, &PathBuf::from(file), vec![mismatch], 0);
|
||||
assert_eq!(&writer[..], format!("{}", exp_json).as_bytes());
|
||||
let _ = emitter
|
||||
.add_misformatted_file(&FileName::Real(PathBuf::from(file)), vec![mismatch])
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(emitter.mismatched_files.len(), 1);
|
||||
assert_eq!(emitter.mismatched_files[0], mismatched_file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -209,7 +208,7 @@ fn emits_empty_array_on_no_diffs() {
|
||||
.unwrap();
|
||||
let _ = emitter.emit_footer(&mut writer);
|
||||
assert_eq!(result.has_diff, false);
|
||||
assert_eq!(&writer[..], "[]".as_bytes());
|
||||
assert_eq!(&writer[..], "[]\n".as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -255,7 +254,7 @@ fn emits_array_with_files_with_diffs() {
|
||||
)
|
||||
.unwrap();
|
||||
let _ = emitter.emit_footer(&mut writer);
|
||||
let exp_json = to_json_string(&MismatchedFile {
|
||||
let exp_json = to_json_string(&vec![MismatchedFile {
|
||||
name: String::from(file_name),
|
||||
mismatches: vec![
|
||||
MismatchedBlock {
|
||||
@ -263,8 +262,8 @@ fn emits_array_with_files_with_diffs() {
|
||||
original_end_line: 2,
|
||||
expected_begin_line: 2,
|
||||
expected_end_line: 2,
|
||||
original: String::from("println!(\"Hello, world!\");"),
|
||||
expected: String::from(" println!(\"Hello, world!\");"),
|
||||
original: String::from("println!(\"Hello, world!\");\n"),
|
||||
expected: String::from(" println!(\"Hello, world!\");\n"),
|
||||
},
|
||||
MismatchedBlock {
|
||||
original_begin_line: 7,
|
||||
@ -272,17 +271,17 @@ fn emits_array_with_files_with_diffs() {
|
||||
expected_begin_line: 7,
|
||||
expected_end_line: 10,
|
||||
original: String::from(
|
||||
"#[test]\nfn it_works() {\n assert_eq!(2 + 2, 4);\n}",
|
||||
"#[test]\nfn it_works() {\n assert_eq!(2 + 2, 4);\n}\n",
|
||||
),
|
||||
expected: String::from(
|
||||
" #[test]\n fn it_works() {\n assert_eq!(2 + 2, 4);\n }",
|
||||
" #[test]\n fn it_works() {\n assert_eq!(2 + 2, 4);\n }\n",
|
||||
),
|
||||
},
|
||||
],
|
||||
})
|
||||
}])
|
||||
.unwrap();
|
||||
assert_eq!(result.has_diff, true);
|
||||
assert_eq!(&writer[..], format!("[{}]", exp_json).as_bytes());
|
||||
assert_eq!(&writer[..], format!("{}\n", exp_json).as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -317,33 +316,31 @@ fn emits_valid_json_with_multiple_files() {
|
||||
)
|
||||
.unwrap();
|
||||
let _ = emitter.emit_footer(&mut writer);
|
||||
let exp_bin_json = to_json_string(&MismatchedFile {
|
||||
let exp_bin = MismatchedFile {
|
||||
name: String::from(bin_file),
|
||||
mismatches: vec![MismatchedBlock {
|
||||
original_begin_line: 2,
|
||||
original_end_line: 2,
|
||||
expected_begin_line: 2,
|
||||
expected_end_line: 2,
|
||||
original: String::from("println!(\"Hello, world!\");"),
|
||||
expected: String::from(" println!(\"Hello, world!\");"),
|
||||
original: String::from("println!(\"Hello, world!\");\n"),
|
||||
expected: String::from(" println!(\"Hello, world!\");\n"),
|
||||
}],
|
||||
})
|
||||
.unwrap();
|
||||
let exp_lib_json = to_json_string(&MismatchedFile {
|
||||
};
|
||||
|
||||
let exp_lib = MismatchedFile {
|
||||
name: String::from(lib_file),
|
||||
mismatches: vec![MismatchedBlock {
|
||||
original_begin_line: 2,
|
||||
original_end_line: 2,
|
||||
expected_begin_line: 2,
|
||||
expected_end_line: 2,
|
||||
original: String::from("println!(\"Greetings!\");"),
|
||||
expected: String::from(" println!(\"Greetings!\");"),
|
||||
original: String::from("println!(\"Greetings!\");\n"),
|
||||
expected: String::from(" println!(\"Greetings!\");\n"),
|
||||
}],
|
||||
})
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
&writer[..],
|
||||
format!("[{},{}]", exp_bin_json, exp_lib_json).as_bytes()
|
||||
);
|
||||
};
|
||||
|
||||
let exp_json = to_json_string(&vec![exp_bin, exp_lib]).unwrap();
|
||||
assert_eq!(&writer[..], format!("{}\n", exp_json).as_bytes());
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ pub fn new(report: &'a FormatReport) -> Self {
|
||||
}
|
||||
|
||||
/// Enables colors and formatting in the output.
|
||||
#[must_use]
|
||||
pub fn enable_colors(self, enable_colors: bool) -> Self {
|
||||
Self {
|
||||
enable_colors,
|
||||
|
@ -152,7 +152,7 @@ pub(crate) fn rewrite_macro(
|
||||
) -> Option<String> {
|
||||
let should_skip = context
|
||||
.skip_context
|
||||
.skip_macro(&context.snippet(mac.path.span).to_owned());
|
||||
.skip_macro(context.snippet(mac.path.span));
|
||||
if should_skip {
|
||||
None
|
||||
} else {
|
||||
|
@ -458,6 +458,7 @@ fn push_inline_mod_directory(&mut self, id: symbol::Ident, attrs: &[ast::Attribu
|
||||
self.directory.path.push(path.as_str());
|
||||
self.directory.ownership = DirectoryOwnership::Owned { relative: None };
|
||||
} else {
|
||||
let id = id.as_str();
|
||||
// We have to push on the current module name in the case of relative
|
||||
// paths in order to ensure that any additional module paths from inline
|
||||
// `mod x { ... }` come after the relative extension.
|
||||
@ -468,9 +469,15 @@ fn push_inline_mod_directory(&mut self, id: symbol::Ident, attrs: &[ast::Attribu
|
||||
if let Some(ident) = relative.take() {
|
||||
// remove the relative offset
|
||||
self.directory.path.push(ident.as_str());
|
||||
|
||||
// In the case where there is an x.rs and an ./x directory we want
|
||||
// to prevent adding x twice. For example, ./x/x
|
||||
if self.directory.path.exists() && !self.directory.path.join(id).exists() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.directory.path.push(id.as_str());
|
||||
self.directory.path.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
123
src/test/mod.rs
123
src/test/mod.rs
@ -307,6 +307,52 @@ fn assert_output(source: &Path, expected_filename: &Path) {
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function for comparing the results of rustfmt
|
||||
// to a known output generated by one of the write modes.
|
||||
fn assert_stdin_output(
|
||||
source: &Path,
|
||||
expected_filename: &Path,
|
||||
emit_mode: EmitMode,
|
||||
has_diff: bool,
|
||||
) {
|
||||
let mut config = Config::default();
|
||||
config.set().newline_style(NewlineStyle::Unix);
|
||||
config.set().emit_mode(emit_mode);
|
||||
|
||||
let mut source_file = fs::File::open(&source).expect("couldn't open source");
|
||||
let mut source_text = String::new();
|
||||
source_file
|
||||
.read_to_string(&mut source_text)
|
||||
.expect("Failed reading target");
|
||||
let input = Input::Text(source_text);
|
||||
|
||||
// Populate output by writing to a vec.
|
||||
let mut buf: Vec<u8> = vec![];
|
||||
{
|
||||
let mut session = Session::new(config, Some(&mut buf));
|
||||
session.format(input).unwrap();
|
||||
let errors = ReportedErrors {
|
||||
has_diff: has_diff,
|
||||
..Default::default()
|
||||
};
|
||||
assert_eq!(session.errors, errors);
|
||||
}
|
||||
|
||||
let mut expected_file = fs::File::open(&expected_filename).expect("couldn't open target");
|
||||
let mut expected_text = String::new();
|
||||
expected_file
|
||||
.read_to_string(&mut expected_text)
|
||||
.expect("Failed reading target");
|
||||
|
||||
let output = String::from_utf8(buf).unwrap();
|
||||
let compare = make_diff(&expected_text, &output, DIFF_CONTEXT_SIZE);
|
||||
if !compare.is_empty() {
|
||||
let mut failures = HashMap::new();
|
||||
failures.insert(source.to_owned(), compare);
|
||||
print_mismatches_default_message(failures);
|
||||
panic!("Text does not match expected output");
|
||||
}
|
||||
}
|
||||
// Idempotence tests. Files in tests/target are checked to be unaltered by
|
||||
// rustfmt.
|
||||
#[nightly_only_test]
|
||||
@ -420,9 +466,9 @@ fn stdin_formatting_smoke_test() {
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
assert_eq!(buf, "stdin:\n\nfn main() {}\n".as_bytes());
|
||||
assert_eq!(buf, "<stdin>:\n\nfn main() {}\n".as_bytes());
|
||||
#[cfg(windows)]
|
||||
assert_eq!(buf, "stdin:\n\nfn main() {}\r\n".as_bytes());
|
||||
assert_eq!(buf, "<stdin>:\n\nfn main() {}\r\n".as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -463,6 +509,30 @@ fn stdin_works_with_modified_lines() {
|
||||
assert_eq!(buf, output.as_bytes());
|
||||
}
|
||||
|
||||
/// Ensures that `EmitMode::Json` works with input from `stdin`.
|
||||
#[test]
|
||||
fn stdin_works_with_json() {
|
||||
init_log();
|
||||
assert_stdin_output(
|
||||
Path::new("tests/writemode/source/stdin.rs"),
|
||||
Path::new("tests/writemode/target/stdin.json"),
|
||||
EmitMode::Json,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
/// Ensures that `EmitMode::Checkstyle` works with input from `stdin`.
|
||||
#[test]
|
||||
fn stdin_works_with_checkstyle() {
|
||||
init_log();
|
||||
assert_stdin_output(
|
||||
Path::new("tests/writemode/source/stdin.rs"),
|
||||
Path::new("tests/writemode/target/stdin.xml"),
|
||||
EmitMode::Checkstyle,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stdin_disable_all_formatting_test() {
|
||||
init_log();
|
||||
@ -914,3 +984,52 @@ fn verify_check_works() {
|
||||
.status()
|
||||
.expect("run with check option failed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_check_works_with_stdin() {
|
||||
init_log();
|
||||
|
||||
let mut child = Command::new(rustfmt().to_str().unwrap())
|
||||
.arg("--check")
|
||||
.stdin(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("run with check option failed");
|
||||
|
||||
{
|
||||
let stdin = child.stdin.as_mut().expect("Failed to open stdin");
|
||||
stdin
|
||||
.write_all("fn main() {}\n".as_bytes())
|
||||
.expect("Failed to write to rustfmt --check");
|
||||
}
|
||||
let output = child
|
||||
.wait_with_output()
|
||||
.expect("Failed to wait on rustfmt child");
|
||||
assert!(output.status.success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_check_l_works_with_stdin() {
|
||||
init_log();
|
||||
|
||||
let mut child = Command::new(rustfmt().to_str().unwrap())
|
||||
.arg("--check")
|
||||
.arg("-l")
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("run with check option failed");
|
||||
|
||||
{
|
||||
let stdin = child.stdin.as_mut().expect("Failed to open stdin");
|
||||
stdin
|
||||
.write_all("fn main()\n{}\n".as_bytes())
|
||||
.expect("Failed to write to rustfmt --check");
|
||||
}
|
||||
let output = child
|
||||
.wait_with_output()
|
||||
.expect("Failed to wait on rustfmt child");
|
||||
assert!(output.status.success());
|
||||
assert_eq!(std::str::from_utf8(&output.stdout).unwrap(), "<stdin>\n");
|
||||
}
|
||||
|
@ -50,3 +50,17 @@ fn skip_out_of_line_nested_inline_within_out_of_line() {
|
||||
&["tests/mod-resolver/skip-files-issue-5065/one.rs"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fmt_out_of_line_test_modules() {
|
||||
// See also https://github.com/rust-lang/rustfmt/issues/5119
|
||||
verify_mod_resolution(
|
||||
"tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs",
|
||||
&[
|
||||
"tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs",
|
||||
"tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs",
|
||||
"tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs",
|
||||
"tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs",
|
||||
],
|
||||
)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
use std::path::Path;
|
||||
|
||||
/// Run the cargo-fmt executable and return its output.
|
||||
fn cargo_fmt(args: &[&str]) -> (String, String) {
|
||||
@ -71,3 +72,26 @@ fn rustfmt_help() {
|
||||
assert_that!(&["--", "-h"], contains("Format Rust code"));
|
||||
assert_that!(&["--", "--help=config"], contains("Configuration Options:"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cargo_fmt_out_of_line_test_modules() {
|
||||
// See also https://github.com/rust-lang/rustfmt/issues/5119
|
||||
let expected_modified_files = [
|
||||
"tests/mod-resolver/test-submodule-issue-5119/src/lib.rs",
|
||||
"tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs",
|
||||
"tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs",
|
||||
"tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs",
|
||||
"tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs",
|
||||
];
|
||||
let args = [
|
||||
"-v",
|
||||
"--check",
|
||||
"--manifest-path",
|
||||
"tests/mod-resolver/test-submodule-issue-5119/Cargo.toml",
|
||||
];
|
||||
let (stdout, _) = cargo_fmt(&args);
|
||||
for file in expected_modified_files {
|
||||
let path = Path::new(file).canonicalize().unwrap();
|
||||
assert!(stdout.contains(&format!("Diff in {}", path.display())))
|
||||
}
|
||||
}
|
||||
|
8
tests/mod-resolver/test-submodule-issue-5119/Cargo.toml
Normal file
8
tests/mod-resolver/test-submodule-issue-5119/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "rustfmt-test-submodule-issue"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
7
tests/mod-resolver/test-submodule-issue-5119/src/lib.rs
Normal file
7
tests/mod-resolver/test-submodule-issue-5119/src/lib.rs
Normal file
@ -0,0 +1,7 @@
|
||||
pub fn foo() -> i32 {
|
||||
3
|
||||
}
|
||||
|
||||
pub fn bar() -> i32 {
|
||||
4
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
mod test1 {
|
||||
#[cfg(unix)]
|
||||
mod sub1;
|
||||
#[cfg(not(unix))]
|
||||
mod sub2;
|
||||
|
||||
mod sub3;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
use rustfmt_test_submodule_issue::foo;
|
||||
|
||||
#[test]
|
||||
fn test_foo() {
|
||||
assert_eq!(3, foo());
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
use rustfmt_test_submodule_issue::bar;
|
||||
|
||||
#[test]
|
||||
fn test_bar() {
|
||||
assert_eq!(4, bar());
|
||||
}
|
@ -0,0 +1 @@
|
||||
mod sub4;
|
6
tests/writemode/source/stdin.rs
Normal file
6
tests/writemode/source/stdin.rs
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
fn
|
||||
some( )
|
||||
{
|
||||
}
|
||||
fn main () {}
|
@ -1 +1 @@
|
||||
[{"name":"tests/writemode/source/json.rs","mismatches":[{"original_begin_line":5,"original_end_line":7,"expected_begin_line":5,"expected_end_line":5,"original":"fn foo_expr() {\n 1\n}","expected":"fn foo_expr() { 1 }"},{"original_begin_line":9,"original_end_line":11,"expected_begin_line":7,"expected_end_line":7,"original":"fn foo_stmt() {\n foo();\n}","expected":"fn foo_stmt() { foo(); }"},{"original_begin_line":13,"original_end_line":15,"expected_begin_line":9,"expected_end_line":9,"original":"fn foo_decl_local() {\n let z = 5;\n }","expected":"fn foo_decl_local() { let z = 5; }"},{"original_begin_line":17,"original_end_line":19,"expected_begin_line":11,"expected_end_line":11,"original":"fn foo_decl_item(x: &mut i32) {\n x = 3;\n}","expected":"fn foo_decl_item(x: &mut i32) { x = 3; }"},{"original_begin_line":21,"original_end_line":21,"expected_begin_line":13,"expected_end_line":13,"original":" fn empty() {","expected":"fn empty() {}"},{"original_begin_line":23,"original_end_line":23,"expected_begin_line":15,"expected_end_line":15,"original":"}","expected":"fn foo_return() -> String { \"yay\" }"},{"original_begin_line":25,"original_end_line":29,"expected_begin_line":17,"expected_end_line":20,"original":"fn foo_return() -> String {\n \"yay\"\n}\n\nfn foo_where() -> T where T: Sync {","expected":"fn foo_where() -> T\nwhere\n T: Sync,\n{"},{"original_begin_line":64,"original_end_line":66,"expected_begin_line":55,"expected_end_line":55,"original":"fn lots_of_space () {\n 1 \n}","expected":"fn lots_of_space() { 1 }"},{"original_begin_line":71,"original_end_line":72,"expected_begin_line":60,"expected_end_line":60,"original":" fn dummy(&self) {\n }","expected":" fn dummy(&self) {}"},{"original_begin_line":75,"original_end_line":75,"expected_begin_line":63,"expected_end_line":64,"original":"trait CoolerTypes { fn dummy(&self) { ","expected":"trait CoolerTypes {\n fn dummy(&self) {}"},{"original_begin_line":77,"original_end_line":77,"expected_begin_line":66,"expected_end_line":66,"original":"}","expected":""},{"original_begin_line":79,"original_end_line":79,"expected_begin_line":67,"expected_end_line":70,"original":"fn Foo<T>() where T: Bar {","expected":"fn Foo<T>()\nwhere\n T: Bar,\n{"}]}]
|
||||
[{"name":"tests/writemode/source/json.rs","mismatches":[{"original_begin_line":5,"original_end_line":7,"expected_begin_line":5,"expected_end_line":5,"original":"fn foo_expr() {\n 1\n}\n","expected":"fn foo_expr() { 1 }\n"},{"original_begin_line":9,"original_end_line":11,"expected_begin_line":7,"expected_end_line":7,"original":"fn foo_stmt() {\n foo();\n}\n","expected":"fn foo_stmt() { foo(); }\n"},{"original_begin_line":13,"original_end_line":15,"expected_begin_line":9,"expected_end_line":9,"original":"fn foo_decl_local() {\n let z = 5;\n }\n","expected":"fn foo_decl_local() { let z = 5; }\n"},{"original_begin_line":17,"original_end_line":19,"expected_begin_line":11,"expected_end_line":11,"original":"fn foo_decl_item(x: &mut i32) {\n x = 3;\n}\n","expected":"fn foo_decl_item(x: &mut i32) { x = 3; }\n"},{"original_begin_line":21,"original_end_line":21,"expected_begin_line":13,"expected_end_line":13,"original":" fn empty() {\n","expected":"fn empty() {}\n"},{"original_begin_line":23,"original_end_line":23,"expected_begin_line":15,"expected_end_line":15,"original":"}\n","expected":"fn foo_return() -> String { \"yay\" }\n"},{"original_begin_line":25,"original_end_line":29,"expected_begin_line":17,"expected_end_line":20,"original":"fn foo_return() -> String {\n \"yay\"\n}\n\nfn foo_where() -> T where T: Sync {\n","expected":"fn foo_where() -> T\nwhere\n T: Sync,\n{\n"},{"original_begin_line":64,"original_end_line":66,"expected_begin_line":55,"expected_end_line":55,"original":"fn lots_of_space () {\n 1 \n}\n","expected":"fn lots_of_space() { 1 }\n"},{"original_begin_line":71,"original_end_line":72,"expected_begin_line":60,"expected_end_line":60,"original":" fn dummy(&self) {\n }\n","expected":" fn dummy(&self) {}\n"},{"original_begin_line":75,"original_end_line":75,"expected_begin_line":63,"expected_end_line":64,"original":"trait CoolerTypes { fn dummy(&self) { \n","expected":"trait CoolerTypes {\n fn dummy(&self) {}\n"},{"original_begin_line":77,"original_end_line":77,"expected_begin_line":66,"expected_end_line":66,"original":"}\n","expected":""},{"original_begin_line":79,"original_end_line":79,"expected_begin_line":67,"expected_end_line":70,"original":"fn Foo<T>() where T: Bar {\n","expected":"fn Foo<T>()\nwhere\n T: Bar,\n{\n"}]}]
|
||||
|
1
tests/writemode/target/stdin.json
Normal file
1
tests/writemode/target/stdin.json
Normal file
@ -0,0 +1 @@
|
||||
[{"name":"<stdin>","mismatches":[{"original_begin_line":1,"original_end_line":6,"expected_begin_line":1,"expected_end_line":2,"original":"\nfn\n some( )\n{\n}\nfn main () {}\n","expected":"fn some() {}\nfn main() {}\n"}]}]
|
2
tests/writemode/target/stdin.xml
Normal file
2
tests/writemode/target/stdin.xml
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<checkstyle version="4.3"><file name="<stdin>"><error line="1" severity="warning" message="Should be `fn some() {}`" /><error line="2" severity="warning" message="Should be `fn main() {}`" /></file></checkstyle>
|
Loading…
Reference in New Issue
Block a user