git: refactor tests by extracting some common setup (#44)

This commit is contained in:
Martin von Zweigbergk 2021-12-08 15:15:21 -08:00
parent c678a89794
commit aa78f97d55

View file

@ -73,7 +73,7 @@ fn test_import_refs() {
let git_repo = repo.store().git_repo().unwrap(); let git_repo = repo.store().git_repo().unwrap();
let mut tx = repo.start_transaction("test"); let mut tx = repo.start_transaction("test");
jujutsu_lib::git::import_refs(tx.mut_repo(), &git_repo).unwrap(); git::import_refs(tx.mut_repo(), &git_repo).unwrap();
let repo = tx.commit(); let repo = tx.commit();
let view = repo.view(); let view = repo.view();
@ -159,7 +159,7 @@ fn test_import_refs_reimport() {
.unwrap(); .unwrap();
let mut tx = repo.start_transaction("test"); let mut tx = repo.start_transaction("test");
jujutsu_lib::git::import_refs(tx.mut_repo(), &git_repo).unwrap(); git::import_refs(tx.mut_repo(), &git_repo).unwrap();
let repo = tx.commit(); let repo = tx.commit();
// Delete feature1 and rewrite feature2 // Delete feature1 and rewrite feature2
@ -179,7 +179,7 @@ fn test_import_refs_reimport() {
let repo = tx.commit(); let repo = tx.commit();
let mut tx = repo.start_transaction("test"); let mut tx = repo.start_transaction("test");
jujutsu_lib::git::import_refs(tx.mut_repo(), &git_repo).unwrap(); git::import_refs(tx.mut_repo(), &git_repo).unwrap();
let repo = tx.commit(); let repo = tx.commit();
let view = repo.view(); let view = repo.view();
@ -244,20 +244,40 @@ fn delete_git_ref(git_repo: &git2::Repository, name: &str) {
git_repo.find_reference(name).unwrap().delete().unwrap(); git_repo.find_reference(name).unwrap().delete().unwrap();
} }
struct GitRepoData {
_temp_dir: TempDir,
origin_repo: git2::Repository,
git_repo: git2::Repository,
repo: Arc<ReadonlyRepo>,
}
impl GitRepoData {
fn create() -> Self {
let settings = testutils::user_settings();
let temp_dir = tempfile::tempdir().unwrap();
let origin_repo_dir = temp_dir.path().join("source");
let origin_repo = git2::Repository::init_bare(&origin_repo_dir).unwrap();
let git_repo_dir = temp_dir.path().join("git");
let git_repo =
git2::Repository::clone(origin_repo_dir.to_str().unwrap(), &git_repo_dir).unwrap();
let jj_repo_dir = temp_dir.path().join("jj");
std::fs::create_dir(&jj_repo_dir).unwrap();
let repo = ReadonlyRepo::init_external_git(&settings, jj_repo_dir, git_repo_dir);
Self {
_temp_dir: temp_dir,
origin_repo,
git_repo,
repo,
}
}
}
#[test] #[test]
fn test_import_refs_empty_git_repo() { fn test_import_refs_empty_git_repo() {
let settings = testutils::user_settings(); let test_data = GitRepoData::create();
let temp_dir = tempfile::tempdir().unwrap(); let heads_before = test_data.repo.view().heads().clone();
let git_repo_dir = temp_dir.path().join("source"); let mut tx = test_data.repo.start_transaction("test");
let jj_repo_dir = temp_dir.path().join("jj"); git::import_refs(tx.mut_repo(), &test_data.git_repo).unwrap();
let git_repo = git2::Repository::init_bare(&git_repo_dir).unwrap();
std::fs::create_dir(&jj_repo_dir).unwrap();
let repo = ReadonlyRepo::init_external_git(&settings, jj_repo_dir, git_repo_dir);
let heads_before = repo.view().heads().clone();
let mut tx = repo.start_transaction("test");
jujutsu_lib::git::import_refs(tx.mut_repo(), &git_repo).unwrap();
let repo = tx.commit(); let repo = tx.commit();
assert_eq!(*repo.view().heads(), heads_before); assert_eq!(*repo.view().heads(), heads_before);
assert_eq!(repo.view().branches().len(), 0); assert_eq!(repo.view().branches().len(), 0);
@ -268,26 +288,20 @@ fn test_import_refs_empty_git_repo() {
#[test] #[test]
fn test_import_refs_detached_head() { fn test_import_refs_detached_head() {
let settings = testutils::user_settings(); let test_data = GitRepoData::create();
let temp_dir = tempfile::tempdir().unwrap(); let commit1 = empty_git_commit(&test_data.git_repo, "refs/heads/main", &[]);
let git_repo_dir = temp_dir.path().join("source");
let jj_repo_dir = temp_dir.path().join("jj");
let git_repo = git2::Repository::init_bare(&git_repo_dir).unwrap();
let commit1 = empty_git_commit(&git_repo, "refs/heads/main", &[]);
// Delete the reference. Check that the detached HEAD commit still gets added to // Delete the reference. Check that the detached HEAD commit still gets added to
// the set of heads // the set of heads
git_repo test_data
.git_repo
.find_reference("refs/heads/main") .find_reference("refs/heads/main")
.unwrap() .unwrap()
.delete() .delete()
.unwrap(); .unwrap();
git_repo.set_head_detached(commit1.id()).unwrap(); test_data.git_repo.set_head_detached(commit1.id()).unwrap();
std::fs::create_dir(&jj_repo_dir).unwrap(); let mut tx = test_data.repo.start_transaction("test");
let repo = ReadonlyRepo::init_external_git(&settings, jj_repo_dir, git_repo_dir); git::import_refs(tx.mut_repo(), &test_data.git_repo).unwrap();
let mut tx = repo.start_transaction("test");
jujutsu_lib::git::import_refs(tx.mut_repo(), &git_repo).unwrap();
let repo = tx.commit(); let repo = tx.commit();
let expected_heads = hashset! { let expected_heads = hashset! {
@ -318,39 +332,77 @@ fn test_init() {
assert!(!repo.view().heads().contains(&initial_commit_id)); assert!(!repo.view().heads().contains(&initial_commit_id));
} }
#[test]
fn test_fetch_empty_repo() {
let test_data = GitRepoData::create();
let mut tx = test_data.repo.start_transaction("test");
let default_branch = git::fetch(tx.mut_repo(), &test_data.git_repo, "origin").unwrap();
// No default branch and no refs
assert_eq!(default_branch, None);
assert_eq!(*tx.mut_repo().view().git_refs(), btreemap! {});
assert_eq!(*tx.mut_repo().view().branches(), btreemap! {});
}
#[test]
fn test_fetch_initial_commit() {
let test_data = GitRepoData::create();
let initial_git_commit = empty_git_commit(&test_data.origin_repo, "refs/heads/main", &[]);
let mut tx = test_data.repo.start_transaction("test");
let default_branch = git::fetch(tx.mut_repo(), &test_data.git_repo, "origin").unwrap();
// No default branch because the origin repo's HEAD wasn't set
assert_eq!(default_branch, None);
let repo = tx.commit();
// The initial commit commit is visible after git::fetch().
let view = repo.view();
assert!(view.heads().contains(&commit_id(&initial_git_commit)));
let initial_commit_target = RefTarget::Normal(commit_id(&initial_git_commit));
assert_eq!(
*view.git_refs(),
btreemap! {
"refs/remotes/origin/main".to_string() => initial_commit_target.clone(),
}
);
assert_eq!(
*view.branches(),
btreemap! {
"main".to_string() => BranchTarget {
local_target: Some(initial_commit_target.clone()),
remote_targets: btreemap! {"origin".to_string() => initial_commit_target}
},
}
);
}
#[test] #[test]
fn test_fetch_success() { fn test_fetch_success() {
let settings = testutils::user_settings(); let mut test_data = GitRepoData::create();
let temp_dir = tempfile::tempdir().unwrap(); let initial_git_commit = empty_git_commit(&test_data.origin_repo, "refs/heads/main", &[]);
let source_repo_dir = temp_dir.path().join("source");
let clone_repo_dir = temp_dir.path().join("clone");
let jj_repo_dir = temp_dir.path().join("jj");
let source_git_repo = git2::Repository::init_bare(&source_repo_dir).unwrap();
let initial_git_commit = empty_git_commit(&source_git_repo, "refs/heads/main", &[]);
source_git_repo.set_head("refs/heads/main").unwrap();
let clone_git_repo =
git2::Repository::clone(source_repo_dir.to_str().unwrap(), &clone_repo_dir).unwrap();
std::fs::create_dir(&jj_repo_dir).unwrap();
let jj_repo = ReadonlyRepo::init_external_git(&settings, jj_repo_dir, clone_repo_dir);
let new_git_commit = let mut tx = test_data.repo.start_transaction("test");
empty_git_commit(&source_git_repo, "refs/heads/main", &[&initial_git_commit]); git::fetch(tx.mut_repo(), &test_data.git_repo, "origin").unwrap();
test_data.repo = tx.commit();
let mut tx = jj_repo.start_transaction("test"); test_data.origin_repo.set_head("refs/heads/main").unwrap();
let default_branch = git::fetch(tx.mut_repo(), &clone_git_repo, "origin").unwrap(); let new_git_commit = empty_git_commit(
&test_data.origin_repo,
"refs/heads/main",
&[&initial_git_commit],
);
let mut tx = test_data.repo.start_transaction("test");
let default_branch = git::fetch(tx.mut_repo(), &test_data.git_repo, "origin").unwrap();
// The default branch is "main" // The default branch is "main"
assert_eq!(default_branch, Some("main".to_string())); assert_eq!(default_branch, Some("main".to_string()));
let repo = tx.commit(); let repo = tx.commit();
// The new commit is visible after git::fetch(). // The new commit is visible after we fetch again
let view = repo.view(); let view = repo.view();
assert!(view.heads().contains(&commit_id(&new_git_commit))); assert!(view.heads().contains(&commit_id(&new_git_commit)));
let initial_commit_target = RefTarget::Normal(commit_id(&initial_git_commit));
let new_commit_target = RefTarget::Normal(commit_id(&new_git_commit)); let new_commit_target = RefTarget::Normal(commit_id(&new_git_commit));
assert_eq!( assert_eq!(
*view.git_refs(), *view.git_refs(),
btreemap! { btreemap! {
// The second ref was created by by git2::Repository::clone()
"refs/heads/main".to_string() => initial_commit_target,
"refs/remotes/origin/main".to_string() => new_commit_target.clone(), "refs/remotes/origin/main".to_string() => new_commit_target.clone(),
} }
); );
@ -367,73 +419,57 @@ fn test_fetch_success() {
#[test] #[test]
fn test_fetch_prune_deleted_ref() { fn test_fetch_prune_deleted_ref() {
let settings = testutils::user_settings(); let test_data = GitRepoData::create();
let temp_dir = tempfile::tempdir().unwrap(); empty_git_commit(&test_data.git_repo, "refs/heads/main", &[]);
let source_repo_dir = temp_dir.path().join("source");
let clone_repo_dir = temp_dir.path().join("clone");
let jj_repo_dir = temp_dir.path().join("jj");
let source_git_repo = git2::Repository::init_bare(&source_repo_dir).unwrap();
empty_git_commit(&source_git_repo, "refs/heads/main", &[]);
let clone_git_repo =
git2::Repository::clone(source_repo_dir.to_str().unwrap(), &clone_repo_dir).unwrap();
std::fs::create_dir(&jj_repo_dir).unwrap();
let jj_repo = ReadonlyRepo::init_external_git(&settings, jj_repo_dir, clone_repo_dir);
let mut tx = jj_repo.start_transaction("test"); let mut tx = test_data.repo.start_transaction("test");
git::fetch(tx.mut_repo(), &clone_git_repo, "origin").unwrap(); git::fetch(tx.mut_repo(), &test_data.git_repo, "origin").unwrap();
// Test the setup // Test the setup
assert!(tx.mut_repo().get_branch("main").is_some()); assert!(tx.mut_repo().get_branch("main").is_some());
// After re-fetching, the branch should be deleted test_data
source_git_repo .git_repo
.find_reference("refs/heads/main") .find_reference("refs/heads/main")
.unwrap() .unwrap()
.delete() .delete()
.unwrap(); .unwrap();
git::fetch(tx.mut_repo(), &clone_git_repo, "origin").unwrap(); // After re-fetching, the branch should be deleted
git::fetch(tx.mut_repo(), &test_data.git_repo, "origin").unwrap();
assert!(tx.mut_repo().get_branch("main").is_none()); assert!(tx.mut_repo().get_branch("main").is_none());
} }
#[test] #[test]
fn test_fetch_no_default_branch() { fn test_fetch_no_default_branch() {
let settings = testutils::user_settings(); let test_data = GitRepoData::create();
let temp_dir = tempfile::tempdir().unwrap(); let initial_git_commit = empty_git_commit(&test_data.origin_repo, "refs/heads/main", &[]);
let source_repo_dir = temp_dir.path().join("source");
let clone_repo_dir = temp_dir.path().join("clone");
let jj_repo_dir = temp_dir.path().join("jj");
let source_git_repo = git2::Repository::init_bare(&source_repo_dir).unwrap();
let initial_git_commit = empty_git_commit(&source_git_repo, "refs/heads/main", &[]);
let clone_git_repo =
git2::Repository::clone(source_repo_dir.to_str().unwrap(), &clone_repo_dir).unwrap();
std::fs::create_dir(&jj_repo_dir).unwrap();
let jj_repo = ReadonlyRepo::init_external_git(&settings, jj_repo_dir, clone_repo_dir);
empty_git_commit(&source_git_repo, "refs/heads/main", &[&initial_git_commit]); let mut tx = test_data.repo.start_transaction("test");
git::fetch(tx.mut_repo(), &test_data.git_repo, "origin").unwrap();
empty_git_commit(
&test_data.origin_repo,
"refs/heads/main",
&[&initial_git_commit],
);
// It's actually not enough to have a detached HEAD, it also needs to point to a // It's actually not enough to have a detached HEAD, it also needs to point to a
// commit without a commit (that's possibly a bug in Git *and* libgit2), so // commit without a branch (that's possibly a bug in Git *and* libgit2), so
// we point it to initial_git_commit. // we point it to initial_git_commit.
source_git_repo test_data
.origin_repo
.set_head_detached(initial_git_commit.id()) .set_head_detached(initial_git_commit.id())
.unwrap(); .unwrap();
let mut tx = jj_repo.start_transaction("test"); let default_branch = git::fetch(tx.mut_repo(), &test_data.git_repo, "origin").unwrap();
let default_branch = git::fetch(tx.mut_repo(), &clone_git_repo, "origin").unwrap();
// There is no default branch // There is no default branch
assert_eq!(default_branch, None); assert_eq!(default_branch, None);
} }
#[test] #[test]
fn test_fetch_no_such_remote() { fn test_fetch_no_such_remote() {
let settings = testutils::user_settings(); let test_data = GitRepoData::create();
let temp_dir = tempfile::tempdir().unwrap();
let source_repo_dir = temp_dir.path().join("source");
let jj_repo_dir = temp_dir.path().join("jj");
let git_repo = git2::Repository::init_bare(&source_repo_dir).unwrap();
std::fs::create_dir(&jj_repo_dir).unwrap();
let jj_repo = ReadonlyRepo::init_external_git(&settings, jj_repo_dir, source_repo_dir);
let mut tx = jj_repo.start_transaction("test"); let mut tx = test_data.repo.start_transaction("test");
let result = git::fetch(tx.mut_repo(), &git_repo, "invalid-remote"); let result = git::fetch(tx.mut_repo(), &test_data.git_repo, "invalid-remote");
assert!(matches!(result, Err(GitFetchError::NoSuchRemote(_)))); assert!(matches!(result, Err(GitFetchError::NoSuchRemote(_))));
} }