use assert_cmd::Command;
use regex::Regex;
use std::{
collections::BTreeSet,
env::{remove_var, set_current_dir},
fs::read_to_string,
path::Path,
sync::LazyLock,
};
use walkdir::WalkDir;
#[ctor::ctor(unsafe)]
fn initialize() {
unsafe {
remove_var("CARGO_TERM_COLOR");
set_current_dir("..").unwrap();
}
}
#[test]
fn check_all_features() {
Command::new("cargo")
.args(["check", "--all-features"])
.env("RUSTFLAGS", "--deny=warnings")
.assert()
.success();
}
#[test]
fn clippy() {
Command::new("cargo")
.args(["clippy", "--all-targets", "--", "--deny=warnings"])
.assert()
.success();
}
#[cfg(unix)]
#[test]
fn disallowed_methods() {
for use_disallowed_methods_function in [false, true] {
let mut command = if use_disallowed_methods_function {
elaborate::disallowed_methods()
} else {
let mut command = std::process::Command::new("cargo");
command.args(["clippy", "--quiet"]);
command.env("CLIPPY_CONF_DIR", "../../elaborate/clippy_conf");
command.env("RUSTFLAGS", "--deny=clippy::disallowed-methods");
command
};
let output = command.current_dir("fixtures/create_dir").output().unwrap();
assert!(!output.status.success());
assert!(output.status.code().is_some());
let stderr = String::from_utf8(output.stderr).unwrap();
assert_eq!("\
error: use of a disallowed method `std::fs::create_dir`
--> src/main.rs:4:5
|
4 | create_dir(\"/dir\")?;
| ^^^^^^^^^^ help: use: `elaborate::std::fs::create_dir_wc`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods
= note: requested on the command line with `-D clippy::disallowed-methods`
error: could not compile `create_dir` (bin \"create_dir\") due to 1 previous error
", stderr);
}
}
#[test]
fn dylint() {
Command::new("cargo")
.args(["dylint", "--all", "--", "--all-targets"])
.env("DYLINT_RUSTFLAGS", "--deny warnings")
.assert()
.success();
}
#[test]
fn features_are_used() {
let contents =
read_to_string(Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml")).unwrap();
let table = contents.parse::<toml::Table>().unwrap();
let features_table = table
.get("features")
.and_then(toml::Value::as_table)
.unwrap();
let features_used = collect_features_used();
for feature in features_table.keys() {
if feature == "default" || feature.starts_with("__") {
continue;
}
assert!(features_used.contains(feature), "`{feature}` is unused");
}
}
static FEATURE_RE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r#"#\[cfg\(feature = "([^"]*)"\)\]"#).unwrap());
fn collect_features_used() -> BTreeSet<String> {
let mut features = BTreeSet::new();
#[cfg_attr(dylint_lib = "general", allow(abs_home_path))]
for result in WalkDir::new(Path::new(env!("CARGO_MANIFEST_DIR")).join("src/generated")) {
let entry = result.unwrap();
let path = entry.path();
if !path.is_file() {
continue;
}
let contents = read_to_string(path).unwrap();
for captures in FEATURE_RE.captures_iter(&contents) {
assert_eq!(2, captures.len());
features.insert(captures.get(1).unwrap().as_str().to_owned());
}
}
features
}
#[cfg(unix)]
#[test]
fn markdown_link_check() {
let tempdir = tempfile::tempdir().unwrap();
Command::new("npm")
.args(["install", "markdown-link-check@3.11"])
.current_dir(&tempdir)
.assert()
.success();
let config = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/markdown_link_check.json");
let readme_md = Path::new(env!("CARGO_MANIFEST_DIR")).join("../README.md");
Command::new("npx")
.args([
"markdown-link-check",
"--config",
&config.to_string_lossy(),
&readme_md.to_string_lossy(),
])
.current_dir(&tempdir)
.assert()
.success();
}
#[test]
fn msrv() {
Command::new("cargo")
.args(["msrv", "verify", "--manifest-path=elaborate/Cargo.toml"])
.assert()
.success();
}
#[test]
fn readme_reference_links_are_sorted() {
let re = Regex::new(r"^\[[^\]]*\]:").unwrap();
let readme = read_to_string("README.md").unwrap();
let links = readme
.lines()
.filter(|line| re.is_match(line))
.collect::<Vec<_>>();
let mut links_sorted = links.clone();
links_sorted.sort_unstable();
assert_eq!(links_sorted, links);
}
#[test]
fn readme_reference_links_are_used() {
let re = Regex::new(r"(?m)^(\[[^\]]*\]):").unwrap();
let readme = read_to_string("README.md").unwrap();
for captures in re.captures_iter(&readme) {
assert_eq!(2, captures.len());
let m = captures.get(1).unwrap();
assert!(
readme[..m.start()].contains(m.as_str()),
"{} is unused",
m.as_str()
);
}
}