use super::*;
use std::path::PathBuf;
use tempfile::TempDir;
fn config_for(path: PathBuf, format: TdgOutputFormat) -> TdgCommandConfig {
TdgCommandConfig {
path,
command: None,
format,
config: None,
quiet: false,
include_components: false,
min_grade: None,
output: None,
with_git_context: false,
explain: false,
threshold: 10,
baseline: None,
viz: false,
viz_theme: "default".to_string(),
}
}
fn tests_fixture() -> (TempDir, PathBuf) {
let dir = TempDir::new().expect("tempdir");
let tests_dir = dir.path().join("tests");
std::fs::create_dir_all(&tests_dir).expect("mkdir tests");
let file = tests_dir.join("m00.rs");
std::fs::write(&file, "#[test]\nfn t0() { assert!(true); }\n").expect("write");
(dir, file)
}
#[test]
#[serial_test::serial]
fn skip_verdict_does_not_depend_on_the_callers_cwd() {
let (dir, file) = tests_fixture();
let absolute = should_skip_path(&config_for(file.clone(), TdgOutputFormat::Json));
let previous = std::env::current_dir().expect("cwd");
std::env::set_current_dir(file.parent().expect("parent")).expect("chdir");
let relative = should_skip_path(&config_for(PathBuf::from("m00.rs"), TdgOutputFormat::Json));
std::env::set_current_dir(previous).expect("restore cwd");
assert_eq!(
absolute, relative,
"same file, two spellings, two verdicts — the grade depended on the caller's cwd"
);
assert!(absolute, "a file under tests/ is a test file either way");
drop(dir);
}
#[test]
fn skip_verdict_follows_the_resolved_path_not_the_spelling() {
let (dir, file) = tests_fixture();
let link = dir.path().join("aliased");
#[cfg(unix)]
std::os::unix::fs::symlink(file.parent().expect("parent"), &link).expect("symlink");
#[cfg(not(unix))]
return;
let aliased = link.join("m00.rs");
assert!(
!aliased.to_string_lossy().contains("/tests/"),
"fixture must not contain the substring the old check looked for"
);
assert!(
should_skip_path(&config_for(aliased, TdgOutputFormat::Json)),
"the file is under tests/ however it is spelled"
);
}
#[test]
fn a_file_named_tests_rs_is_not_skipped() {
let dir = TempDir::new().expect("tempdir");
let file = dir.path().join("tests.rs");
std::fs::write(&file, "pub fn f() {}\n").expect("write");
assert!(!should_skip_path(&config_for(file, TdgOutputFormat::Json)));
}
#[test]
fn skipped_json_is_json_and_says_nothing_was_measured() {
let (_dir, file) = tests_fixture();
let rendered =
skipped_output(&config_for(file.clone(), TdgOutputFormat::Json)).expect("render");
let value: serde_json::Value =
serde_json::from_str(&rendered).unwrap_or_else(|e| panic!("not JSON: {e}\n{rendered}"));
assert_eq!(value["analyzed"], serde_json::json!(false));
assert!(value["score"].is_null(), "no score may be invented");
assert!(value["grade"].is_null(), "no grade may be invented");
assert_eq!(
value["not_measured"],
serde_json::json!(["score", "grade"]),
"the unmeasured fields must be named"
);
}
#[test]
fn skipped_sarif_is_a_valid_empty_sarif_run() {
let (_dir, file) = tests_fixture();
let rendered = skipped_output(&config_for(file, TdgOutputFormat::Sarif)).expect("render");
let value: serde_json::Value =
serde_json::from_str(&rendered).unwrap_or_else(|e| panic!("not JSON: {e}\n{rendered}"));
assert_eq!(value["version"], serde_json::json!("2.1.0"));
assert_eq!(
value["runs"][0]["results"],
serde_json::json!([]),
"a skipped file produces no results"
);
assert_eq!(
value["runs"][0]["properties"]["analyzed"],
serde_json::json!(false)
);
}