async def test_git_current_branch_detached(git_repo): await git_repo._run(ProcessFormatter().format( git_repo.GIT_CHECKOUT, path=git_repo.folder_path, rev="c950fc05a540dd76b944719c2a3302da2e2f3090", )) p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_CURRENT_BRANCH, path=git_repo.folder_path)) assert p.returncode == 128 assert p.stderr.decode().strip() == "fatal: ref HEAD is not a symbolic ref"
async def test_git_current_commit_detached(git_repo): # detached HEAD state (c950fc05a540dd76b944719c2a3302da2e2f3090) await git_repo._run(ProcessFormatter().format( git_repo.GIT_CHECKOUT, path=git_repo.folder_path, rev="c950fc05a540dd76b944719c2a3302da2e2f3090", )) p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_CURRENT_COMMIT, path=git_repo.folder_path)) assert p.returncode == 0 assert p.stdout.decode().strip( ) == "c950fc05a540dd76b944719c2a3302da2e2f3090"
async def test_git_current_commit_on_branch(git_repo): # HEAD on dont_add_commits (a0ccc2390883c85a361f5a90c72e1b07958939fa) # setup p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_CHECKOUT, path=git_repo.folder_path, rev="dont_add_commits")) assert p.returncode == 0 p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_CURRENT_COMMIT, path=git_repo.folder_path)) assert p.returncode == 0 assert p.stdout.decode().strip( ) == "a0ccc2390883c85a361f5a90c72e1b07958939fa"
async def test_get_file_update_statuses(mocker, repo): old_rev = "c950fc05a540dd76b944719c2a3302da2e2f3090" new_rev = "fb99eb7d2d5bed514efc98fe6686b368f8425745" m = _mock_run( mocker, repo, 0, b"A\x00added_file.txt\x00\t" b"M\x00mycog/__init__.py\x00\t" b"D\x00sample_file1.txt\x00\t" b"D\x00sample_file2.txt\x00\t" b"A\x00sample_file3.txt", ) ret = await repo._get_file_update_statuses(old_rev, new_rev) m.assert_called_once_with(ProcessFormatter().format( repo.GIT_DIFF_FILE_STATUS, path=repo.folder_path, old_rev=old_rev, new_rev=new_rev)) assert ret == { "added_file.txt": "A", "mycog/__init__.py": "M", "sample_file1.txt": "D", "sample_file2.txt": "D", "sample_file3.txt": "A", }
async def test_git_checkout_detached_head(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_CHECKOUT, path=git_repo.folder_path, rev="c950fc05a540dd76b944719c2a3302da2e2f3090", )) assert p.returncode == 0
async def test_get_full_sha1_notfound(mocker, repo): m = _mock_run(mocker, repo, 128, b"", b"fatal: Needed a single revision") with pytest.raises(UnknownRevision): await repo.get_full_sha1("invalid") m.assert_called_once_with(ProcessFormatter().format(repo.GIT_GET_FULL_SHA1, path=repo.folder_path, rev="invalid"))
async def test_git_clone_nobranch(git_repo, tmp_path): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_CLONE_NO_BRANCH, url=git_repo.folder_path, folder=tmp_path / "cloned_repo_test", )) assert p.returncode == 0
async def test_git_clone_non_existent_branch(git_repo, tmp_path): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_CLONE, branch="non-existent-branch", url=git_repo.folder_path, folder=tmp_path / "cloned_repo_test", )) assert p.returncode == 128
async def test_git_is_ancestor_false(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_IS_ANCESTOR, path=git_repo.folder_path, maybe_ancestor_rev="fb99eb7d2d5bed514efc98fe6686b368f8425745", descendant_rev="c950fc05a540dd76b944719c2a3302da2e2f3090", )) assert p.returncode == 1
async def test_git_get_full_sha1_from_annotated_tag(git_repo): p = await git_repo._run( ProcessFormatter().format(git_repo.GIT_GET_FULL_SHA1, path=git_repo.folder_path, rev="annotated")) assert p.returncode == 0 assert p.stdout.decode().strip( ) == "a7120330cc179396914e0d6af80cfa282adc124b"
async def test_git_get_full_sha1_from_lightweight_tag(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_GET_FULL_SHA1, path=git_repo.folder_path, rev="lightweight")) assert p.returncode == 0 assert p.stdout.decode().strip( ) == "fb99eb7d2d5bed514efc98fe6686b368f8425745"
async def test_git_get_full_sha1_from_branch_name(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_GET_FULL_SHA1, path=git_repo.folder_path, rev="dont_add_commits")) assert p.returncode == 0 assert p.stdout.decode().strip( ) == "a0ccc2390883c85a361f5a90c72e1b07958939fa"
async def test_git_clone_notgit_repo(git_repo, tmp_path): notgit_repo = tmp_path / "test_clone_folder" p = await git_repo._run(ProcessFormatter().format(git_repo.GIT_CLONE, branch=None, url=notgit_repo, folder=tmp_path / "cloned_repo_test")) assert p.returncode == 128
async def test_git_check_if_module_exists_true(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_CHECK_IF_MODULE_EXISTS, path=git_repo.folder_path, rev="fb99eb7d2d5bed514efc98fe6686b368f8425745", module_name="mycog", )) assert p.returncode == 0
async def test_git_get_full_sha1_from_full_hash(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_GET_FULL_SHA1, path=git_repo.folder_path, rev="c950fc05a540dd76b944719c2a3302da2e2f3090", )) assert p.returncode == 0 assert p.stdout.decode().strip( ) == "c950fc05a540dd76b944719c2a3302da2e2f3090"
async def test_git_latest_commit(git_repo): # HEAD on dont_add_commits (a0ccc2390883c85a361f5a90c72e1b07958939fa) p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_LATEST_COMMIT, path=git_repo.folder_path, branch="dont_add_commits")) assert p.returncode == 0 assert p.stdout.decode().strip( ) == "a0ccc2390883c85a361f5a90c72e1b07958939fa"
async def test_git_find_last_occurrence_non_existent(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_GET_LAST_MODULE_OCCURRENCE_COMMIT, path=git_repo.folder_path, descendant_rev="c950fc05a540dd76b944719c2a3302da2e2f3090", module_name="mycog", )) assert p.returncode == 0 assert p.stdout.decode().strip() == ""
async def test_get_full_sha1_success(mocker, repo): commit = "c950fc05a540dd76b944719c2a3302da2e2f3090" m = _mock_run(mocker, repo, 0, commit.encode()) ret = await repo.get_full_sha1(commit) m.assert_called_once_with(ProcessFormatter().format(repo.GIT_GET_FULL_SHA1, path=repo.folder_path, rev=commit)) assert ret == commit
async def test_git_is_ancestor_invalid_object(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_IS_ANCESTOR, path=git_repo.folder_path, maybe_ancestor_rev="invalid1", descendant_rev="invalid2", )) assert p.returncode == 128 assert p.stderr.decode().strip( ) == "fatal: Not a valid object name invalid1"
async def test_git_is_ancestor_invalid_commit(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_IS_ANCESTOR, path=git_repo.folder_path, maybe_ancestor_rev="0123456789abcde0123456789abcde0123456789", descendant_rev="c950fc05a540dd76b944719c2a3302da2e2f3090", )) assert p.returncode == 128 assert p.stderr.decode().strip() == ( "fatal: Not a valid commit name 0123456789abcde0123456789abcde0123456789" )
async def test_git_find_last_occurrence_existent(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_GET_LAST_MODULE_OCCURRENCE_COMMIT, path=git_repo.folder_path, descendant_rev="2db662c1d341b1db7d225ccc1af4019ba5228c70", module_name="mycog", )) assert p.returncode == 0 # the command gives a commit after last occurrence assert p.stdout.decode().strip( ) == "a7120330cc179396914e0d6af80cfa282adc124b"
async def test_git_check_if_module_exists_false(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_CHECK_IF_MODULE_EXISTS, path=git_repo.folder_path, rev="a7120330cc179396914e0d6af80cfa282adc124b", module_name="mycog", )) assert p.returncode == 128 assert p.stderr.decode().strip() == ( "fatal: Not a valid object name a7120330cc179396914e0d6af80cfa282adc124b:mycog/__init__.py" )
async def test_clone_with_branch(mocker, repo): branch = repo.branch = "dont_add_commits" commit = "a0ccc2390883c85a361f5a90c72e1b07958939fa" repo.commit = "" m = _mock_run(mocker, repo, 0) _mock_setup_repo(mocker, repo, commit) await repo.clone() assert repo.commit == commit m.assert_called_once_with(ProcessFormatter().format( repo.GIT_CLONE, branch=branch, url=repo.url, folder=repo.folder_path))
async def test_checkout(mocker, repo): commit = "c950fc05a540dd76b944719c2a3302da2e2f3090" m = _mock_run(mocker, repo, 0) _mock_setup_repo(mocker, repo, commit) git_path = repo.folder_path / ".git" git_path.mkdir() await repo._checkout(commit) assert repo.commit == commit m.assert_called_once_with(ProcessFormatter().format(repo.GIT_CHECKOUT, path=repo.folder_path, rev=commit))
async def test_git_hard_reset(cloned_git_repo, tmp_path): staged_file = cloned_git_repo.folder_path / "staged_file.txt" staged_file.touch() git_dirparams = ("git", "-C", str(cloned_git_repo.folder_path)) sp.run((*git_dirparams, "add", "staged_file.txt"), check=True) assert staged_file.exists() is True p = await cloned_git_repo._run(ProcessFormatter().format( cloned_git_repo.GIT_HARD_RESET, path=cloned_git_repo.folder_path, branch="master")) assert p.returncode == 0 assert staged_file.exists() is False
async def test_git_get_full_sha1_from_ambiguous_commits(git_repo): # 2 ambiguous refs: # branch ambiguous_1 - 95da0b576271cb5bee5f3e075074c03ee05fed05 # branch ambiguous_2 - 95da0b57a416d9c8ce950554228d1fc195c30b43 p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_GET_FULL_SHA1, path=git_repo.folder_path, rev="95da0b57")) assert p.returncode == 128 assert p.stderr.decode().strip() == ( "error: short SHA1 95da0b57 is ambiguous\n" "hint: The candidates are:\n" "hint: 95da0b576 commit 2019-10-22 - Ambiguous commit 16955\n" "hint: 95da0b57a commit 2019-10-22 - Ambiguous commit 44414\n" "fatal: Needed a single revision")
async def test_git_get_full_sha1_from_ambiguous_tag_and_commit(git_repo): # 2 ambiguous refs: # branch ambiguous_with_tag - c6f0e5ec04d99bdf8c6c78ff20d66d286eecb3ea # tag ambiguous_tag_66387 - c6f0e5ec04d99bdf8c6c78ff20d66d286eecb3ea p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_GET_FULL_SHA1, path=git_repo.folder_path, rev="c6f0")) assert p.returncode == 128 assert p.stderr.decode().strip() == ( "error: short SHA1 c6f0 is ambiguous\n" "hint: The candidates are:\n" "hint: c6f028f tag ambiguous_tag_66387\n" "hint: c6f0e5e commit 2019-10-24 - Commit ambiguous with tag.\n" "fatal: Needed a single revision")
async def test_git_diff_file_status(git_repo): p = await git_repo._run(ProcessFormatter().format( git_repo.GIT_DIFF_FILE_STATUS, path=git_repo.folder_path, old_rev="c950fc05a540dd76b944719c2a3302da2e2f3090", new_rev="fb99eb7d2d5bed514efc98fe6686b368f8425745", )) assert p.returncode == 0 stdout = p.stdout.strip(b"\t\n\x00 ").decode() assert stdout == ("A\x00added_file.txt\x00\t" "M\x00mycog/__init__.py\x00\t" "D\x00sample_file1.txt\x00\t" "D\x00sample_file2.txt\x00\t" "A\x00sample_file3.txt")
async def test_is_ancestor(mocker, repo, maybe_ancestor_rev, descendant_rev, returncode, expected): m = _mock_run(mocker, repo, returncode) ret = await repo.is_ancestor(maybe_ancestor_rev, descendant_rev) m.assert_called_once_with( ProcessFormatter().format( repo.GIT_IS_ANCESTOR, path=repo.folder_path, maybe_ancestor_rev=maybe_ancestor_rev, descendant_rev=descendant_rev, ), valid_exit_codes=(0, 1), debug_only=True, ) assert ret is expected
async def test_update(mocker, repo): old_commit = repo.commit new_commit = "a0ccc2390883c85a361f5a90c72e1b07958939fa" m = _mock_run(mocker, repo, 0) _mock_setup_repo(mocker, repo, new_commit) mocker.patch.object(repo, "latest_commit", autospec=True, return_value=old_commit) mocker.patch.object(repo, "hard_reset", autospec=True, return_value=None) ret = await repo.update() assert ret == (old_commit, new_commit) m.assert_called_once_with(ProcessFormatter().format(repo.GIT_PULL, path=repo.folder_path))