Port clippy away from compiletest to ui_test

This commit is contained in:
Oli Scherer 2023-02-28 16:12:10 +00:00
parent 78e36d9f53
commit 514b6d04bb
14 changed files with 208 additions and 392 deletions

View file

@ -1,5 +1,7 @@
[alias]
uitest = "test --test compile-test"
uibless = "test --test compile-test -- -- --bless"
bless = "test -- -- --bless"
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"

View file

@ -27,27 +27,14 @@ tempfile = { version = "3.2", optional = true }
termize = "0.1"
[dev-dependencies]
compiletest_rs = { version = "0.10", features = ["tmp"] }
ui_test = "0.11.5"
tester = "0.9"
regex = "1.5"
toml = "0.7.3"
walkdir = "2.3"
# This is used by the `collect-metadata` alias.
filetime = "0.2"
# UI test dependencies
clap = { version = "4.1.4", features = ["derive"] }
clippy_utils = { path = "clippy_utils" }
derive-new = "0.5"
if_chain = "1.0"
itertools = "0.10.1"
quote = "1.0"
serde = { version = "1.0.125", features = ["derive"] }
syn = { version = "2.0", features = ["full"] }
futures = "0.3"
parking_lot = "0.12"
tokio = { version = "1", features = ["io-util"] }
rustc-semver = "1.1"
[build-dependencies]
rustc_tools_util = "0.3.0"
@ -60,3 +47,7 @@ internal = ["clippy_lints/internal", "tempfile"]
[package.metadata.rust-analyzer]
# This package uses #[feature(rustc_private)]
rustc_private = true
[[test]]
name = "compile-test"
harness = false

View file

@ -122,20 +122,17 @@ fn main() {
}
```
Now we can run the test with `TESTNAME=foo_functions cargo uitest`, currently
Now we can run the test with `TESTNAME=foo_functions cargo uibless`, currently
this test is meaningless though.
While we are working on implementing our lint, we can keep running the UI test.
That allows us to check if the output is turning into what we want.
That allows us to check if the output is turning into what we want by checking the
`.stderr` file that gets updated on every test run.
Once we are satisfied with the output, we need to run `cargo dev bless` to
update the `.stderr` file for our lint. Please note that, we should run
`TESTNAME=foo_functions cargo uitest` every time before running `cargo dev
bless`. Running `TESTNAME=foo_functions cargo uitest` should pass then. When we
Running `TESTNAME=foo_functions cargo uitest` should pass on its own. When we
commit our lint, we need to commit the generated `.stderr` files, too. In
general, you should only commit files changed by `cargo dev bless` for the
specific lint you are creating/editing. Note that if the generated files are
empty, they should be removed.
general, you should only commit files changed by `cargo bless` for the
specific lint you are creating/editing.
> _Note:_ you can run multiple test files by specifying a comma separated list:
> `TESTNAME=foo_functions,test2,test3`.
@ -169,7 +166,7 @@ additionally run [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.
Use `cargo dev bless` to automatically generate the `.fixed` file after running
Use `cargo bless` to automatically generate the `.fixed` file while running
the tests.
[rustfix]: https://github.com/rust-lang/rustfix

View file

@ -66,7 +66,7 @@ If the output of a [UI test] differs from the expected output, you can update
the reference file with:
```bash
cargo dev bless
cargo bless
```
For example, this is necessary if you fix a typo in an error message of a lint,

View file

@ -1,60 +0,0 @@
//! `bless` updates the reference files in the repo with changed output files
//! from the last test run.
use crate::cargo_clippy_path;
use std::ffi::OsStr;
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::LazyLock;
use walkdir::{DirEntry, WalkDir};
static CLIPPY_BUILD_TIME: LazyLock<Option<std::time::SystemTime>> =
LazyLock::new(|| cargo_clippy_path().metadata().ok()?.modified().ok());
/// # Panics
///
/// Panics if the path to a test file is broken
pub fn bless(ignore_timestamp: bool) {
let extensions = ["stdout", "stderr", "fixed"].map(OsStr::new);
WalkDir::new(build_dir())
.into_iter()
.map(Result::unwrap)
.filter(|entry| entry.path().extension().map_or(false, |ext| extensions.contains(&ext)))
.for_each(|entry| update_reference_file(&entry, ignore_timestamp));
}
fn update_reference_file(test_output_entry: &DirEntry, ignore_timestamp: bool) {
let test_output_path = test_output_entry.path();
let reference_file_name = test_output_entry.file_name().to_str().unwrap().replace(".stage-id", "");
let reference_file_path = Path::new("tests")
.join(test_output_path.strip_prefix(build_dir()).unwrap())
.with_file_name(reference_file_name);
// If the test output was not updated since the last clippy build, it may be outdated
if !ignore_timestamp && !updated_since_clippy_build(test_output_entry).unwrap_or(true) {
return;
}
let test_output_file = fs::read(test_output_path).expect("Unable to read test output file");
let reference_file = fs::read(&reference_file_path).unwrap_or_default();
if test_output_file != reference_file {
// If a test run caused an output file to change, update the reference file
println!("updating {}", reference_file_path.display());
fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");
}
}
fn updated_since_clippy_build(entry: &DirEntry) -> Option<bool> {
let clippy_build_time = (*CLIPPY_BUILD_TIME)?;
let modified = entry.metadata().ok()?.modified().ok()?;
Some(modified >= clippy_build_time)
}
fn build_dir() -> PathBuf {
let mut path = std::env::current_exe().unwrap();
path.set_file_name("test");
path
}

View file

@ -14,7 +14,6 @@ use std::io;
use std::path::PathBuf;
use std::process::{self, ExitStatus};
pub mod bless;
pub mod dogfood;
pub mod fmt;
pub mod lint;

View file

@ -3,7 +3,7 @@
#![warn(rust_2018_idioms, unused_lifetimes)]
use clap::{Arg, ArgAction, ArgMatches, Command};
use clippy_dev::{bless, dogfood, fmt, lint, new_lint, serve, setup, update_lints};
use clippy_dev::{dogfood, fmt, lint, new_lint, serve, setup, update_lints};
use indoc::indoc;
use std::convert::Infallible;
@ -11,8 +11,8 @@ fn main() {
let matches = get_clap_config();
match matches.subcommand() {
Some(("bless", matches)) => {
bless::bless(matches.get_flag("ignore-timestamp"));
Some(("bless", _)) => {
eprintln!("use `cargo bless` to automatically replace `.stderr` and `.fixed` files as tests are being run");
},
Some(("dogfood", matches)) => {
dogfood::dogfood(

View file

@ -96,7 +96,7 @@ fn create_test(lint: &LintData<'_>) -> io::Result<()> {
path.push("src");
fs::create_dir(&path)?;
let header = format!("// compile-flags: --crate-name={lint_name}");
let header = format!("//@compile-flags: --crate-name={lint_name}");
write_file(path.join("main.rs"), get_test_file_contents(lint_name, Some(&header)))?;
Ok(())

View file

@ -0,0 +1,25 @@
[package]
name = "clippy_test_deps"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.1.4", features = ["derive"] }
clippy_utils = { path = "../clippy_utils" }
derive-new = "0.5"
if_chain = "1.0"
itertools = "0.10.1"
quote = "1.0"
serde = { version = "1.0.125", features = ["derive"] }
syn = { version = "2.0", features = ["full"] }
futures = "0.3"
parking_lot = "0.12"
tokio = { version = "1", features = ["io-util"] }
rustc-semver = "1.1"
regex = "1.5"
clippy_lints = { path = "../clippy_lints" }
[features]
internal = ["clippy_lints/internal"]

View file

@ -0,0 +1,14 @@
pub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}

View file

@ -2397,7 +2397,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalDefId, f: impl Fn(&[Symbol
/// Checks if the function containing the given `HirId` is a `#[test]` function
///
/// Note: Add `// compile-flags: --test` to UI tests with a `#[test]` function
/// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function
pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
with_test_item_names(tcx, tcx.parent_module(id), |names| {
tcx.hir()
@ -2419,7 +2419,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
/// Checks if the item containing the given `HirId` has `#[cfg(test)]` attribute applied
///
/// Note: Add `// compile-flags: --test` to UI tests with a `#[cfg(test)]` function
/// Note: Add `//@compile-flags: --test` to UI tests with a `#[cfg(test)]` function
pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
fn is_cfg_test(attr: &Attribute) -> bool {
if attr.has_name(sym::cfg)
@ -2441,7 +2441,7 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
/// Checks whether item either has `test` attribute applied, or
/// is a module with `test` in its name.
///
/// Note: Add `// compile-flags: --test` to UI tests with a `#[test]` function
/// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function
pub fn is_test_module_or_function(tcx: TyCtxt<'_>, item: &Item<'_>) -> bool {
is_in_test_function(tcx, item.hir_id())
|| matches!(item.kind, ItemKind::Mod(..))

View file

@ -4,16 +4,14 @@
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![warn(rust_2018_idioms, unused_lifetimes)]
use compiletest_rs as compiletest;
use compiletest_rs::common::Mode as TestMode;
use compiletest::{status_emitter, CommandBuilder};
use ui_test as compiletest;
use ui_test::Mode as TestMode;
use std::collections::HashMap;
use std::env::{self, remove_var, set_var, var_os};
use std::ffi::{OsStr, OsString};
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use std::sync::LazyLock;
use test_utils::IS_RUSTC_TEST_SUITE;
mod test_utils;
@ -21,143 +19,41 @@ mod test_utils;
// whether to run internal tests or not
const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");
/// All crates used in UI tests are listed here
static TEST_DEPENDENCIES: &[&str] = &[
"clippy_lints",
"clippy_utils",
"derive_new",
"futures",
"if_chain",
"itertools",
"quote",
"regex",
"serde",
"serde_derive",
"syn",
"tokio",
"parking_lot",
"rustc_semver",
];
// Test dependencies may need an `extern crate` here to ensure that they show up
// in the depinfo file (otherwise cargo thinks they are unused)
#[allow(unused_extern_crates)]
extern crate clippy_lints;
#[allow(unused_extern_crates)]
extern crate clippy_utils;
#[allow(unused_extern_crates)]
extern crate derive_new;
#[allow(unused_extern_crates)]
extern crate futures;
#[allow(unused_extern_crates)]
extern crate if_chain;
#[allow(unused_extern_crates)]
extern crate itertools;
#[allow(unused_extern_crates)]
extern crate parking_lot;
#[allow(unused_extern_crates)]
extern crate quote;
#[allow(unused_extern_crates)]
extern crate rustc_semver;
#[allow(unused_extern_crates)]
extern crate syn;
#[allow(unused_extern_crates)]
extern crate tokio;
/// Produces a string with an `--extern` flag for all UI test crate
/// dependencies.
///
/// The dependency files are located by parsing the depinfo file for this test
/// module. This assumes the `-Z binary-dep-depinfo` flag is enabled. All test
/// dependencies must be added to Cargo.toml at the project root. Test
/// dependencies that are not *directly* used by this test module require an
/// `extern crate` declaration.
static EXTERN_FLAGS: LazyLock<String> = LazyLock::new(|| {
let current_exe_depinfo = {
let mut path = env::current_exe().unwrap();
path.set_extension("d");
fs::read_to_string(path).unwrap()
};
let mut crates: HashMap<&str, &str> = HashMap::with_capacity(TEST_DEPENDENCIES.len());
for line in current_exe_depinfo.lines() {
// each dependency is expected to have a Makefile rule like `/path/to/crate-hash.rlib:`
let parse_name_path = || {
if line.starts_with(char::is_whitespace) {
return None;
}
let path_str = line.strip_suffix(':')?;
let path = Path::new(path_str);
if !matches!(path.extension()?.to_str()?, "rlib" | "so" | "dylib" | "dll") {
return None;
}
let (name, _hash) = path.file_stem()?.to_str()?.rsplit_once('-')?;
// the "lib" prefix is not present for dll files
let name = name.strip_prefix("lib").unwrap_or(name);
Some((name, path_str))
};
if let Some((name, path)) = parse_name_path() {
if TEST_DEPENDENCIES.contains(&name) {
// A dependency may be listed twice if it is available in sysroot,
// and the sysroot dependencies are listed first. As of the writing,
// this only seems to apply to if_chain.
crates.insert(name, path);
}
}
}
let not_found: Vec<&str> = TEST_DEPENDENCIES
.iter()
.copied()
.filter(|n| !crates.contains_key(n))
.collect();
assert!(
not_found.is_empty(),
"dependencies not found in depinfo: {not_found:?}\n\
help: Make sure the `-Z binary-dep-depinfo` rust flag is enabled\n\
help: Try adding to dev-dependencies in Cargo.toml\n\
help: Be sure to also add `extern crate ...;` to tests/compile-test.rs",
);
crates
.into_iter()
.map(|(name, path)| format!(" --extern {name}={path}"))
.collect()
});
fn base_config(test_dir: &str) -> compiletest::Config {
let mut config = compiletest::Config {
edition: Some("2021".into()),
mode: TestMode::Ui,
strict_headers: true,
..Default::default()
mode: TestMode::Yolo,
stderr_filters: vec![],
stdout_filters: vec![],
output_conflict_handling: if std::env::args().any(|arg| arg == "--bless") {
compiletest::OutputConflictHandling::Bless
} else {
compiletest::OutputConflictHandling::Error("cargo test -- -- --bless".into())
},
dependencies_crate_manifest_path: Some("clippy_test_deps/Cargo.toml".into()),
target: None,
out_dir: "target/ui_test".into(),
..compiletest::Config::rustc(Path::new("tests").join(test_dir))
};
if let Ok(filters) = env::var("TESTNAME") {
config.filters = filters.split(',').map(ToString::to_string).collect();
}
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;
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();
// Using `-L dependency={}` enforces that external dependencies are added with `--extern`.
// This is valuable because a) it allows us to monitor what external dependencies are used
// and b) it ensures that conflicting rlibs are resolved properly.
let host_libs = option_env!("HOST_LIBS")
.map(|p| format!(" -L dependency={}", Path::new(p).join("deps").display()))
.unwrap_or_default();
config.target_rustcflags = Some(format!(
"--emit=metadata -Dwarnings -Zui-testing -L dependency={}{host_libs}{}",
deps_path.display(),
&*EXTERN_FLAGS,
));
config.program.args.push("--emit=metadata".into());
config.program.args.push("-Aunused".into());
config.program.args.push("-Zui-testing".into());
config.program.args.push("-Dwarnings".into());
config.src_base = Path::new("tests").join(test_dir);
config.build_base = profile_path.join("test").join(test_dir);
config.rustc_path = profile_path.join(if cfg!(windows) {
// Normalize away slashes in windows paths.
config.stderr_filter(r#"\\"#, "/");
//config.build_base = profile_path.join("test").join(test_dir);
config.program.program = profile_path.join(if cfg!(windows) {
"clippy-driver.exe"
} else {
"clippy-driver"
@ -165,9 +61,23 @@ fn base_config(test_dir: &str) -> compiletest::Config {
config
}
fn test_filter() -> Box<dyn Sync + Fn(&Path) -> bool> {
if let Ok(filters) = env::var("TESTNAME") {
let filters: Vec<_> = filters.split(',').map(ToString::to_string).collect();
Box::new(move |path| {
filters.is_empty()
|| filters
.iter()
.any(|f| path.file_stem().map_or(false, |stem| stem == f.as_str()))
})
} else {
Box::new(|_| true)
}
}
fn run_ui() {
let mut config = base_config("ui");
config.rustfix_coverage = true;
let config = base_config("ui");
//config.rustfix_coverage = true;
// use tests/clippy.toml
let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
let _threads = VarGuard::set(
@ -179,7 +89,19 @@ fn run_ui() {
.to_string()
}),
);
compiletest::run_tests(&config);
eprintln!(" Compiler: {}", config.program.display());
let name = config.root_dir.display().to_string();
let test_filter = test_filter();
compiletest::run_tests_generic(
config,
move |path| compiletest::default_file_filter(path) && test_filter(path),
compiletest::default_per_file_config,
(status_emitter::Text, status_emitter::Gha::<true> { name }),
)
.unwrap();
check_rustfix_coverage();
}
@ -188,177 +110,114 @@ fn run_internal_tests() {
if !RUN_INTERNAL_TESTS {
return;
}
let config = base_config("ui-internal");
compiletest::run_tests(&config);
let mut config = base_config("ui-internal");
config.dependency_builder.args.push("--features".into());
config.dependency_builder.args.push("internal".into());
compiletest::run_tests(config).unwrap();
}
fn run_ui_toml() {
fn run_tests(config: &compiletest::Config, mut tests: Vec<tester::TestDescAndFn>) -> Result<bool, io::Error> {
let mut result = true;
let opts = compiletest::test_opts(config);
for dir in fs::read_dir(&config.src_base)? {
let dir = dir?;
if !dir.file_type()?.is_dir() {
continue;
}
let dir_path = dir.path();
let _g = VarGuard::set("CARGO_MANIFEST_DIR", &dir_path);
for file in fs::read_dir(&dir_path)? {
let file = file?;
let file_path = file.path();
if file.file_type()?.is_dir() {
continue;
}
if file_path.extension() != Some(OsStr::new("rs")) {
continue;
}
let paths = compiletest::common::TestPaths {
file: file_path,
base: config.src_base.clone(),
relative_dir: dir_path.file_name().unwrap().into(),
};
let test_name = compiletest::make_test_name(config, &paths);
let index = tests
.iter()
.position(|test| test.desc.name == test_name)
.expect("The test should be in there");
result &= tester::run_tests_console(&opts, vec![tests.swap_remove(index)])?;
}
}
Ok(result)
}
let mut config = base_config("ui-toml");
config.src_base = config.src_base.canonicalize().unwrap();
let tests = compiletest::make_tests(&config);
config.stderr_filter(
&regex::escape(
&std::path::Path::new(file!())
.parent()
.unwrap()
.canonicalize()
.unwrap()
.parent()
.unwrap()
.display()
.to_string()
.replace('\\', "/"),
),
"$$DIR",
);
let res = run_tests(&config, tests);
match res {
Ok(true) => {},
Ok(false) => panic!("Some tests failed"),
Err(e) => {
panic!("I/O failure during tests: {e:?}");
let name = config.root_dir.display().to_string();
let test_filter = test_filter();
ui_test::run_tests_generic(
config,
|path| test_filter(path) && path.extension() == Some("rs".as_ref()),
|config, path| {
let mut config = config.clone();
config
.program
.envs
.push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into())));
Some(config)
},
}
(status_emitter::Text, status_emitter::Gha::<true> { name }),
)
.unwrap();
}
fn run_ui_cargo() {
fn run_tests(
config: &compiletest::Config,
filters: &[String],
mut tests: Vec<tester::TestDescAndFn>,
) -> Result<bool, io::Error> {
let mut result = true;
let opts = compiletest::test_opts(config);
for dir in fs::read_dir(&config.src_base)? {
let dir = dir?;
if !dir.file_type()?.is_dir() {
continue;
}
// Use the filter if provided
let dir_path = dir.path();
for filter in filters {
if !dir_path.ends_with(filter) {
continue;
}
}
for case in fs::read_dir(&dir_path)? {
let case = case?;
if !case.file_type()?.is_dir() {
continue;
}
let src_path = case.path().join("src");
// When switching between branches, if the previous branch had a test
// that the current branch does not have, the directory is not removed
// because an ignored Cargo.lock file exists.
if !src_path.exists() {
continue;
}
env::set_current_dir(&src_path)?;
let cargo_toml_path = case.path().join("Cargo.toml");
let cargo_content = fs::read(cargo_toml_path)?;
let cargo_parsed: toml::Value = toml::from_str(
std::str::from_utf8(&cargo_content).expect("`Cargo.toml` is not a valid utf-8 file!"),
)
.expect("Can't parse `Cargo.toml`");
let _g = VarGuard::set("CARGO_MANIFEST_DIR", case.path());
let _h = VarGuard::set(
"CARGO_PKG_RUST_VERSION",
cargo_parsed
.get("package")
.and_then(|p| p.get("rust-version"))
.and_then(toml::Value::as_str)
.unwrap_or(""),
);
for file in fs::read_dir(&src_path)? {
let file = file?;
if file.file_type()?.is_dir() {
continue;
}
// Search for the main file to avoid running a test for each file in the project
let file_path = file.path();
match file_path.file_name().and_then(OsStr::to_str) {
Some("main.rs") => {},
_ => continue,
}
let _g = VarGuard::set("CLIPPY_CONF_DIR", case.path());
let paths = compiletest::common::TestPaths {
file: file_path,
base: config.src_base.clone(),
relative_dir: src_path.strip_prefix(&config.src_base).unwrap().into(),
};
let test_name = compiletest::make_test_name(config, &paths);
let index = tests
.iter()
.position(|test| test.desc.name == test_name)
.expect("The test should be in there");
result &= tester::run_tests_console(&opts, vec![tests.swap_remove(index)])?;
}
}
}
Ok(result)
}
if IS_RUSTC_TEST_SUITE {
return;
}
let mut config = base_config("ui-cargo");
config.src_base = config.src_base.canonicalize().unwrap();
config.program = CommandBuilder::cargo();
config.program.args = vec!["clippy".into(), "--color".into(), "never".into(), "--quiet".into()];
config
.program
.envs
.push(("RUSTFLAGS".into(), Some("-Dwarnings".into())));
// We need to do this while we still have a rustc in the `program` field.
config.fill_host_and_target().unwrap();
config.dependencies_crate_manifest_path = None;
config.program.program.set_file_name(if cfg!(windows) {
"cargo-clippy.exe"
} else {
"cargo-clippy"
});
config.edition = None;
let tests = compiletest::make_tests(&config);
config.stderr_filter(
&regex::escape(
&std::path::Path::new(file!())
.parent()
.unwrap()
.canonicalize()
.unwrap()
.parent()
.unwrap()
.display()
.to_string()
.replace('\\', "/"),
),
"$$DIR",
);
let current_dir = env::current_dir().unwrap();
let res = run_tests(&config, &config.filters, tests);
env::set_current_dir(current_dir).unwrap();
let name = config.root_dir.display().to_string();
match res {
Ok(true) => {},
Ok(false) => panic!("Some tests failed"),
Err(e) => {
panic!("I/O failure during tests: {e:?}");
let test_filter = test_filter();
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)
},
}
(status_emitter::Text, status_emitter::Gha::<true> { name }),
)
.unwrap();
}
#[test]
fn compile_test() {
fn main() {
set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
run_ui();
run_ui_toml();
run_ui_cargo();
run_internal_tests();
rustfix_coverage_known_exceptions_accuracy();
ui_cargo_toml_metadata();
}
const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
@ -384,7 +243,6 @@ const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
"needless_for_each_unfixable.rs",
"nonminimal_bool.rs",
"print_literal.rs",
"print_with_newline.rs",
"redundant_static_lifetimes_multiple.rs",
"ref_binding_to_reference.rs",
"repl_uninit.rs",
@ -399,7 +257,6 @@ const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
"unnecessary_lazy_eval_unfixable.rs",
"write_literal.rs",
"write_literal_2.rs",
"write_with_newline.rs",
];
fn check_rustfix_coverage() {
@ -432,25 +289,16 @@ fn check_rustfix_coverage() {
}
}
#[test]
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.strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap().display()
);
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.strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap().display()
);
println!("{}", fixed_path.display());
assert!(!fixed_path.exists(), "`{}` exists", fixed_path.display());
}
}
#[test]
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");

View file

@ -41,8 +41,8 @@ fn explore_directory(dir: &Path) -> Vec<String> {
x.path().extension().and_then(OsStr::to_str),
y.path().extension().and_then(OsStr::to_str),
) {
(Some("rs"), _) => Ordering::Less,
(_, Some("rs")) => Ordering::Greater,
(Some("rs" | "toml"), _) => Ordering::Less,
(_, Some("rs" | "toml")) => Ordering::Greater,
_ => Ordering::Equal,
}
});
@ -54,7 +54,7 @@ fn explore_directory(dir: &Path) -> Vec<String> {
let file_prefix = path.file_prefix().unwrap().to_str().unwrap().to_string();
if let Some(ext) = path.extension() {
match ext.to_str().unwrap() {
"rs" => current_file = file_prefix.clone(),
"rs" | "toml" => current_file = file_prefix.clone(),
"stderr" | "stdout" => {
if file_prefix != current_file {
missing_files.push(path.to_str().unwrap().to_string());

View file

@ -47,9 +47,9 @@
"group": "test"
},
{
"label": "cargo dev bless",
"label": "bless ui tests",
"type": "shell",
"command": "cargo dev bless",
"command": "cargo bless",
"problemMatcher": [],
"group": "none"
}