use provenance_macros::verifies;
use super::*;
fn all_outcomes() -> Vec<FileStatus> {
let mut all = vec![FileStatus::Unchanged];
while let Some(next) = match all.last().unwrap() {
FileStatus::Unchanged => Some(FileStatus::Installed),
FileStatus::Installed => Some(FileStatus::Updated),
FileStatus::Updated => Some(FileStatus::Linked),
FileStatus::Linked => Some(FileStatus::Removed),
FileStatus::Removed => None,
} {
all.push(next);
}
all
}
fn strength(outcome: FileStatus) -> usize {
match outcome {
FileStatus::Unchanged => 0,
FileStatus::Installed | FileStatus::Linked => 1,
FileStatus::Updated | FileStatus::Removed => 2,
}
}
fn strongest(outcomes: &[FileStatus]) -> FileStatus {
let rank = outcomes.iter().copied().map(strength).max().unwrap_or(0);
[
FileStatus::Unchanged,
FileStatus::Installed,
FileStatus::Updated,
][rank]
}
fn reports(outcomes: &[FileStatus]) -> Vec<FileInstallReport> {
outcomes
.iter()
.enumerate()
.map(|(index, outcome)| FileInstallReport {
path: format!("file-{index}"),
status: *outcome,
})
.collect()
}
#[test]
#[verifies("rule_install_run_status", exhaustion)]
fn every_outcome_set_reports_the_strongest_change() {
let outcomes = all_outcomes();
for mask in 0..(1usize << outcomes.len()) {
let present = outcomes
.iter()
.copied()
.enumerate()
.filter(|(index, _)| (mask >> index) & 1 == 1)
.map(|(_, outcome)| outcome)
.collect::<Vec<_>>();
let padded = present
.iter()
.rev()
.chain(present.iter())
.copied()
.collect::<Vec<_>>();
let expected = strongest(&present);
for files in [reports(&present), reports(&padded)] {
let statuses = files.iter().map(|file| file.status).collect::<Vec<_>>();
assert_eq!(
combined_status(&files),
expected,
"run of {statuses:?} should be reported as {expected:?}"
);
}
}
}
#[test]
fn home_dir_uses_userprofile_when_home_is_absent() {
let resolved = home_dir_from_env(|key| {
if key == "USERPROFILE" {
Some(OsString::from(r"C:\Users\Ada"))
} else {
None
}
})
.unwrap();
assert_eq!(resolved, PathBuf::from(r"C:\Users\Ada"));
}