-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
test_cli.py
322 lines (262 loc) · 10.9 KB
/
test_cli.py
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
import os
import re
import sys
from pathlib import Path
import pytest
from pipenv.utils.processes import subprocess_run
from pipenv.utils.shell import normalize_drive
@pytest.mark.cli
def test_pipenv_where(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv("--where")
assert c.returncode == 0
assert normalize_drive(p.path) in c.stdout
@pytest.mark.cli
def test_pipenv_venv(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv('install dataclasses-json')
assert c.returncode == 0
c = p.pipenv('--venv')
assert c.returncode == 0
venv_path = c.stdout.strip()
assert os.path.isdir(venv_path)
@pytest.mark.cli
@pytest.mark.skipif(sys.version_info[:2] == (3, 8) and os.name == "nt", reason="Python 3.8 on Windows is not supported")
def test_pipenv_py(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv('--python python')
assert c.returncode == 0
c = p.pipenv('--py')
assert c.returncode == 0
python = c.stdout.strip()
assert os.path.basename(python).startswith('python')
@pytest.mark.cli
@pytest.mark.skipif(os.name == 'nt' and sys.version_info[:2] == (3, 8), reason='Test issue with windows 3.8 CIs')
def test_pipenv_site_packages(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv('--python python --site-packages')
assert c.returncode == 0
assert 'Making site-packages available' in c.stderr
# no-global-site-packages.txt under stdlib dir should not exist.
c = p.pipenv('run python -c "import sysconfig; print(sysconfig.get_path(\'stdlib\'))"')
assert c.returncode == 0
stdlib_path = c.stdout.strip()
assert not os.path.isfile(os.path.join(stdlib_path, 'no-global-site-packages.txt'))
@pytest.mark.cli
def test_pipenv_support(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv('--support')
assert c.returncode == 0
assert c.stdout
@pytest.mark.cli
def test_pipenv_rm(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv('--python python')
assert c.returncode == 0
c = p.pipenv('--venv')
assert c.returncode == 0
venv_path = c.stdout.strip()
assert os.path.isdir(venv_path)
c = p.pipenv('--rm')
assert c.returncode == 0
assert c.stdout
assert not os.path.isdir(venv_path)
@pytest.mark.cli
def test_pipenv_graph(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv('install tablib')
assert c.returncode == 0
graph = p.pipenv("graph")
assert graph.returncode == 0
assert "tablib" in graph.stdout
graph_json = p.pipenv("graph --json")
assert graph_json.returncode == 0
assert "tablib" in graph_json.stdout
graph_json_tree = p.pipenv("graph --json-tree")
assert graph_json_tree.returncode == 0
assert "tablib" in graph_json_tree.stdout
@pytest.mark.cli
def test_pipenv_graph_reverse(pipenv_instance_private_pypi):
from pipenv.cli import cli
from pipenv.vendor.click.testing import CliRunner # not thread safe but graph is a tricky test
with pipenv_instance_private_pypi() as p:
c = p.pipenv('install tablib==0.13.0')
assert c.returncode == 0
cli_runner = CliRunner(mix_stderr=False)
c = cli_runner.invoke(cli, "graph --reverse")
assert c.exit_code == 0
output = c.stdout
requests_dependency = [
('backports.csv', 'backports.csv'),
('odfpy', 'odfpy'),
('openpyxl', 'openpyxl>=2.4.0'),
('pyyaml', 'pyyaml'),
('xlrd', 'xlrd'),
('xlwt', 'xlwt'),
]
for dep_name, dep_constraint in requests_dependency:
pat = fr'{dep_name}==[\d.]+'
dep_match = re.search(pat,
output,
flags=re.MULTILINE | re.IGNORECASE)
assert dep_match is not None, f'{pat} not found in {output}'
# openpyxl should be indented
if dep_name == 'openpyxl':
openpyxl_dep = re.search(r'^openpyxl',
output,
flags=re.MULTILINE | re.IGNORECASE)
assert openpyxl_dep is None, f'openpyxl should not appear at beginning of lines in {output}'
if sys.version_info[:2] == (3, 12):
assert 'openpyxl==2.5.4 [requires: et_xmlfile]' in output
else:
assert 'openpyxl==2.5.4 [requires: et-xmlfile]' in output
else:
dep_match = re.search(fr'^[ -]*{dep_name}==[\d.]+$',
output,
flags=re.MULTILINE | re.IGNORECASE)
assert dep_match is not None, f'{dep_name} not found at beginning of line in {output}'
dep_requests_match = re.search(fr'└── tablib==0.13.0 \[requires: {dep_constraint}',
output,
flags=re.MULTILINE | re.IGNORECASE)
assert dep_requests_match is not None, f'constraint {dep_constraint} not found in {output}'
assert dep_requests_match.start() > dep_match.start()
@pytest.mark.cli
@pytest.mark.needs_internet(reason='required by check')
def test_pipenv_check(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
c = p.pipenv('install pyyaml')
assert c.returncode == 0
c = p.pipenv('check --use-installed')
assert c.returncode != 0
assert 'pyyaml' in c.stdout
c = p.pipenv('uninstall pyyaml')
assert c.returncode == 0
c = p.pipenv('install six')
assert c.returncode == 0
c = p.pipenv("run python -m pip install --upgrade pip")
assert c.returncode == 0
# Note: added
# 51457: py <=1.11.0 resolved (1.11.0 installed)!
# this is installed via pytest, and causes a false positive
# https://github.com/pytest-dev/py/issues/287
# the issue above is still not resolved.
# added also 51499
# https://github.com/pypa/wheel/issues/481
c = p.pipenv('check --use-installed --ignore 35015 -i 51457 -i 51499')
assert c.returncode == 0
assert 'Ignoring' in c.stderr
@pytest.mark.cli
@pytest.mark.needs_internet(reason='required by check')
@pytest.mark.parametrize("category", ["CVE", "packages"])
def test_pipenv_check_check_lockfile_categories(pipenv_instance_pypi, category):
with pipenv_instance_pypi() as p:
c = p.pipenv(f'install wheel==0.37.1 --categories={category}')
assert c.returncode == 0
c = p.pipenv(f'check --categories={category}')
assert c.returncode != 0
assert 'wheel' in c.stdout
@pytest.mark.cli
@pytest.mark.skipif(sys.version_info[:2] == (3, 8) and os.name == "nt", reason="This test is not working om Windows Python 3. 8")
def test_pipenv_clean(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
with open('setup.py', 'w') as f:
f.write('from setuptools import setup; setup(name="empty")')
c = p.pipenv('install -e .')
assert c.returncode == 0
c = p.pipenv(f'run pip install -i {p.index_url} six')
assert c.returncode == 0
c = p.pipenv('clean')
assert c.returncode == 0
assert 'six' in c.stdout, f"{c.stdout} -- STDERR: {c.stderr}"
@pytest.mark.cli
def test_venv_envs(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
assert p.pipenv('--envs').stdout
@pytest.mark.cli
def test_bare_output(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
assert p.pipenv('').stdout
@pytest.mark.cli
def test_scripts(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
with open(p.pipfile_path, "w") as f:
contents = """
[scripts]
pyver = "which python"
""".strip()
f.write(contents)
c = p.pipenv('scripts')
assert 'pyver' in c.stdout
assert 'which python' in c.stdout
@pytest.mark.cli
def test_help(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
assert p.pipenv('--help').stdout
@pytest.mark.cli
def test_man(pipenv_instance_pypi):
with pipenv_instance_pypi():
c = subprocess_run(["pipenv", "--man"])
assert c.returncode == 0, c.stderr
@pytest.mark.cli
def test_install_parse_error(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
# Make sure unparsable packages don't wind up in the pipfile
# Escape $ for shell input
with open(p.pipfile_path, 'w') as f:
contents = """
[packages]
[dev-packages]
""".strip()
f.write(contents)
c = p.pipenv('install requests u/\\/p@r\\$34b13+pkg')
assert c.returncode != 0
assert 'u/\\/p@r$34b13+pkg' not in p.pipfile['packages']
@pytest.mark.skip(reason="This test clears the cache that other tests may be using.")
@pytest.mark.cli
def test_pipenv_clear(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv('--clear')
assert c.returncode == 0
assert 'Clearing caches' in c.stdout
@pytest.mark.outdated
def test_pipenv_outdated_prerelease(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
with open(p.pipfile_path, "w") as f:
contents = """
[packages]
sqlalchemy = "<=1.2.3"
""".strip()
f.write(contents)
c = p.pipenv('update --pre --outdated')
assert c.returncode == 0
@pytest.mark.cli
def test_pipenv_verify_without_pipfile(pipenv_instance_pypi):
with pipenv_instance_pypi(pipfile=False) as p:
c = p.pipenv('verify')
assert c.returncode == 1
assert 'No Pipfile present at project home.' in c.stderr
@pytest.mark.cli
def test_pipenv_verify_without_pipfile_lock(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
c = p.pipenv('verify')
assert c.returncode == 1
assert 'Pipfile.lock is out-of-date.' in c.stderr
@pytest.mark.cli
def test_pipenv_verify_locked_passing(pipenv_instance_pypi):
with pipenv_instance_pypi() as p:
p.pipenv('lock')
c = p.pipenv('verify')
assert c.returncode == 0
assert 'Pipfile.lock is up-to-date.' in c.stdout
@pytest.mark.cli
def test_pipenv_verify_locked_outdated_failing(pipenv_instance_private_pypi):
with pipenv_instance_private_pypi() as p:
p.pipenv('lock')
# modify the Pipfile
pf = Path(p.path).joinpath('Pipfile')
pf_data = pf.read_text()
pf_new = re.sub(r'\[packages\]', '[packages]\nrequests = "*"', pf_data)
pf.write_text(pf_new)
c = p.pipenv('verify')
assert c.returncode == 1
assert 'Pipfile.lock is out-of-date.' in c.stderr