use std::path::Path;
use super::super::{MAIN, Project, ball, read0, snap};
use super::{NAME, WS, only, worked};
use crate::workdiff::{Change, WorkFile, patch};
#[test]
fn a_ref_that_is_not_there_is_named() {
let project = Project::new();
let snap = snap(
Path::new(WS),
NAME,
&project.path,
vec![ball("bl-1", Some(NAME), None)],
);
let attempt = only(read0(&snap, Path::new(WS)));
let Change::Absent {
target,
source,
missing,
} = &attempt.change
else {
panic!("an unminted work branch is absent: {attempt:?}");
};
assert_eq!((target.as_str(), source.as_str()), (MAIN, "work/bl-1"));
assert_eq!(missing, &vec!["work/bl-1".to_owned()]);
assert_eq!(attempt.range().as_deref(), Some("main..work/bl-1"));
assert!(
patch(
&snap,
std::slice::from_ref(&attempt),
&WorkFile {
ball: "bl-1".to_owned(),
handle: None,
path: "src/a.rs".to_owned(),
}
)
.is_none()
);
}
#[test]
fn a_project_that_is_not_a_repo_is_unreadable() {
let dir = tempfile::tempdir().unwrap();
let project = dir.path().to_path_buf();
let snap = snap(
Path::new(WS),
NAME,
&project,
vec![ball("bl-1", Some(NAME), None)],
);
let attempt = only(read0(&snap, Path::new(WS)));
assert_eq!(attempt.change, Change::Unreadable);
assert_eq!(attempt.range(), None, "there is no range to state");
assert!(
patch(
&snap,
&[attempt],
&WorkFile {
ball: "bl-1".to_owned(),
handle: None,
path: "x".to_owned(),
}
)
.is_none()
);
}
#[test]
fn a_repo_that_cannot_diff_is_unreadable() {
let project = worked();
let snap = snap(
Path::new(WS),
NAME,
&project.path,
vec![ball("bl-1", Some(NAME), None)],
);
let Change::Diff {
target_oid,
source_oid,
..
} = only(read0(&snap, Path::new(WS))).change
else {
panic!("the repo reads before it is damaged");
};
keep_only(&project.path, &[target_oid, source_oid]);
assert_eq!(only(read0(&snap, Path::new(WS))).change, Change::Unreadable);
}
fn keep_only(repo: &Path, keep: &[String]) {
let objects = repo.join(".git/objects");
for shard in std::fs::read_dir(&objects).unwrap().flatten() {
let name = shard.file_name().to_string_lossy().into_owned();
if name.len() != 2 {
continue;
}
for object in std::fs::read_dir(shard.path()).unwrap().flatten() {
let oid = format!("{name}{}", object.file_name().to_string_lossy());
if !keep.contains(&oid) {
std::fs::remove_file(object.path()).unwrap();
}
}
}
}