Skip to content

Commit

Permalink
Auto merge of #11239 - oli-obk:ui_test, r=Alexendoo,flip1995
Browse files Browse the repository at this point in the history
Update ui test crate

This update also removes the `//`@run-rustfix`` flag, and just runs rustfix on all tests. This means I had to opt out of running rustfix on ~100 tests, but it also allowed me to remove the rustfix coverage check entirely, as it is now effectively builtin.

changelog: update ui-test crate to 0.13 (automatically runs rustfix on all tests)
  • Loading branch information
bors committed Aug 11, 2023
2 parents 1e8fdf4 + 665a619 commit 739faf3
Show file tree
Hide file tree
Showing 1,264 changed files with 7,082 additions and 6,140 deletions.
6 changes: 3 additions & 3 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[alias]
uitest = "test --test compile-test"
uibless = "test --test compile-test -- -- --bless"
bless = "test -- -- --bless"
uitest = "test --test compile-test -- --check"
uibless = "test --test compile-test"
bless = "test"
dev = "run --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --"
lintcheck = "run --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml -- "
collect-metadata = "test --test dogfood --features internal -- run_metadata_collection_lint --ignored"
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ tempfile = { version = "3.2", optional = true }
termize = "0.1"

[dev-dependencies]
ui_test = "0.11.5"
ui_test = "0.17.0"
tester = "0.9"
regex = "1.5"
toml = "0.7.3"
Expand Down
4 changes: 2 additions & 2 deletions book/src/development/adding_lints.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ The process of generating the `.stderr` file is the same, and prepending the
## Rustfix tests

If the lint you are working on is making use of structured suggestions, the test
file should include a `//@run-rustfix` comment at the top. This will
additionally run [rustfix] for that test. Rustfix will apply the suggestions
will create a `.fixed` file by running [rustfix] for that test.
Rustfix will apply the suggestions
from the lint to the code of the test file and compare that to the contents of a
`.fixed` file.

Expand Down
1 change: 0 additions & 1 deletion clippy_dev/src/update_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,6 @@ fn gen_deprecated_lints_test(lints: &[DeprecatedLint]) -> String {
fn gen_renamed_lints_test(lints: &[RenamedLint]) -> String {
let mut seen_lints = HashSet::new();
let mut res: String = GENERATED_FILE_COMMENT.into();
res.push_str("//@run-rustfix\n\n");
for lint in lints {
if seen_lints.insert(&lint.new_name) {
writeln!(res, "#![allow({})]", lint.new_name).unwrap();
Expand Down
195 changes: 72 additions & 123 deletions tests/compile-test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#![warn(rust_2018_idioms, unused_lifetimes)]
#![allow(unused_extern_crates)]

use compiletest::{status_emitter, CommandBuilder, OutputConflictHandling};
use compiletest::{status_emitter, Args, CommandBuilder, OutputConflictHandling};
use ui_test as compiletest;
use ui_test::Mode as TestMode;

Expand Down Expand Up @@ -110,28 +110,33 @@ mod test_utils;
// whether to run internal tests or not
const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");

fn base_config(test_dir: &str) -> compiletest::Config {
fn canonicalize(path: impl AsRef<Path>) -> PathBuf {
let path = path.as_ref();
fs::create_dir_all(path).unwrap();
fs::canonicalize(path).unwrap_or_else(|err| panic!("{} cannot be canonicalized: {err}", path.display()))
}

fn base_config(test_dir: &str) -> (compiletest::Config, Args) {
let args = Args::test().unwrap();
let mut config = compiletest::Config {
mode: TestMode::Yolo,
mode: TestMode::Yolo { rustfix: true },
stderr_filters: vec![],
stdout_filters: vec![],
output_conflict_handling: if var_os("RUSTC_BLESS").is_some_and(|v| v != "0")
|| env::args().any(|arg| arg == "--bless")
output_conflict_handling: if var_os("GITHUB_ACTION").is_none()
&& (var_os("RUSTC_BLESS").is_some_and(|v| v != "0") || !args.check)
{
OutputConflictHandling::Bless
} else {
OutputConflictHandling::Error("cargo uibless".into())
},
target: None,
out_dir: PathBuf::from(std::env::var_os("CARGO_TARGET_DIR").unwrap_or("target".into())).join("ui_test"),
out_dir: canonicalize(
std::env::var_os("CARGO_TARGET_DIR")
.map_or_else(|| std::env::current_dir().unwrap().join("target"), PathBuf::from),
)
.join("ui_test"),
..compiletest::Config::rustc(Path::new("tests").join(test_dir))
};

if let Some(_path) = option_env!("RUSTC_LIB_PATH") {
//let path = PathBuf::from(path);
//config.run_lib_path = path.clone();
//config.compile_lib_path = path;
}
let current_exe_path = env::current_exe().unwrap();
let deps_path = current_exe_path.parent().unwrap();
let profile_path = deps_path.parent().unwrap();
Expand Down Expand Up @@ -164,7 +169,7 @@ fn base_config(test_dir: &str) -> compiletest::Config {
} else {
"clippy-driver"
});
config
(config, args)
}

fn test_filter() -> Box<dyn Sync + Fn(&Path) -> bool> {
Expand All @@ -177,10 +182,10 @@ fn test_filter() -> Box<dyn Sync + Fn(&Path) -> bool> {
}

fn run_ui() {
let config = base_config("ui");
let (config, args) = base_config("ui");
//config.rustfix_coverage = true;
// use tests/clippy.toml
let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
let _g = VarGuard::set("CARGO_MANIFEST_DIR", canonicalize("tests"));
let _threads = VarGuard::set(
"RUST_TEST_THREADS",
// if RUST_TEST_THREADS is set, adhere to it, otherwise override it
Expand All @@ -193,43 +198,54 @@ fn run_ui() {

let test_filter = test_filter();

let quiet = args.quiet;

compiletest::run_tests_generic(
config,
move |path| compiletest::default_file_filter(path) && test_filter(path),
vec![config],
args,
move |path, args, config| compiletest::default_file_filter(path, args, config) && test_filter(path),
compiletest::default_per_file_config,
status_emitter::Text,
if quiet {
status_emitter::Text::quiet()
} else {
status_emitter::Text::verbose()
},
)
.unwrap();
check_rustfix_coverage();
}

fn run_internal_tests() {
// only run internal tests with the internal-tests feature
if !RUN_INTERNAL_TESTS {
return;
}
let mut config = base_config("ui-internal");
let (mut config, args) = base_config("ui-internal");
if let OutputConflictHandling::Error(err) = &mut config.output_conflict_handling {
*err = "cargo uitest --features internal -- -- --bless".into();
*err = "cargo uitest --features internal".into();
}
let test_filter = test_filter();
let quiet = args.quiet;

compiletest::run_tests_generic(
config,
move |path| compiletest::default_file_filter(path) && test_filter(path),
vec![config],
args,
move |path, args, config| compiletest::default_file_filter(path, args, config) && test_filter(path),
compiletest::default_per_file_config,
status_emitter::Text,
if quiet {
status_emitter::Text::quiet()
} else {
status_emitter::Text::verbose()
},
)
.unwrap();
}

fn run_ui_toml() {
let mut config = base_config("ui-toml");
let (mut config, args) = base_config("ui-toml");

config.stderr_filter(
&regex::escape(
&fs::canonicalize("tests")
.unwrap()
&canonicalize("tests")
.parent()
.unwrap()
.display()
Expand All @@ -240,19 +256,23 @@ fn run_ui_toml() {
);

let test_filter = test_filter();
let quiet = args.quiet;

ui_test::run_tests_generic(
config,
|path| compiletest::default_file_filter(path) && test_filter(path),
|config, path| {
let mut config = config.clone();
vec![config],
args,
|path, args, config| compiletest::default_file_filter(path, args, config) && test_filter(path),
|config, path, _file_contents| {
config
.program
.envs
.push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into())));
Some(config)
},
status_emitter::Text,
if quiet {
status_emitter::Text::quiet()
} else {
status_emitter::Text::verbose()
},
)
.unwrap();
}
Expand All @@ -262,7 +282,7 @@ fn run_ui_cargo() {
return;
}

let mut config = base_config("ui-cargo");
let (mut config, args) = base_config("ui-cargo");
config.program.input_file_flag = CommandBuilder::cargo().input_file_flag;
config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag;
config.program.args = vec!["clippy".into(), "--color".into(), "never".into(), "--quiet".into()];
Expand All @@ -282,8 +302,7 @@ fn run_ui_cargo() {

config.stderr_filter(
&regex::escape(
&fs::canonicalize("tests")
.unwrap()
&canonicalize("tests")
.parent()
.unwrap()
.display()
Expand All @@ -294,16 +313,26 @@ fn run_ui_cargo() {
);

let test_filter = test_filter();
let quiet = args.quiet;

ui_test::run_tests_generic(
config,
|path| test_filter(path) && path.ends_with("Cargo.toml"),
|config, path| {
let mut config = config.clone();
config.out_dir = PathBuf::from("target/ui_test_cargo/").join(path.parent().unwrap());
Some(config)
vec![config],
args,
|path, _args, _config| test_filter(path) && path.ends_with("Cargo.toml"),
|config, path, _file_contents| {
config.out_dir = canonicalize(
std::env::current_dir()
.unwrap()
.join("target")
.join("ui_test_cargo/")
.join(path.parent().unwrap()),
);
},
if quiet {
status_emitter::Text::quiet()
} else {
status_emitter::Text::verbose()
},
status_emitter::Text,
)
.unwrap();
}
Expand All @@ -328,7 +357,6 @@ fn main() {
"cargo" => run_ui_cargo as fn(),
"toml" => run_ui_toml as fn(),
"internal" => run_internal_tests as fn(),
"rustfix-coverage-known-exceptions-accuracy" => rustfix_coverage_known_exceptions_accuracy as fn(),
"ui-cargo-toml-metadata" => ui_cargo_toml_metadata as fn(),

_ => panic!("unknown speedtest: {speedtest} || accepted speedtests are: [ui, cargo, toml, internal]"),
Expand All @@ -355,89 +383,10 @@ fn main() {
run_ui_toml();
run_ui_cargo();
run_internal_tests();
rustfix_coverage_known_exceptions_accuracy();
ui_cargo_toml_metadata();
}
}

const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
"assign_ops2.rs",
"borrow_deref_ref_unfixable.rs",
"cast_size_32bit.rs",
"char_lit_as_u8.rs",
"cmp_owned/without_suggestion.rs",
"dbg_macro.rs",
"deref_addrof_double_trigger.rs",
"doc/unbalanced_ticks.rs",
"eprint_with_newline.rs",
"explicit_counter_loop.rs",
"iter_skip_next_unfixable.rs",
"let_and_return.rs",
"literals.rs",
"map_flatten.rs",
"map_unwrap_or.rs",
"match_bool.rs",
"mem_replace_macro.rs",
"needless_arbitrary_self_type_unfixable.rs",
"needless_borrow_pat.rs",
"needless_for_each_unfixable.rs",
"nonminimal_bool.rs",
"print_literal.rs",
"redundant_static_lifetimes_multiple.rs",
"ref_binding_to_reference.rs",
"repl_uninit.rs",
"result_map_unit_fn_unfixable.rs",
"search_is_some.rs",
"single_component_path_imports_nested_first.rs",
"string_add.rs",
"suspicious_to_owned.rs",
"toplevel_ref_arg_non_rustfix.rs",
"unit_arg.rs",
"unnecessary_clone.rs",
"unnecessary_lazy_eval_unfixable.rs",
"write_literal.rs",
"write_literal_2.rs",
];

fn check_rustfix_coverage() {
let missing_coverage_path = Path::new("debug/test/ui/rustfix_missing_coverage.txt");
let missing_coverage_path = if let Ok(target_dir) = std::env::var("CARGO_TARGET_DIR") {
PathBuf::from(target_dir).join(missing_coverage_path)
} else {
missing_coverage_path.to_path_buf()
};

if let Ok(missing_coverage_contents) = std::fs::read_to_string(missing_coverage_path) {
assert!(RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS.iter().is_sorted_by_key(Path::new));

for rs_file in missing_coverage_contents.lines() {
let rs_path = Path::new(rs_file);
if rs_path.starts_with("tests/ui/crashes") {
continue;
}
assert!(rs_path.starts_with("tests/ui/"), "{rs_file:?}");
let filename = rs_path.strip_prefix("tests/ui/").unwrap();
assert!(
RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS
.binary_search_by_key(&filename, Path::new)
.is_ok(),
"`{rs_file}` runs `MachineApplicable` diagnostics but is missing a `run-rustfix` annotation. \
Please either add `//@run-rustfix` at the top of the file or add the file to \
`RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS` in `tests/compile-test.rs`.",
);
}
}
}

fn rustfix_coverage_known_exceptions_accuracy() {
for filename in RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS {
let rs_path = Path::new("tests/ui").join(filename);
assert!(rs_path.exists(), "`{}` does not exist", rs_path.display());
let fixed_path = rs_path.with_extension("fixed");
assert!(!fixed_path.exists(), "`{}` exists", fixed_path.display());
}
}

fn ui_cargo_toml_metadata() {
let ui_cargo_path = Path::new("tests/ui-cargo");
let cargo_common_metadata_path = ui_cargo_path.join("cargo_common_metadata");
Expand Down
2 changes: 1 addition & 1 deletion tests/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn old_test_headers() {
continue;
}

let file = fs::read_to_string(entry.path()).unwrap();
let file = fs::read_to_string(entry.path()).unwrap_or_else(|err| panic!("{}: {err}", entry.path().display()));

if let Some(header) = old_headers.find(&file) {
println!("Found header `{}` in {}", header.as_str(), entry.path().display());
Expand Down
1 change: 0 additions & 1 deletion tests/ui-internal/collapsible_span_lint_calls.fixed
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
#![feature(rustc_private)]
Expand Down
1 change: 0 additions & 1 deletion tests/ui-internal/collapsible_span_lint_calls.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//@run-rustfix
#![deny(clippy::internal)]
#![allow(clippy::missing_clippy_version_attribute)]
#![feature(rustc_private)]
Expand Down
Loading

0 comments on commit 739faf3

Please sign in to comment.