use super::support::*;
use crate::languages::runner::*;
#[tokio::test]
async fn a_whole_project_tools_findings_are_narrowed_to_the_requested_files() {
let dir = tempfile::tempdir().expect("tempdir");
let root = dir.path();
install_stub(
root,
"wholeproject",
"#!/bin/sh\nprintf 'wanted.rs\\nuntouched.rs\\nalso_wanted.rs\\n'\n",
);
let spec = whole_project_lines_spec();
let outcome = run_tool(
&spec,
root,
&["wanted.rs".to_owned(), "./also_wanted.rs".to_owned()],
)
.await;
assert_eq!(outcome.status, ToolStatus::Ok, "detail: {}", outcome.detail);
let mut reported: Vec<&str> = outcome
.findings
.iter()
.map(|f| f.file_path.as_str())
.collect();
reported.sort_unstable();
assert_eq!(
reported,
vec!["also_wanted.rs", "wanted.rs"],
"untouched.rs was not asked about, so its finding must be dropped"
);
}
#[tokio::test]
async fn a_file_taking_tools_findings_are_not_filtered() {
let dir = tempfile::tempdir().expect("tempdir");
let root = dir.path();
install_stub(
root,
"perfile",
"#!/bin/sh\nprintf 'somewhere/else.rs\\n'\n",
);
let spec = per_file_lines_spec();
let outcome = run_tool(&spec, root, &["asked.rs".to_owned()]).await;
assert_eq!(outcome.status, ToolStatus::Ok, "detail: {}", outcome.detail);
assert_eq!(
outcome.findings.len(),
1,
"a per-file tool only reports on what it was given, so nothing is dropped"
);
}
#[tokio::test]
async fn a_whole_project_tools_absolute_paths_still_match_the_requested_files() {
let dir = tempfile::tempdir().expect("tempdir");
let root = dir.path();
let absolute = root.join("asked.rs");
install_stub(
root,
"wholeproject",
&format!(
"#!/bin/sh\nprintf '%s\\n' '{}'\n",
absolute.to_string_lossy()
),
);
let spec = whole_project_lines_spec();
let outcome = run_tool(&spec, root, &["asked.rs".to_owned()]).await;
assert_eq!(outcome.status, ToolStatus::Ok, "detail: {}", outcome.detail);
assert_eq!(
outcome.findings.len(),
1,
"an absolute path naming the requested file is the requested file"
);
}
#[tokio::test]
async fn a_whole_project_tools_untouched_files_are_still_dropped() {
let dir = tempfile::tempdir().expect("tempdir");
let root = dir.path();
let elsewhere = root.join("untouched.rs");
install_stub(
root,
"wholeproject",
&format!(
"#!/bin/sh\nprintf '%s\\n' '{}'\n",
elsewhere.to_string_lossy()
),
);
let spec = whole_project_lines_spec();
let outcome = run_tool(&spec, root, &["asked.rs".to_owned()]).await;
assert_eq!(outcome.status, ToolStatus::Ok, "detail: {}", outcome.detail);
assert!(
outcome.findings.is_empty(),
"a commit gate must not block on a file the commit never touched"
);
}
#[cfg(unix)]
#[tokio::test]
async fn findings_match_when_the_workspace_path_is_a_symlink() {
let dir = tempfile::tempdir().expect("tempdir");
let real = dir.path().join("real");
std::fs::create_dir(&real).expect("real dir");
let link = dir.path().join("link");
std::os::unix::fs::symlink(&real, &link).expect("symlink");
std::fs::write(real.join("asked.rs"), "fn main() {}\n").expect("source");
let canonical = real.join("asked.rs").canonicalize().expect("canonical");
install_stub(
&real,
"wholeproject",
&format!(
"#!/bin/sh\nprintf '%s\\n' '{}'\n",
canonical.to_string_lossy()
),
);
let spec = whole_project_lines_spec();
let outcome = run_tool(&spec, &link, &["asked.rs".to_owned()]).await;
assert_eq!(outcome.status, ToolStatus::Ok, "detail: {}", outcome.detail);
assert_eq!(
outcome.findings.len(),
1,
"a canonical spelling of a requested file is the requested file"
);
}