use super::support::{Fixture, Observed, fixture, git, observe, remove, repository, wrapped};
use std::ffi::{OsStr, OsString};
use std::os::unix::ffi::OsStringExt;
use std::path::PathBuf;
const LATIN_NAME: &[u8] = b"caf\xe9.txt";
const LATIN_NAME_BYTES: &str = "Y2Fm6S50eHQ=";
fn latin_finding(sequence: u64, trigger: &str, fix: &str) -> String {
return format!(
"{{\"schemaVersion\":1,\"sequence\":{sequence},\"type\":\"finding\",\"trigger\":\"{trigger}\",\
\"policyId\":\"final-newline\",\"severity\":\"warn\",\"code\":\"final-newline/noncanonical-final-newline\",\
\"message\":\"Non-empty text file must end with exactly one LF byte.\",\
\"path\":\"caf\u{fffd}.txt\",\"pathBytes\":\"{LATIN_NAME_BYTES}\",\"fix\":\"{fix}\"}}\n"
);
}
#[test]
fn events_carry_the_exact_bytes_of_a_name_that_is_not_utf8() {
let fixture: Fixture = fixture("event-path");
let repo: PathBuf = repository(&fixture, OsStr::new("repo"));
let latin: OsString = OsString::from_vec(LATIN_NAME.to_vec());
std::fs::write(repo.join(&latin), b"no newline").expect("Latin-1 file");
let added: Observed = observe(
wrapped(&fixture)
.current_dir(&repo)
.arg("add")
.arg("--")
.arg(&latin),
b"",
);
assert_eq!(
(
added.code,
String::from_utf8_lossy(&added.stderr).into_owned()
),
(Some(0), latin_finding(0, "pre-forward", "none"))
);
git(&fixture, repo.as_path(), &["reset", "--quiet"]);
std::fs::write(repo.join("b.txt"), b"utf-8 name").expect("UTF-8 file");
let checked: Observed = observe(
wrapped(&fixture)
.current_dir(&repo)
.args(["cli-git", "check", "--all"]),
b"",
);
let expected_check: String = format!(
"{{\"schemaVersion\":1,\"sequence\":0,\"type\":\"finding\",\"trigger\":\"direct-check\",\
\"policyId\":\"final-newline\",\"severity\":\"warn\",\"code\":\"final-newline/noncanonical-final-newline\",\
\"message\":\"Non-empty text file must end with exactly one LF byte.\",\"path\":\"b.txt\",\"fix\":\"none\"}}\n{}",
latin_finding(1, "direct-check", "none")
);
assert_eq!(
(
checked.code,
String::from_utf8_lossy(&checked.stdout).into_owned()
),
(Some(0), expected_check)
);
let fixed: Observed = observe(
wrapped(&fixture)
.current_dir(&repo)
.args(["cli-git", "fix", "--all"]),
b"",
);
assert_eq!(
(
fixed.code,
String::from_utf8_lossy(&fixed.stdout).into_owned()
),
(
Some(0),
format!(
"{{\"schemaVersion\":1,\"sequence\":0,\"type\":\"fix-summary\",\"trigger\":\"direct-fix\",\
\"passes\":1,\"changedPaths\":[\"b.txt\",\"caf\u{fffd}.txt\"],\
\"changedPathBytes\":[\"Yi50eHQ=\",\"{LATIN_NAME_BYTES}\"]}}\n"
)
)
);
assert_eq!(
std::fs::read(repo.join(&latin)).expect("corrected"),
b"no newline\n"
);
remove(&fixture);
}