1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
from __future__ import annotations
import sys
from argparse import Namespace
import pytest
from virtualenv.activation import PowerShellActivator
def test_powershell_pydoc_call_operator(tmp_path):
"""Test that PowerShell pydoc function uses call operator to handle spaces in python path."""
# GIVEN: A mock interpreter
class MockInterpreter:
os = "nt"
tcl_lib = None
tk_lib = None
class MockCreator:
def __init__(self, dest):
self.dest = dest
self.bin_dir = dest / "Scripts"
self.bin_dir.mkdir(parents=True)
self.interpreter = MockInterpreter()
self.pyenv_cfg = {}
self.env_name = "test-env"
creator = MockCreator(tmp_path)
options = Namespace(prompt=None)
activator = PowerShellActivator(options)
# WHEN: Generate activation scripts
activator.generate(creator)
# THEN: pydoc function should use call operator & to handle paths with spaces
activate_content = (creator.bin_dir / "activate.ps1").read_text(encoding="utf-8-sig")
# The pydoc function should use & call operator to handle paths with spaces
assert "& python -m pydoc" in activate_content, (
f"pydoc function should use & call operator. Content:\n{activate_content}"
)
@pytest.mark.parametrize(
("tcl_lib", "tk_lib", "present"),
[
("C:\\tcl", "C:\\tk", True),
(None, None, False),
],
)
def test_powershell_tkinter_generation(tmp_path, tcl_lib, tk_lib, present):
# GIVEN
class MockInterpreter:
os = "nt"
interpreter = MockInterpreter()
interpreter.tcl_lib = tcl_lib
interpreter.tk_lib = tk_lib
class MockCreator:
def __init__(self, dest):
self.dest = dest
self.bin_dir = dest / "bin"
self.bin_dir.mkdir()
self.interpreter = interpreter
self.pyenv_cfg = {}
self.env_name = "my-env"
creator = MockCreator(tmp_path)
options = Namespace(prompt=None)
activator = PowerShellActivator(options)
# WHEN
activator.generate(creator)
content = (creator.bin_dir / "activate.ps1").read_text(encoding="utf-8-sig")
# THEN
# PKG_CONFIG_PATH is always set
assert "New-Variable -Scope global -Name _OLD_PKG_CONFIG_PATH" in content
assert '$env:PKG_CONFIG_PATH = "$env:VIRTUAL_ENV\\lib\\pkgconfig;$env:PKG_CONFIG_PATH"' in content
assert "if (Test-Path variable:_OLD_PKG_CONFIG_PATH)" in content
assert "$env:PKG_CONFIG_PATH = $variable:_OLD_PKG_CONFIG_PATH" in content
assert 'Remove-Variable "_OLD_PKG_CONFIG_PATH" -Scope global' in content
if present:
assert "if ('C:\\tcl' -ne \"\")" in content
assert "$env:TCL_LIBRARY = 'C:\\tcl'" in content
assert "if ('C:\\tk' -ne \"\")" in content
assert "$env:TK_LIBRARY = 'C:\\tk'" in content
assert "if (Test-Path variable:_OLD_VIRTUAL_TCL_LIBRARY)" in content
assert "if (Test-Path variable:_OLD_VIRTUAL_TK_LIBRARY)" in content
else:
assert "if ('' -ne \"\")" in content
assert "$env:TCL_LIBRARY = ''" in content
@pytest.mark.slow
def test_powershell(activation_tester_class, activation_tester, monkeypatch):
monkeypatch.setenv("TERM", "xterm")
class PowerShell(activation_tester_class):
def __init__(self, session) -> None:
cmd = "powershell.exe" if sys.platform == "win32" else "pwsh"
super().__init__(PowerShellActivator, session, cmd, "activate.ps1", "ps1")
self._version_cmd = [cmd, "-c", "$PSVersionTable"]
self._invoke_script = [cmd, "-NonInteractive", "-NoProfile", "-ExecutionPolicy", "ByPass", "-File"]
self.activate_cmd = "."
self.script_encoding = "utf-8-sig"
def _get_test_lines(self, activate_script):
return super()._get_test_lines(activate_script)
def invoke_script(self):
return [self.cmd, "-File"]
def print_os_env_var(self, var):
return f'if ($env:{var} -eq $null) {{ "None" }} else {{ $env:{var} }}'
def print_prompt(self):
return "prompt"
def quote(self, s):
"""Tester will pass strings to native commands on Windows so extra parsing rules are used. Check `PowerShellActivator.quote` for more details."""
text = PowerShellActivator.quote(s)
return text.replace('"', '""') if sys.platform == "win32" else text
def activate_call(self, script):
# Commands are called without quotes in PowerShell
cmd = self.activate_cmd
scr = self.quote(str(script))
return f"{cmd} {scr}".strip()
activation_tester(PowerShell)
|