diff --git a/Cargo.toml b/Cargo.toml index 964d006..e6d1321 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,9 +27,9 @@ log = "0.4.1" duct = "0.8.2" env_logger = "0.5.0-rc.1" log = "0.4.1" -pretty_assertions = "0.4.1" tempdir = "0.3.5" proptest = "0.7.0" +difference = "2.0.0" [workspace] members = [ diff --git a/tests/fixtures/.gitignore b/tests/edition/.gitignore similarity index 100% rename from tests/fixtures/.gitignore rename to tests/edition/.gitignore diff --git a/tests/everything.rs b/tests/everything.rs deleted file mode 100644 index 0d42e1a..0000000 --- a/tests/everything.rs +++ /dev/null @@ -1,158 +0,0 @@ -#![cfg(not(windows))] // TODO: should fix these tests on Windows - -#[macro_use] -extern crate duct; -extern crate env_logger; -#[macro_use] -extern crate log; -#[macro_use] -extern crate pretty_assertions; -extern crate rustfix; -extern crate serde_json; -extern crate tempdir; - -use std::fs; -use std::error::Error; -use std::path::{Path, PathBuf}; -use std::collections::HashSet; -use std::process::Output; -use tempdir::TempDir; - -use rustfix::apply_suggestions; - -fn compile(file: &Path) -> Result<Output, Box<Error>> { - let tmp = TempDir::new("rustfix-tests")?; - let better_call_clippy = cmd!( - "rustc", - file, - "--error-format=pretty-json", - "-Zunstable-options", - "--emit=metadata", - "--crate-name=rustfix_test", - "-Zsuggestion-applicability", - "--out-dir", - tmp.path() - ); - let res = better_call_clippy - .env("CLIPPY_DISABLE_DOCS_LINKS", "true") - .stdout_capture() - .stderr_capture() - .unchecked() - .run()?; - - Ok(res) -} - -fn compile_and_get_json_errors(file: &Path) -> Result<String, Box<Error>> { - let res = compile(file)?; - let stderr = String::from_utf8(res.stderr)?; - - use std::io::{Error, ErrorKind}; - match res.status.code() { - Some(0) | Some(1) | Some(101) => Ok(stderr), - _ => Err(Box::new(Error::new( - ErrorKind::Other, - format!("failed with status {:?}: {}", res.status.code(), stderr), - ))), - } -} - -fn compiles_without_errors(file: &Path) -> Result<(), Box<Error>> { - let res = compile(file)?; - - use std::io::{Error, ErrorKind}; - match res.status.code() { - Some(0) => Ok(()), - _ => { - info!( - "file {:?} failed to compile:\n{}", - file, - String::from_utf8(res.stderr)? - ); - Err(Box::new(Error::new( - ErrorKind::Other, - format!( - "failed with status {:?} (`env RUST_LOG=everything=info` for more info)", - res.status.code(), - ), - ))) - } - } -} - -fn read_file(path: &Path) -> Result<String, Box<Error>> { - use std::io::Read; - - let mut buffer = String::new(); - let mut file = fs::File::open(path)?; - file.read_to_string(&mut buffer)?; - Ok(buffer) -} - -fn test_rustfix_with_file<P: AsRef<Path>>(file: P) -> Result<(), Box<Error>> { - let file: &Path = file.as_ref(); - let json_file = file.with_extension("json"); - let fixed_file = file.with_extension("fixed.rs"); - - debug!("next up: {:?}", file); - let code = read_file(file)?; - let errors = compile_and_get_json_errors(file)?; - let suggestions = rustfix::get_suggestions_from_json(&errors, &HashSet::new()) - .expect("could not load suggestions"); - - if std::env::var("RUSTFIX_TEST_RECORD_JSON").is_ok() { - use std::io::Write; - let mut recorded_json = fs::File::create(&file.with_extension("recorded.json"))?; - recorded_json.write_all(errors.as_bytes())?; - } - - let expected_json = read_file(&json_file)?; - let expected_suggestions = rustfix::get_suggestions_from_json(&expected_json, &HashSet::new()) - .expect("could not load expected suggesitons"); - assert_eq!( - expected_suggestions, suggestions, - "got unexpected suggestions from clippy", - ); - - let fixed = apply_suggestions(&code, &suggestions)?; - - if std::env::var("RUSTFIX_TEST_RECORD_FIXED_RUST").is_ok() { - use std::io::Write; - let mut recorded_rust = fs::File::create(&file.with_extension("recorded.rs"))?; - recorded_rust.write_all(fixed.as_bytes())?; - } - - let expected_fixed = read_file(&fixed_file)?; - assert_eq!( - fixed.trim(), - expected_fixed.trim(), - "file {} doesn't look fixed", - file.display() - ); - - compiles_without_errors(&fixed_file)?; - - Ok(()) -} - -fn get_fixture_files() -> Result<Vec<PathBuf>, Box<Error>> { - Ok(fs::read_dir("./tests/fixtures")? - .into_iter() - .map(|e| e.unwrap().path()) - .filter(|p| p.is_file()) - .filter(|p| { - let x = p.to_string_lossy(); - x.ends_with(".rs") && !x.ends_with(".fixed.rs") && !x.ends_with(".recorded.rs") - }) - .collect()) -} - -#[test] -fn fixtures() { - let _ = env_logger::try_init(); - - for file in &get_fixture_files().unwrap() { - test_rustfix_with_file(file).unwrap(); - info!("passed: {:?}", file); - } -} diff --git a/tests/everything/.gitignore b/tests/everything/.gitignore new file mode 100644 index 0000000..bfb599d --- /dev/null +++ b/tests/everything/.gitignore @@ -0,0 +1,2 @@ +*.recorded.json +*.recorded.rs diff --git a/tests/fixtures/E0178.fixed.rs b/tests/everything/E0178.fixed.rs similarity index 100% rename from tests/fixtures/E0178.fixed.rs rename to tests/everything/E0178.fixed.rs diff --git a/tests/fixtures/E0178.json b/tests/everything/E0178.json similarity index 84% rename from tests/fixtures/E0178.json rename to tests/everything/E0178.json index 52ac88c..89f15b5 100644 --- a/tests/fixtures/E0178.json +++ b/tests/everything/E0178.json @@ -7,7 +7,7 @@ "level": "error", "spans": [ { - "file_name": "./tests/fixtures/E0178.rs", + "file_name": "./tests/everything/E0178.rs", "byte_start": 60, "byte_end": 74, "line_start": 6, @@ -34,7 +34,7 @@ "level": "help", "spans": [ { - "file_name": "./tests/fixtures/E0178.rs", + "file_name": "./tests/everything/E0178.rs", "byte_start": 60, "byte_end": 74, "line_start": 6, @@ -58,7 +58,7 @@ "rendered": null } ], - "rendered": "error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`\n --> ./tests/fixtures/E0178.rs:6:8\n |\n6 | w: &'a Foo + Send,\n | ^^^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + Send)`\n\nIf you want more information on this error, try using \"rustc --explain E0178\"\n" + "rendered": "error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`\n --> ./tests/everything/E0178.rs:6:8\n |\n6 | w: &'a Foo + Send,\n | ^^^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + Send)`\n\nIf you want more information on this error, try using \"rustc --explain E0178\"\n" } { "message": "aborting due to previous error", diff --git a/tests/fixtures/E0178.rs b/tests/everything/E0178.rs similarity index 100% rename from tests/fixtures/E0178.rs rename to tests/everything/E0178.rs diff --git a/tests/fixtures/closure-immutable-outer-variable.fixed.rs b/tests/everything/closure-immutable-outer-variable.fixed.rs similarity index 100% rename from tests/fixtures/closure-immutable-outer-variable.fixed.rs rename to tests/everything/closure-immutable-outer-variable.fixed.rs diff --git a/tests/fixtures/closure-immutable-outer-variable.json b/tests/everything/closure-immutable-outer-variable.json similarity index 73% rename from tests/fixtures/closure-immutable-outer-variable.json rename to tests/everything/closure-immutable-outer-variable.json index 3ecfb41..f7afa49 100644 --- a/tests/fixtures/closure-immutable-outer-variable.json +++ b/tests/everything/closure-immutable-outer-variable.json @@ -7,7 +7,7 @@ "level": "error", "spans": [ { - "file_name": "./tests/fixtures/closure-immutable-outer-variable.rs", + "file_name": "./tests/everything/closure-immutable-outer-variable.rs", "byte_start": 615, "byte_end": 624, "line_start": 19, @@ -34,7 +34,7 @@ "level": "help", "spans": [ { - "file_name": "./tests/fixtures/closure-immutable-outer-variable.rs", + "file_name": "./tests/everything/closure-immutable-outer-variable.rs", "byte_start": 580, "byte_end": 581, "line_start": 18, @@ -58,7 +58,7 @@ "rendered": null } ], - "rendered": "error[E0594]: cannot assign to captured outer variable in an `FnMut` closure\n --> ./tests/fixtures/closure-immutable-outer-variable.rs:19:26\n |\n18 | let y = true;\n | - help: consider making `y` mutable: `mut y`\n19 | foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to captured outer variable\n | ^^^^^^^^^\n\nIf you want more information on this error, try using \"rustc --explain E0594\"\n" + "rendered": "error[E0594]: cannot assign to captured outer variable in an `FnMut` closure\n --> ./tests/everything/closure-immutable-outer-variable.rs:19:26\n |\n18 | let y = true;\n | - help: consider making `y` mutable: `mut y`\n19 | foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to captured outer variable\n | ^^^^^^^^^\n\nIf you want more information on this error, try using \"rustc --explain E0594\"\n" } { "message": "aborting due to previous error", diff --git a/tests/fixtures/closure-immutable-outer-variable.rs b/tests/everything/closure-immutable-outer-variable.rs similarity index 100% rename from tests/fixtures/closure-immutable-outer-variable.rs rename to tests/everything/closure-immutable-outer-variable.rs diff --git a/tests/fixtures/lt-generic-comp.fixed.rs b/tests/everything/lt-generic-comp.fixed.rs similarity index 100% rename from tests/fixtures/lt-generic-comp.fixed.rs rename to tests/everything/lt-generic-comp.fixed.rs diff --git a/tests/fixtures/lt-generic-comp.json b/tests/everything/lt-generic-comp.json similarity index 79% rename from tests/fixtures/lt-generic-comp.json rename to tests/everything/lt-generic-comp.json index 4230585..0634762 100644 --- a/tests/fixtures/lt-generic-comp.json +++ b/tests/everything/lt-generic-comp.json @@ -4,7 +4,7 @@ "level": "error", "spans": [ { - "file_name": "./tests/fixtures/lt-generic-comp.rs", + "file_name": "./tests/everything/lt-generic-comp.rs", "byte_start": 49, "byte_end": 50, "line_start": 4, @@ -24,7 +24,7 @@ "expansion": null }, { - "file_name": "./tests/fixtures/lt-generic-comp.rs", + "file_name": "./tests/everything/lt-generic-comp.rs", "byte_start": 47, "byte_end": 48, "line_start": 4, @@ -51,7 +51,7 @@ "level": "help", "spans": [ { - "file_name": "./tests/fixtures/lt-generic-comp.rs", + "file_name": "./tests/everything/lt-generic-comp.rs", "byte_start": 38, "byte_end": 46, "line_start": 4, @@ -75,7 +75,7 @@ "rendered": null } ], - "rendered": "error: `<` is interpreted as a start of generic arguments for `u32`, not a comparison\n --> ./tests/fixtures/lt-generic-comp.rs:4:17\n |\n4 | if x as u32 < 4 {\n | -------- ^ - interpreted as generic arguments\n | | |\n | | not interpreted as comparison\n | help: try comparing the cast value: `(x as u32)`\n\n" + "rendered": "error: `<` is interpreted as a start of generic arguments for `u32`, not a comparison\n --> ./tests/everything/lt-generic-comp.rs:4:17\n |\n4 | if x as u32 < 4 {\n | -------- ^ - interpreted as generic arguments\n | | |\n | | not interpreted as comparison\n | help: try comparing the cast value: `(x as u32)`\n\n" } { "message": "aborting due to previous error", diff --git a/tests/fixtures/lt-generic-comp.rs b/tests/everything/lt-generic-comp.rs similarity index 100% rename from tests/fixtures/lt-generic-comp.rs rename to tests/everything/lt-generic-comp.rs diff --git a/tests/fixtures/str-lit-type-mismatch.fixed.rs b/tests/everything/str-lit-type-mismatch.fixed.rs similarity index 100% rename from tests/fixtures/str-lit-type-mismatch.fixed.rs rename to tests/everything/str-lit-type-mismatch.fixed.rs diff --git a/tests/fixtures/str-lit-type-mismatch.json b/tests/everything/str-lit-type-mismatch.json similarity index 76% rename from tests/fixtures/str-lit-type-mismatch.json rename to tests/everything/str-lit-type-mismatch.json index 0e3e764..1c85251 100644 --- a/tests/fixtures/str-lit-type-mismatch.json +++ b/tests/everything/str-lit-type-mismatch.json @@ -7,7 +7,7 @@ "level": "error", "spans": [ { - "file_name": "./tests/fixtures/str-lit-type-mismatch.rs", + "file_name": "./tests/everything/str-lit-type-mismatch.rs", "byte_start": 499, "byte_end": 504, "line_start": 13, @@ -42,7 +42,7 @@ "level": "help", "spans": [ { - "file_name": "./tests/fixtures/str-lit-type-mismatch.rs", + "file_name": "./tests/everything/str-lit-type-mismatch.rs", "byte_start": 499, "byte_end": 504, "line_start": 13, @@ -66,7 +66,7 @@ "rendered": null } ], - "rendered": "error[E0308]: mismatched types\n --> ./tests/fixtures/str-lit-type-mismatch.rs:13:20\n |\n13 | let x: &[u8] = \"foo\"; //~ ERROR mismatched types\n | ^^^^^\n | |\n | expected slice, found str\n | help: consider adding a leading `b`: `b\"foo\"`\n |\n = note: expected type `&[u8]`\n found type `&'static str`\n\nIf you want more information on this error, try using \"rustc --explain E0308\"\n" + "rendered": "error[E0308]: mismatched types\n --> ./tests/everything/str-lit-type-mismatch.rs:13:20\n |\n13 | let x: &[u8] = \"foo\"; //~ ERROR mismatched types\n | ^^^^^\n | |\n | expected slice, found str\n | help: consider adding a leading `b`: `b\"foo\"`\n |\n = note: expected type `&[u8]`\n found type `&'static str`\n\nIf you want more information on this error, try using \"rustc --explain E0308\"\n" } { "message": "mismatched types", @@ -77,7 +77,7 @@ "level": "error", "spans": [ { - "file_name": "./tests/fixtures/str-lit-type-mismatch.rs", + "file_name": "./tests/everything/str-lit-type-mismatch.rs", "byte_start": 555, "byte_end": 561, "line_start": 14, @@ -112,7 +112,7 @@ "level": "help", "spans": [ { - "file_name": "./tests/fixtures/str-lit-type-mismatch.rs", + "file_name": "./tests/everything/str-lit-type-mismatch.rs", "byte_start": 555, "byte_end": 561, "line_start": 14, @@ -136,7 +136,7 @@ "rendered": null } ], - "rendered": "error[E0308]: mismatched types\n --> ./tests/fixtures/str-lit-type-mismatch.rs:14:23\n |\n14 | let y: &[u8; 4] = \"baaa\"; //~ ERROR mismatched types\n | ^^^^^^\n | |\n | expected array of 4 elements, found str\n | help: consider adding a leading `b`: `b\"baaa\"`\n |\n = note: expected type `&[u8; 4]`\n found type `&'static str`\n\nIf you want more information on this error, try using \"rustc --explain E0308\"\n" + "rendered": "error[E0308]: mismatched types\n --> ./tests/everything/str-lit-type-mismatch.rs:14:23\n |\n14 | let y: &[u8; 4] = \"baaa\"; //~ ERROR mismatched types\n | ^^^^^^\n | |\n | expected array of 4 elements, found str\n | help: consider adding a leading `b`: `b\"baaa\"`\n |\n = note: expected type `&[u8; 4]`\n found type `&'static str`\n\nIf you want more information on this error, try using \"rustc --explain E0308\"\n" } { "message": "mismatched types", @@ -147,7 +147,7 @@ "level": "error", "spans": [ { - "file_name": "./tests/fixtures/str-lit-type-mismatch.rs", + "file_name": "./tests/everything/str-lit-type-mismatch.rs", "byte_start": 608, "byte_end": 614, "line_start": 15, @@ -182,7 +182,7 @@ "level": "help", "spans": [ { - "file_name": "./tests/fixtures/str-lit-type-mismatch.rs", + "file_name": "./tests/everything/str-lit-type-mismatch.rs", "byte_start": 608, "byte_end": 614, "line_start": 15, @@ -206,7 +206,7 @@ "rendered": null } ], - "rendered": "error[E0308]: mismatched types\n --> ./tests/fixtures/str-lit-type-mismatch.rs:15:19\n |\n15 | let z: &str = b\"foo\"; //~ ERROR mismatched types\n | ^^^^^^\n | |\n | expected str, found array of 3 elements\n | help: consider removing the leading `b`: `\"foo\"`\n |\n = note: expected type `&str`\n found type `&'static [u8; 3]`\n\nIf you want more information on this error, try using \"rustc --explain E0308\"\n" + "rendered": "error[E0308]: mismatched types\n --> ./tests/everything/str-lit-type-mismatch.rs:15:19\n |\n15 | let z: &str = b\"foo\"; //~ ERROR mismatched types\n | ^^^^^^\n | |\n | expected str, found array of 3 elements\n | help: consider removing the leading `b`: `\"foo\"`\n |\n = note: expected type `&str`\n found type `&'static [u8; 3]`\n\nIf you want more information on this error, try using \"rustc --explain E0308\"\n" } { "message": "aborting due to 3 previous errors", diff --git a/tests/fixtures/str-lit-type-mismatch.rs b/tests/everything/str-lit-type-mismatch.rs similarity index 100% rename from tests/fixtures/str-lit-type-mismatch.rs rename to tests/everything/str-lit-type-mismatch.rs diff --git a/tests/parse_and_replace.rs b/tests/parse_and_replace.rs new file mode 100644 index 0000000..9d10e94 --- /dev/null +++ b/tests/parse_and_replace.rs @@ -0,0 +1,239 @@ +#![cfg(not(windows))] // TODO: should fix these tests on Windows + +extern crate duct; +extern crate env_logger; +#[macro_use] +extern crate log; +extern crate rustfix; +extern crate serde_json; +extern crate tempdir; +#[macro_use] +extern crate failure; +extern crate difference; + +use std::ffi::OsString; +use std::{env, fs}; +use std::path::{Path, PathBuf}; +use std::collections::HashSet; +use std::process::Output; + +use failure::{Error, ResultExt}; +use tempdir::TempDir; + +use rustfix::apply_suggestions; + +mod fixmode { + pub const EVERYTHING: &str = "yolo"; + pub const EDITION: &str = "edition"; +} + +mod settings { + // can be set as env var to debug + pub const CHECK_JSON: &str = "RUSTFIX_TEST_CHECK_JSON"; + pub const RECORD_JSON: &str = "RUSTFIX_TEST_RECORD_JSON"; + pub const RECORD_FIXED_RUST: &str = "RUSTFIX_TEST_RECORD_FIXED_RUST"; + + // set automatically + pub const MODE: &str = "RUSTFIX_MODE"; +} + +fn compile(file: &Path, mode: &str) -> Result<Output, Error> { + let tmp = TempDir::new("rustfix-tests")?; + + let mut args: Vec<OsString> = vec![ + file.into(), + "--error-format=pretty-json".into(), + "-Zunstable-options".into(), + "--emit=metadata".into(), + "--crate-name=rustfix_test".into(), + "-Zsuggestion-applicability".into(), + "--out-dir".into(), + tmp.path().into(), + ]; + + if mode == fixmode::EDITION { + args.push("--edition=2018".into()); + } + + let res = duct::cmd("rustc", &args) + .env("CLIPPY_DISABLE_DOCS_LINKS", "true") + .stdout_capture() + .stderr_capture() + .unchecked() + .run()?; + + Ok(res) +} + +fn compile_and_get_json_errors(file: &Path, mode: &str) -> Result<String, Error> { + let res = compile(file, mode)?; + let stderr = String::from_utf8(res.stderr)?; + + match res.status.code() { + Some(0) | Some(1) | Some(101) => Ok(stderr), + _ => Err(format_err!("failed with status {:?}: {}", res.status.code(), stderr)), + } +} + +fn compiles_without_errors(file: &Path, mode: &str) -> Result<(), Error> { + let res = compile(file, mode)?; + + match res.status.code() { + Some(0) => Ok(()), + _ => { + info!( + "file {:?} failed to compile:\n{}", + file, + String::from_utf8(res.stderr)? + ); + Err(format_err!( + "failed with status {:?} (`env RUST_LOG=parse_and_replace=info` for more info)", + res.status.code(), + )) + } + } +} + +fn read_file(path: &Path) -> Result<String, Error> { + use std::io::Read; + + let mut buffer = String::new(); + let mut file = fs::File::open(path)?; + file.read_to_string(&mut buffer)?; + Ok(buffer) +} + +fn diff(expected: &str, actual: &str) -> String { + use std::fmt::Write; + use difference::{Changeset, Difference}; + + let mut res = String::new(); + let changeset = Changeset::new(expected.trim(), actual.trim(), "\n"); + + let mut different = false; + for diff in changeset.diffs { + let (prefix, diff) = match diff { + Difference::Same(_) => continue, + Difference::Add(add) => ("+", add), + Difference::Rem(rem) => ("-", rem), + }; + if !different { + write!(&mut res, "differences found (+ == actual, - == expected):\n"); + different = true; + } + for diff in diff.lines() { + writeln!(&mut res, "{} {}", prefix, diff); + } + } + if different { + write!(&mut res, ""); + } + + res +} + +fn test_rustfix_with_file<P: AsRef<Path>>(file: P, mode: &str) -> Result<(), Error> { + let file: &Path = file.as_ref(); + let json_file = file.with_extension("json"); + let fixed_file = file.with_extension("fixed.rs"); + + debug!("next up: {:?}", file); + let code = read_file(file) + .context(format!("could not read {}", file.display()))?; + let errors = compile_and_get_json_errors(file, mode) + .context(format!("could compile {}", file.display()))?; + let suggestions = rustfix::get_suggestions_from_json(&errors, &HashSet::new()) + .context("could not load suggestions")?; + + if std::env::var(settings::RECORD_JSON).is_ok() { + use std::io::Write; + let mut recorded_json = fs::File::create(&file.with_extension("recorded.json")) + .context(format!("could not create recorded.json for {}", file.display()))?; + recorded_json.write_all(errors.as_bytes())?; + } + + if std::env::var(settings::CHECK_JSON).is_ok() { + let expected_json = read_file(&json_file) + .context(format!("could not load json fixtures for {}", file.display()))?;; + let expected_suggestions = rustfix::get_suggestions_from_json(&expected_json, &HashSet::new()) + .context("could not load expected suggesitons")?; + + ensure!( + expected_suggestions == suggestions, + "got unexpected suggestions from clippy:\n{}", + diff(&format!("{:?}", expected_suggestions), &format!("{:?}", suggestions)) + ); + } + + let fixed = apply_suggestions(&code, &suggestions) + .context(format!("could not apply suggestions to {}", file.display()))?; + + if std::env::var(settings::RECORD_FIXED_RUST).is_ok() { + use std::io::Write; + let mut recorded_rust = fs::File::create(&file.with_extension("recorded.rs"))?; + recorded_rust.write_all(fixed.as_bytes())?; + } + + let expected_fixed = read_file(&fixed_file) + .context(format!("could read fixed file for {}", file.display()))?; + ensure!( + fixed.trim() == expected_fixed.trim(), + "file {} doesn't look fixed:\n{}", file.display(), diff(fixed.trim(), expected_fixed.trim()) + ); + + compiles_without_errors(&fixed_file, mode)?; + + Ok(()) +} + +fn get_fixture_files(p: &str) -> Result<Vec<PathBuf>, Error> { + Ok(fs::read_dir(&p)? + .into_iter() + .map(|e| e.unwrap().path()) + .filter(|p| p.is_file()) + .filter(|p| { + let x = p.to_string_lossy(); + x.ends_with(".rs") && !x.ends_with(".fixed.rs") && !x.ends_with(".recorded.rs") + }) + .collect()) +} + +fn assert_fixtures(dir: &str, mode: &str) { + let files = get_fixture_files(&dir) + .context(format!("couldn't load dir `{}`", dir)) + .unwrap(); + let mut failures = 0; + + for file in &files { + if let Err(err) = test_rustfix_with_file(file, mode) { + println!("failed: {}", file.display()); + warn!("{}", err); + for cause in err.causes().skip(1) { + info!("\tcaused by: {}", cause); + } + failures += 1; + } + info!("passed: {:?}", file); + } + + if failures > 0 { + panic!( + "{} out of {} fixture asserts failed\n\ + (run with `env RUST_LOG=parse_and_replace=info` to get more details)", + failures, files.len(), + ); + } +} + +#[test] +fn everything() { + let _ = env_logger::try_init(); + assert_fixtures("./tests/everything", fixmode::EVERYTHING); +} + +#[test] +#[ignore = "Requires custom rustc build"] +fn edition() { + let _ = env_logger::try_init(); + assert_fixtures("./tests/edition", fixmode::EDITION); +}