xonsh/tests/prompt/test_vc.py
Noorhteen Raja NJ 45b588c52e
feat: add config option to hide gitstatus prompt fields (#4294)
* refactor: create namedConstants for std colors

* feat: add gitstatus hide option

* test: update test_vc to not leak xsh object
2021-06-11 02:24:24 +03:00

143 lines
3.9 KiB
Python

import os
import subprocess as sp
from pathlib import Path
from unittest.mock import Mock
import pytest
from xonsh.environ import Env
from xonsh.prompt import vc
# Xonsh interaction with version control systems.
VC_BRANCH = {"git": {"master", "main"}, "hg": {"default"}}
@pytest.fixture(params=VC_BRANCH.keys())
def repo(request, tmpdir_factory):
"""Return a dict with vc and a temporary dir
that is a repository for testing.
"""
vc = request.param
temp_dir = Path(tmpdir_factory.mktemp("dir"))
os.chdir(temp_dir)
try:
sp.call([vc, "init"])
except FileNotFoundError:
pytest.skip("cannot find {} executable".format(vc))
if vc == "git":
git_config = temp_dir / ".git/config"
git_config.write_text(
"""
[user]
name = me
email = my@email.address
[init]
defaultBranch = main
"""
)
# git needs at least one commit
Path("test-file").touch()
sp.call(["git", "add", "test-file"])
sp.call(["git", "commit", "-m", "test commit"])
return {"vc": vc, "dir": temp_dir}
@pytest.fixture
def set_xenv(xession, monkeypatch):
def _wrapper(path):
monkeypatch.setattr(xession, "env", Env(VC_BRANCH_TIMEOUT=2, PWD=path))
return xession
return _wrapper
def test_test_repo(repo):
test_vc_dir = repo["dir"] / ".{}".format(repo["vc"])
assert test_vc_dir.is_dir()
if repo["vc"] == "git":
test_file = repo["dir"] / "test-file"
assert test_file.exists()
def test_no_repo(tmpdir, set_xenv):
set_xenv(tmpdir)
assert vc.get_hg_branch() is None
assert vc.get_git_branch() is None
def test_vc_get_branch(repo, set_xenv):
set_xenv(repo["dir"])
# get corresponding function from vc module
get_branch = "get_{}_branch".format(repo["vc"])
branch = getattr(vc, get_branch)()
assert branch in VC_BRANCH[repo["vc"]]
if repo["vc"] == "git":
git_config = repo["dir"] / ".git/config"
with git_config.open("a") as f:
f.write(
"""
[color]
branch = always
interactive = always
[color "branch"]
current = yellow reverse
"""
)
branch = getattr(vc, get_branch)()
assert branch in VC_BRANCH[repo["vc"]]
assert not branch.startswith(u"\u001b[")
def test_current_branch_calls_locate_binary_for_empty_cmds_cache(xession):
cache = xession.commands_cache
cache.is_empty = Mock(return_value=True)
cache.locate_binary = Mock(return_value="")
vc.current_branch()
assert cache.locate_binary.called
def test_current_branch_does_not_call_locate_binary_for_non_empty_cmds_cache(
xession,
):
cache = xession.commands_cache
cache.is_empty = Mock(return_value=False)
cache.locate_binary = Mock(return_value="")
# make lazy locate return nothing to avoid running vc binaries
cache.lazy_locate_binary = Mock(return_value="")
vc.current_branch()
assert not cache.locate_binary.called
def test_dirty_working_directory(repo, set_xenv):
get_dwd = "{}_dirty_working_directory".format(repo["vc"])
set_xenv(repo["dir"])
# By default, git / hg do not care about untracked files
Path("second-test-file").touch()
assert not getattr(vc, get_dwd)()
sp.call([repo["vc"], "add", "second-test-file"])
assert getattr(vc, get_dwd)()
@pytest.mark.parametrize("include_untracked", [True, False])
def test_git_dirty_working_directory_includes_untracked(
xession, fake_process, include_untracked
):
xession.env["VC_GIT_INCLUDE_UNTRACKED"] = include_untracked
if include_untracked:
fake_process.register_subprocess(
command="git status --porcelain --untracked-files=normal".split(),
stdout=b"?? untracked-test-file",
)
else:
fake_process.register_subprocess(
command="git status --porcelain --untracked-files=no".split(),
stdout=b"",
)
assert vc.git_dirty_working_directory() == include_untracked