xonsh/tests/prompt/test_vc.py
Danny Sepler 97cb072f9f
Add a better test suite for "vc.py", and fix "include_untracked" logic (#4041)
* move test_prompt to test_base

* move test_prompt to test_vc

* revamp test_vc file

* Add VC_GIT_INCLUDE_UNTRACKED variable, move test_prompt.py to test_base.py

* reduce test_base
2021-01-05 09:26:19 -05:00

130 lines
3.9 KiB
Python

import os
from pathlib import Path
import shutil
import subprocess as sp
import tempfile
from unittest.mock import Mock
import pytest
from xonsh.environ import Env
from xonsh.prompt import vc
from tools import DummyEnv
# Xonsh interaction with version control systems.
VC_BRANCH = {"git": {"master", "main"}, "hg": {"default"}}
@pytest.fixture(params=VC_BRANCH.keys())
def test_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
"""
)
# 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}
def test_test_repo(test_repo):
test_vc_dir = test_repo["dir"] / ".{}".format(test_repo["vc"])
assert test_vc_dir.is_dir()
if test_repo["vc"] == "git":
test_file = test_repo["dir"] / "test-file"
assert test_file.exists()
def test_no_repo(xonsh_builtins, tmpdir):
xonsh_builtins.__xonsh__.env = Env(VC_BRANCH_TIMEOUT=2, PWD=tmpdir)
assert vc.get_hg_branch() is None
assert vc.get_git_branch() is None
def test_vc_get_branch(test_repo, xonsh_builtins):
xonsh_builtins.__xonsh__.env = Env(VC_BRANCH_TIMEOUT=2, PWD=test_repo["dir"])
# get corresponding function from vc module
get_branch = "get_{}_branch".format(test_repo["vc"])
branch = getattr(vc, get_branch)()
assert branch in VC_BRANCH[test_repo["vc"]]
if test_repo["vc"] == "git":
git_config = test_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[test_repo["vc"]]
assert not branch.startswith(u"\u001b[")
def test_current_branch_calls_locate_binary_for_empty_cmds_cache(xonsh_builtins):
cache = xonsh_builtins.__xonsh__.commands_cache
xonsh_builtins.__xonsh__.env = DummyEnv(VC_BRANCH_TIMEOUT=1)
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(
xonsh_builtins,
):
cache = xonsh_builtins.__xonsh__.commands_cache
xonsh_builtins.__xonsh__.env = DummyEnv(VC_BRANCH_TIMEOUT=1)
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(test_repo, xonsh_builtins):
get_dwd = "{}_dirty_working_directory".format(test_repo["vc"])
xonsh_builtins.__xonsh__.env = Env(VC_BRANCH_TIMEOUT=2, PWD=test_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([test_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(
xonsh_builtins, test_repo, include_untracked
):
xonsh_builtins.__xonsh__.env = DummyEnv(VC_GIT_INCLUDE_UNTRACKED=include_untracked)
if test_repo["vc"] != "git":
return
Path("untracked-test-file").touch()
assert vc.git_dirty_working_directory() == include_untracked