mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
f4f0187e2e
This reverts commit f60385e6c9.
568 lines
18 KiB
Python
568 lines
18 KiB
Python
import os
|
|
import tempfile
|
|
import shutil
|
|
import json
|
|
|
|
import pytest
|
|
|
|
from pipenv.cli import activate_virtualenv
|
|
from pipenv.vendor import toml
|
|
from pipenv.vendor import delegator
|
|
from pipenv.project import Project
|
|
|
|
os.environ['PIPENV_DONT_USE_PYENV'] = '1'
|
|
|
|
class PipenvInstance():
|
|
"""An instance of a Pipenv Project..."""
|
|
def __init__(self, pipfile=True, chdir=False):
|
|
self.original_dir = os.path.abspath(os.curdir)
|
|
self.path = tempfile.mkdtemp(suffix='project', prefix='pipenv')
|
|
self.pipfile_path = None
|
|
self.chdir = chdir
|
|
|
|
if pipfile:
|
|
p_path = os.sep.join([self.path, 'Pipfile'])
|
|
with open(p_path, 'a'):
|
|
os.utime(p_path, None)
|
|
|
|
self.chdir = False or chdir
|
|
self.pipfile_path = p_path
|
|
|
|
def __enter__(self):
|
|
if self.chdir:
|
|
os.chdir(self.path)
|
|
return self
|
|
|
|
def __exit__(self, *args):
|
|
if self.chdir:
|
|
os.chdir(self.original_dir)
|
|
|
|
shutil.rmtree(self.path)
|
|
|
|
def pipenv(self, cmd, block=True):
|
|
if self.pipfile_path:
|
|
os.environ['PIPENV_PIPFILE'] = self.pipfile_path
|
|
|
|
c = delegator.run('pipenv {0}'.format(cmd), block=block)
|
|
|
|
if 'PIPENV_PIPFILE' in os.environ:
|
|
del os.environ['PIPENV_PIPFILE']
|
|
|
|
# Pretty output for failing tests.
|
|
if block:
|
|
print('$ pipenv {0}'.format(cmd))
|
|
print(c.out)
|
|
print(c.err)
|
|
|
|
# Where the action happens.
|
|
return c
|
|
|
|
@property
|
|
def pipfile(self):
|
|
p_path = os.sep.join([self.path, 'Pipfile'])
|
|
with open(p_path, 'r') as f:
|
|
return toml.loads(f.read())
|
|
|
|
@property
|
|
def lockfile(self):
|
|
p_path = os.sep.join([self.path, 'Pipfile.lock'])
|
|
with open(p_path, 'r') as f:
|
|
return json.loads(f.read())
|
|
|
|
|
|
class TestPipenv:
|
|
"""The ultimate testing class."""
|
|
|
|
@pytest.mark.cli
|
|
def test_pipenv_where(self):
|
|
with PipenvInstance() as p:
|
|
assert p.path in p.pipenv('--where').out
|
|
|
|
@pytest.mark.cli
|
|
def test_pipenv_venv(self):
|
|
with PipenvInstance() as p:
|
|
p.pipenv('--python python')
|
|
assert p.pipenv('--venv').out
|
|
|
|
@pytest.mark.cli
|
|
def test_pipenv_py(self):
|
|
with PipenvInstance() as p:
|
|
p.pipenv('--python python')
|
|
assert p.pipenv('--py').out
|
|
|
|
@pytest.mark.cli
|
|
def test_pipenv_rm(self):
|
|
with PipenvInstance() as p:
|
|
p.pipenv('--python python')
|
|
venv_path = p.pipenv('--venv').out
|
|
|
|
assert p.pipenv('--rm').out
|
|
assert not os.path.isdir(venv_path)
|
|
|
|
@pytest.mark.cli
|
|
def test_pipenv_graph(self):
|
|
with PipenvInstance() as p:
|
|
p.pipenv('install requests')
|
|
assert 'requests' in p.pipenv('graph').out
|
|
assert 'requests' in p.pipenv('graph --json').out
|
|
|
|
@pytest.mark.cli
|
|
def test_pipenv_check(self):
|
|
with PipenvInstance() as p:
|
|
p.pipenv('install requests==1.0.0')
|
|
assert 'requests' in p.pipenv('check').out
|
|
|
|
@pytest.mark.cli
|
|
def test_venv_envs(self):
|
|
with PipenvInstance() as p:
|
|
assert p.pipenv('--envs').out
|
|
|
|
@pytest.mark.cli
|
|
def test_venv_jumbotron(self):
|
|
with PipenvInstance() as p:
|
|
assert p.pipenv('--jumbotron').out
|
|
|
|
@pytest.mark.cli
|
|
def test_bare_output(self):
|
|
with PipenvInstance() as p:
|
|
assert p.pipenv('').out
|
|
|
|
@pytest.mark.cli
|
|
def test_help(self):
|
|
with PipenvInstance() as p:
|
|
assert p.pipenv('--help').out
|
|
|
|
@pytest.mark.cli
|
|
def test_completion(self):
|
|
with PipenvInstance() as p:
|
|
assert p.pipenv('--completion').out
|
|
|
|
@pytest.mark.cli
|
|
def test_man(self):
|
|
with PipenvInstance() as p:
|
|
c = p.pipenv('--man')
|
|
assert c.return_code == 0 or c.err
|
|
|
|
@pytest.mark.install
|
|
@pytest.mark.setup
|
|
@pytest.mark.skip(reason="this doesn't work on travis")
|
|
def test_basic_setup(self):
|
|
with PipenvInstance() as p:
|
|
with PipenvInstance(pipfile=False) as p:
|
|
c = p.pipenv('install requests')
|
|
assert c.return_code == 0
|
|
|
|
assert 'requests' in p.pipfile['packages']
|
|
assert 'requests' in p.lockfile['default']
|
|
assert 'chardet' in p.lockfile['default']
|
|
assert 'idna' in p.lockfile['default']
|
|
assert 'urllib3' in p.lockfile['default']
|
|
assert 'certifi' in p.lockfile['default']
|
|
|
|
@pytest.mark.spelling
|
|
@pytest.mark.skip(reason="this is slightly non-deterministic")
|
|
def test_spell_checking(self):
|
|
with PipenvInstance() as p:
|
|
c = p.pipenv('install flaskcors', block=False)
|
|
c.expect(u'[Y//n]:')
|
|
c.send('y')
|
|
c.block()
|
|
|
|
assert c.return_code == 0
|
|
assert 'flask-cors' in p.pipfile['packages']
|
|
assert 'flask' in p.lockfile['default']
|
|
|
|
@pytest.mark.install
|
|
def test_basic_install(self):
|
|
with PipenvInstance() as p:
|
|
c = p.pipenv('install requests')
|
|
assert c.return_code == 0
|
|
assert 'requests' in p.pipfile['packages']
|
|
assert 'requests' in p.lockfile['default']
|
|
assert 'chardet' in p.lockfile['default']
|
|
assert 'idna' in p.lockfile['default']
|
|
assert 'urllib3' in p.lockfile['default']
|
|
assert 'certifi' in p.lockfile['default']
|
|
|
|
@pytest.mark.dev
|
|
@pytest.mark.run
|
|
@pytest.mark.install
|
|
def test_basic_dev_install(self):
|
|
with PipenvInstance() as p:
|
|
c = p.pipenv('install requests --dev')
|
|
assert c.return_code == 0
|
|
assert 'requests' in p.pipfile['dev-packages']
|
|
assert 'requests' in p.lockfile['develop']
|
|
assert 'chardet' in p.lockfile['develop']
|
|
assert 'idna' in p.lockfile['develop']
|
|
assert 'urllib3' in p.lockfile['develop']
|
|
assert 'certifi' in p.lockfile['develop']
|
|
|
|
c = p.pipenv('run python -m requests.help')
|
|
assert c.return_code == 0
|
|
|
|
@pytest.mark.run
|
|
@pytest.mark.uninstall
|
|
def test_uninstall(self):
|
|
with PipenvInstance() as p:
|
|
c = p.pipenv('install requests')
|
|
assert c.return_code == 0
|
|
assert 'requests' in p.pipfile['packages']
|
|
assert 'requests' in p.lockfile['default']
|
|
assert 'chardet' in p.lockfile['default']
|
|
assert 'idna' in p.lockfile['default']
|
|
assert 'urllib3' in p.lockfile['default']
|
|
assert 'certifi' in p.lockfile['default']
|
|
|
|
c = p.pipenv('uninstall requests')
|
|
assert c.return_code == 0
|
|
assert 'requests' not in p.pipfile['dev-packages']
|
|
assert 'requests' not in p.lockfile['develop']
|
|
assert 'chardet' not in p.lockfile['develop']
|
|
assert 'idna' not in p.lockfile['develop']
|
|
assert 'urllib3' not in p.lockfile['develop']
|
|
assert 'certifi' not in p.lockfile['develop']
|
|
|
|
c = p.pipenv('run python -m requests.help')
|
|
assert c.return_code > 0
|
|
|
|
@pytest.mark.extras
|
|
@pytest.mark.install
|
|
def test_extras_install(self):
|
|
with PipenvInstance() as p:
|
|
c = p.pipenv('install requests[socks]')
|
|
assert c.return_code == 0
|
|
assert 'requests' in p.pipfile['packages']
|
|
assert 'extras' in p.pipfile['packages']['requests']
|
|
|
|
assert 'requests' in p.lockfile['default']
|
|
assert 'chardet' in p.lockfile['default']
|
|
assert 'idna' in p.lockfile['default']
|
|
assert 'urllib3' in p.lockfile['default']
|
|
assert 'pysocks' in p.lockfile['default']
|
|
|
|
@pytest.mark.vcs
|
|
@pytest.mark.install
|
|
def test_basic_vcs_install(self):
|
|
with PipenvInstance() as p:
|
|
c = p.pipenv('install git+https://github.com/requests/requests.git#egg=requests')
|
|
assert c.return_code == 0
|
|
assert 'requests' in p.pipfile['packages']
|
|
assert 'git' in p.pipfile['packages']['requests']
|
|
assert p.lockfile['default']['requests'] == {"git": "https://github.com/requests/requests.git"}
|
|
|
|
@pytest.mark.e
|
|
@pytest.mark.vcs
|
|
@pytest.mark.install
|
|
def test_editable_vcs_install(self):
|
|
with PipenvInstance() as p:
|
|
c = p.pipenv('install -e git+https://github.com/requests/requests.git#egg=requests')
|
|
assert c.return_code == 0
|
|
assert 'requests' in p.pipfile['packages']
|
|
assert 'git' in p.pipfile['packages']['requests']
|
|
assert 'editable' in p.pipfile['packages']['requests']
|
|
assert 'editable' in p.lockfile['default']['requests']
|
|
assert 'chardet' in p.lockfile['default']
|
|
assert 'idna' in p.lockfile['default']
|
|
assert 'urllib3' in p.lockfile['default']
|
|
assert 'certifi' in p.lockfile['default']
|
|
|
|
@pytest.mark.run
|
|
@pytest.mark.install
|
|
def test_multiprocess_bug_and_install(self):
|
|
os.environ['PIPENV_MAX_SUBPROCESS'] = '2'
|
|
|
|
with PipenvInstance() as p:
|
|
with open(p.pipfile_path, 'w') as f:
|
|
contents = """
|
|
[packages]
|
|
requests = "*"
|
|
records = "*"
|
|
tpfd = "*"
|
|
""".strip()
|
|
f.write(contents)
|
|
|
|
c = p.pipenv('install')
|
|
assert c.return_code == 0
|
|
|
|
assert 'requests' in p.lockfile['default']
|
|
assert 'idna' in p.lockfile['default']
|
|
assert 'urllib3' in p.lockfile['default']
|
|
assert 'certifi' in p.lockfile['default']
|
|
assert 'records' in p.lockfile['default']
|
|
assert 'tpfd' in p.lockfile['default']
|
|
assert 'parse' in p.lockfile['default']
|
|
|
|
c = p.pipenv('run python -c "import requests; import idna; import certifi; import records; import tpfd; import parse;"')
|
|
assert c.return_code == 0
|
|
|
|
del os.environ['PIPENV_MAX_SUBPROCESS']
|
|
|
|
@pytest.mark.sequential
|
|
@pytest.mark.install
|
|
def test_sequential_mode(self):
|
|
|
|
with PipenvInstance() as p:
|
|
with open(p.pipfile_path, 'w') as f:
|
|
contents = """
|
|
[packages]
|
|
requests = "*"
|
|
records = "*"
|
|
tpfd = "*"
|
|
""".strip()
|
|
f.write(contents)
|
|
|
|
c = p.pipenv('install --sequential')
|
|
assert c.return_code == 0
|
|
|
|
assert 'requests' in p.lockfile['default']
|
|
assert 'idna' in p.lockfile['default']
|
|
assert 'urllib3' in p.lockfile['default']
|
|
assert 'certifi' in p.lockfile['default']
|
|
assert 'records' in p.lockfile['default']
|
|
assert 'tpfd' in p.lockfile['default']
|
|
assert 'parse' in p.lockfile['default']
|
|
|
|
c = p.pipenv('run python -c "import requests; import idna; import certifi; import records; import tpfd; import parse;"')
|
|
assert c.return_code == 0
|
|
|
|
@pytest.mark.run
|
|
@pytest.mark.markers
|
|
@pytest.mark.install
|
|
def test_package_environment_markers(self):
|
|
|
|
with PipenvInstance() as p:
|
|
with open(p.pipfile_path, 'w') as f:
|
|
contents = """
|
|
[packages]
|
|
requests = {version = "*", markers="os_name=='splashwear'"}
|
|
""".strip()
|
|
f.write(contents)
|
|
|
|
c = p.pipenv('install')
|
|
assert c.return_code == 0
|
|
|
|
assert 'Ignoring' in c.out
|
|
assert 'markers' in p.lockfile['default']['requests']
|
|
|
|
c = p.pipenv('run python -c "import requests;"')
|
|
assert c.return_code == 1
|
|
|
|
@pytest.mark.run
|
|
@pytest.mark.alt
|
|
@pytest.mark.install
|
|
def test_specific_package_environment_markers(self):
|
|
|
|
with PipenvInstance() as p:
|
|
with open(p.pipfile_path, 'w') as f:
|
|
contents = """
|
|
[packages]
|
|
requests = {version = "*", os_name = "== 'splashwear'"}
|
|
""".strip()
|
|
f.write(contents)
|
|
|
|
c = p.pipenv('install')
|
|
assert c.return_code == 0
|
|
|
|
assert 'Ignoring' in c.out
|
|
assert 'markers' in p.lockfile['default']['requests']
|
|
|
|
c = p.pipenv('run python -c "import requests;"')
|
|
assert c.return_code == 1
|
|
|
|
@pytest.mark.run
|
|
@pytest.mark.alt
|
|
@pytest.mark.install
|
|
def test_alternative_version_specifier(self):
|
|
|
|
with PipenvInstance() as p:
|
|
with open(p.pipfile_path, 'w') as f:
|
|
contents = """
|
|
[packages]
|
|
requests = {version = "*"}
|
|
""".strip()
|
|
f.write(contents)
|
|
|
|
c = p.pipenv('install')
|
|
assert c.return_code == 0
|
|
|
|
assert 'requests' in p.lockfile['default']
|
|
assert 'idna' in p.lockfile['default']
|
|
assert 'urllib3' in p.lockfile['default']
|
|
assert 'certifi' in p.lockfile['default']
|
|
assert 'chardet' in p.lockfile['default']
|
|
|
|
c = p.pipenv('run python -c "import requests; import idna; import certifi;"')
|
|
assert c.return_code == 0
|
|
|
|
@pytest.mark.bad
|
|
@pytest.mark.install
|
|
def test_bad_packages(self):
|
|
|
|
with PipenvInstance() as p:
|
|
c = p.pipenv('install NotAPackage')
|
|
assert c.return_code > 0
|
|
|
|
@pytest.mark.dotvenv
|
|
def test_venv_in_project(self):
|
|
|
|
os.environ['PIPENV_VENV_IN_PROJECT'] = '1'
|
|
with PipenvInstance() as p:
|
|
c = p.pipenv('install requests')
|
|
assert c.return_code == 0
|
|
|
|
assert p.path in p.pipenv('--venv').out
|
|
|
|
del os.environ['PIPENV_VENV_IN_PROJECT']
|
|
|
|
@pytest.mark.run
|
|
@pytest.mark.dotenv
|
|
def test_env(self):
|
|
|
|
with PipenvInstance(pipfile=False) as p:
|
|
with open('.env', 'w') as f:
|
|
f.write('HELLO=WORLD')
|
|
|
|
c = p.pipenv('run python -c "import os; print(os.environ[\'HELLO\'])"')
|
|
assert c.return_code == 0
|
|
assert 'WORLD' in c.out
|
|
|
|
@pytest.mark.e
|
|
@pytest.mark.install
|
|
@pytest.mark.skip(reason="this doesn't work on windows")
|
|
def test_e_dot(self):
|
|
|
|
with PipenvInstance() as p:
|
|
path = os.path.abspath(os.path.sep.join([os.path.dirname(__file__), '..']))
|
|
c = p.pipenv('install -e \'{0}\' --dev'.format(path))
|
|
|
|
assert c.return_code == 0
|
|
|
|
key = [k for k in p.pipfile['dev-packages'].keys()][0]
|
|
assert 'path' in p.pipfile['dev-packages'][key]
|
|
assert 'requests' in p.lockfile['develop']
|
|
|
|
|
|
@pytest.mark.code
|
|
@pytest.mark.install
|
|
def test_code_import_manual(self):
|
|
|
|
with PipenvInstance() as p:
|
|
|
|
with PipenvInstance(chdir=True) as p:
|
|
with open('t.py', 'w') as f:
|
|
f.write('import requests')
|
|
|
|
p.pipenv('install -c .')
|
|
assert 'requests' in p.pipfile['packages']
|
|
|
|
@pytest.mark.code
|
|
@pytest.mark.check
|
|
@pytest.mark.unused
|
|
def test_check_unused(self):
|
|
|
|
with PipenvInstance() as p:
|
|
|
|
with PipenvInstance(chdir=True) as p:
|
|
|
|
p.pipenv('install requests')
|
|
p.pipenv('install tablib')
|
|
|
|
assert 'requests' in p.pipfile['packages']
|
|
|
|
c = p.pipenv('check --unused .')
|
|
assert 'tablib' in c.out
|
|
|
|
@pytest.mark.check
|
|
@pytest.mark.style
|
|
def test_flake8(self):
|
|
|
|
with PipenvInstance() as p:
|
|
|
|
with PipenvInstance(chdir=True) as p:
|
|
with open('t.py', 'w') as f:
|
|
f.write('import requests')
|
|
|
|
c = p.pipenv('check --style .')
|
|
assert 'requests' in c.out
|
|
|
|
@pytest.mark.extras
|
|
@pytest.mark.install
|
|
@pytest.mark.requirements
|
|
def test_requirements_to_pipfile(self):
|
|
|
|
with PipenvInstance(pipfile=False, chdir=True) as p:
|
|
|
|
# Write a requirements file
|
|
with open('requirements.txt', 'w') as f:
|
|
f.write('requests[socks]==2.18.1\n')
|
|
|
|
c = p.pipenv('install')
|
|
assert c.return_code == 0
|
|
print(c.out)
|
|
print(c.err)
|
|
print(delegator.run('ls -l').out)
|
|
|
|
# assert stuff in pipfile
|
|
assert 'requests' in p.pipfile['packages']
|
|
assert 'extras' in p.pipfile['packages']['requests']
|
|
|
|
# assert stuff in lockfile
|
|
assert 'requests' in p.lockfile['default']
|
|
assert 'chardet' in p.lockfile['default']
|
|
assert 'idna' in p.lockfile['default']
|
|
assert 'urllib3' in p.lockfile['default']
|
|
assert 'pysocks' in p.lockfile['default']
|
|
|
|
@pytest.mark.code
|
|
@pytest.mark.virtualenv
|
|
@pytest.mark.parametrize('shell, extension', [
|
|
('/bin/bash', ''),
|
|
('/bin/fish', '.fish'),
|
|
('/bin/csh', '.csh'),
|
|
('/bin/unknown', '')]
|
|
)
|
|
@pytest.mark.skipif(os.name == 'nt', reason="Not supported to windows")
|
|
def test_activate_virtualenv(self, shell, extension):
|
|
|
|
orig_shell = os.environ['SHELL']
|
|
os.environ['SHELL'] = shell
|
|
|
|
# Get standard activation command for bash
|
|
command = activate_virtualenv()
|
|
|
|
# Return environment to initial shell config.
|
|
os.environ['SHELL'] = orig_shell
|
|
|
|
venv = Project().virtualenv_location
|
|
assert command == 'source {0}/bin/activate{1}'.format(venv, extension)
|
|
|
|
@pytest.mark.code
|
|
@pytest.mark.virtualenv
|
|
def test_activate_virtualenv_no_source(self):
|
|
command = activate_virtualenv(source=False)
|
|
venv = Project().virtualenv_location
|
|
|
|
assert command == '{0}/bin/activate'.format(venv)
|
|
|
|
@pytest.mark.lock
|
|
@pytest.mark.requirements
|
|
def test_lock_requirements_file(self):
|
|
|
|
with PipenvInstance() as p:
|
|
with open(p.pipfile_path, 'w') as f:
|
|
contents = """
|
|
[packages]
|
|
requests = "==2.14.0"
|
|
flask = "==0.12.2"
|
|
[dev-packages]
|
|
pytest = "==3.1.1"
|
|
""".strip()
|
|
f.write(contents)
|
|
|
|
req_list = ("requests==2.14.0", "flask==0.12.2", "pytest==3.1.1")
|
|
|
|
c = p.pipenv('lock --requirements')
|
|
assert c.return_code == 0
|
|
for req in req_list:
|
|
assert req in c.out |