Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
Signed-off-by: Bernat Gabor <[email protected]>
  • Loading branch information
gaborbernat committed Nov 29, 2019
1 parent eb64b9f commit 47be424
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 37 deletions.
3 changes: 2 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ where = src
testing =
pytest >= 4.0.0, <6
coverage >= 4.5.0, < 5
pytest-mock
pytest-mock >= 1.12.1, <2
xonsh >= 0.9.13, <1; python_version > '3.4'
docs =
sphinx >= 2.0.0, < 3
towncrier >= 18.5.0
Expand Down
2 changes: 1 addition & 1 deletion src/virtualenv/activation/xonosh/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ def templates(self):

@classmethod
def supports(cls, interpreter):
return True if interpreter.version_info >= (3, 4) else False
return True if interpreter.version_info >= (3, 5) else False
105 changes: 70 additions & 35 deletions tests/unit/activation/test_activation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from virtualenv.activation import (
BashActivator,
CShellActivator,
DOSActivator,
FishActivator,
PowerShellActivator,
PythonActivator,
Expand Down Expand Up @@ -41,14 +42,12 @@ def norm_path(path):
class ActivationTester(object):
def __init__(self, session, cmd, activate_script, extension):
self._creator = session.creator
self._env = None
self.cmd = cmd
self._version_cmd = [cmd, "--version"]
self._invoke_script = [cmd]
self.activate_script = activate_script
self.activate_cmd = "source"
self.extension = extension
self.non_source_raise = False

def get_version(self, raise_on_fail):
# locally we disable, so that contributors don't need to have everything setup
Expand All @@ -65,35 +64,22 @@ def __call__(self, monkeypatch, tmp_path):
monkeypatch.chdir(tmp_path)

monkeypatch.delenv(str("VIRTUAL_ENV"), raising=False)
invoke = self._invoke_script + [str(test_script)]
invoke, env = self._invoke_script + [str(test_script)], self.env(tmp_path)

try:
raw = subprocess.check_output(invoke, universal_newlines=True, stderr=subprocess.STDOUT, env=self._env)
raw = subprocess.check_output(invoke, universal_newlines=True, stderr=subprocess.STDOUT, env=env)
except subprocess.CalledProcessError as exception:
assert not exception.returncode, exception.output
return
out = re.sub(r"pydev debugger: process \d+ is connecting\n\n", "", raw, re.M).strip().split("\n")
self.assert_output(out, raw, tmp_path)
return env, activate_script

if self.non_source_raise:
with pytest.raises(subprocess.CalledProcessError) as context:
invoke = self._invoke_script + [str(activate_script)]
subprocess.check_output(invoke, stderr=subprocess.STDOUT, env=self._env)
assert context.value.returncode, context
def non_source_activate(self, activate_script):
return self._invoke_script + [str(activate_script)]

def assert_output(self, out, raw, tmp_path):
# pre-activation
assert out[0], raw
assert out[1] == "None", raw
# post-activation
assert norm_path(out[2]) == norm_path(self._creator.exe), raw
assert norm_path(out[3]) == norm_path(self._creator.dest_dir).replace("\\\\", "\\"), raw
assert out[4] == "wrote pydoc_test.html"
content = tmp_path / "pydoc_test.html"
assert content.exists(), raw
# post deactivation, same as before
assert out[-2] == out[0], raw
assert out[-1] == "None", raw
def env(self, tmp_path):
return None

def _generate_test_script(self, activate_script, tmp_path):
commands = self._get_test_lines(activate_script)
Expand All @@ -118,6 +104,20 @@ def _get_test_lines(self, activate_script):
]
return commands

def assert_output(self, out, raw, tmp_path):
# pre-activation
assert out[0], raw
assert out[1] == "None", raw
# post-activation
assert norm_path(out[2]) == norm_path(self._creator.exe), raw
assert norm_path(out[3]) == norm_path(self._creator.dest_dir).replace("\\\\", "\\"), raw
assert out[4] == "wrote pydoc_test.html"
content = tmp_path / "pydoc_test.html"
assert content.exists(), raw
# post deactivation, same as before
assert out[-2] == out[0], raw
assert out[-1] == "None", raw

def quote(self, s):
return pipes.quote(s)

Expand All @@ -135,17 +135,40 @@ def activate_call(self, script):
return "{} {}".format(pipes.quote(str(self.activate_cmd)), pipes.quote(str(script))).strip()


class Bash(ActivationTester):
class RaiseOnNonSourceCall(ActivationTester):
def __init__(self, session, cmd, activate_script, extension, non_source_fail_message):
super(RaiseOnNonSourceCall, self).__init__(session, cmd, activate_script, extension)
self.non_source_fail_message = non_source_fail_message

def __call__(self, monkeypatch, tmp_path):
env, activate_script = super(RaiseOnNonSourceCall, self).__call__(monkeypatch, tmp_path)
process = subprocess.Popen(
self.non_source_activate(activate_script),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
universal_newlines=True,
)
out, err = process.communicate()
assert process.returncode
assert self.non_source_fail_message in err


class Bash(RaiseOnNonSourceCall):
def __init__(self, session):
super(Bash, self).__init__(session, "bash", "activate.sh", "sh")
self.non_source_raise = True
super(Bash, self).__init__(session, "bash", "activate.sh", "sh", "You must source this script: $ source ")


class Csh(ActivationTester):
def __init__(self, session):
super(Csh, self).__init__(session, "csh", "activate.csh", "csh")


class DOS(ActivationTester):
def __init__(self, session):
super(DOS, self).__init__(session, "bat", "activate.bat", "cmd")


class Fish(ActivationTester):
def __init__(self, session):
super(Fish, self).__init__(session, "fish", "activate.fish", "fish")
Expand Down Expand Up @@ -175,19 +198,33 @@ def __init__(self, session):
super(Xonosh, self).__init__(session, "xonsh", "activate.xsh", "xsh")
self._invoke_script = [sys.executable, "-m", "xonsh"]
self.__version_cmd = [sys.executable, "-m", "xonsh", "--version"]

def env(self, tmp_path):
env = os.environ.copy()
env[str("PATH")] = os.pathsep.join([dirname(sys.executable)] + env.get(str("PATH"), str("")).split(os.pathsep))
env.update({"XONSH_DEBUG": "1", "XONSH_SHOW_TRACEBACK": "True"})
self._env = env
return env

def activate_call(self, script):
return "{} {}".format(self.activate_cmd, repr(script)).strip()
return "{} {}".format(self.activate_cmd, repr(str(script))).strip()


class Python(ActivationTester):
class Python(RaiseOnNonSourceCall):
def __init__(self, session):
cmd = sys.executable
super(Python, self).__init__(session, cmd, "activate_this.py", "py")
super(Python, self).__init__(
session,
sys.executable,
activate_script="activate_this.py",
extension="py",
non_source_fail_message="You must use exec(open(this_file).read(), {'__file__': this_file}))",
)

def env(self, tmp_path):
env = os.environ.copy()
for key in {"VIRTUAL_ENV", "PYTHONPATH"}:
env.pop(str(key), None)
env[str("PATH")] = os.pathsep.join([str(tmp_path), str(tmp_path / "other")])
return env

def _get_test_lines(self, activate_script):
raw = inspect.getsource(self.activate_this_test)
Expand Down Expand Up @@ -231,11 +268,8 @@ def assert_output(self, out, raw, tmp_path):
# manage to import from activate site package
assert norm_path(out[6]) == norm_path(self._creator.site_packages[0] / "pydoc_test.py")

def __call__(self, monkeypatch, tmp_path):
monkeypatch.delenv(str("VIRTUAL_ENV"), raising=False)
monkeypatch.delenv(str("PYTHONPATH"), raising=False)
monkeypatch.setenv(str("PATH"), os.pathsep.join([str(tmp_path), str(tmp_path / "other")]))
super(Python, self).__call__(monkeypatch, tmp_path)
def non_source_activate(self, activate_script):
return self._invoke_script + ["-c", 'exec(open(r"{}").read())'.format(activate_script)]


ACTIVATION_TEST = {
Expand All @@ -245,6 +279,7 @@ def __call__(self, monkeypatch, tmp_path):
XonoshActivator: Xonosh,
FishActivator: Fish,
PythonActivator: Python,
DOSActivator: DOS,
}
IS_INSIDE_CI = "CI_RUN" in os.environ

Expand Down

0 comments on commit 47be424

Please sign in to comment.