Skip to content

Commit 1cf7b4f

Browse files
committed
Split test_identify
Also make test coverage a little better
1 parent 98ea69c commit 1cf7b4f

File tree

1 file changed

+179
-80
lines changed

1 file changed

+179
-80
lines changed

test/test_package_identification_python.py

Lines changed: 179 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# Copyright 2016-2018 Dirk Thomas
2+
# Copyright 2019 Rover Robotics
23
# Licensed under the Apache License, Version 2.0
3-
4-
from pathlib import Path
5-
from tempfile import TemporaryDirectory
4+
import re
65

76
from colcon_core.package_descriptor import PackageDescriptor
87
from colcon_core.package_identification.python \
@@ -12,85 +11,185 @@
1211
import pytest
1312

1413

15-
def test_identify():
14+
@pytest.fixture
15+
def package_descriptor(tmp_path):
16+
"""Create package descriptor and fail the test if its path changes."""
17+
desc = PackageDescriptor(tmp_path)
18+
yield desc
19+
assert desc.path == tmp_path
20+
21+
22+
@pytest.fixture
23+
def unchanged_empty_descriptor(package_descriptor):
24+
"""Create package descriptor and fail the test if it changes."""
25+
yield package_descriptor
26+
assert package_descriptor.name is None
27+
assert package_descriptor.type is None
28+
29+
30+
def test_error_in_setup_py(unchanged_empty_descriptor):
31+
setup_py = unchanged_empty_descriptor.path / 'setup.py'
32+
error_text = 'My hovercraft is full of eels'
33+
setup_py.write_text('raise OverflowError({!r})'.format(error_text))
34+
35+
extension = PythonPackageIdentification()
36+
with pytest.raises(RuntimeError) as e:
37+
extension.identify(unchanged_empty_descriptor)
38+
39+
assert e.match('Failure when trying to run setup script')
40+
assert e.match(re.escape(str(setup_py)))
41+
42+
# details of the root cause should be in error string
43+
assert e.match('OverflowError')
44+
assert e.match(error_text)
45+
46+
47+
def test_missing_setup_py(unchanged_empty_descriptor):
48+
extension = PythonPackageIdentification()
49+
# should not raise
50+
extension.identify(unchanged_empty_descriptor)
51+
52+
53+
def test_empty_setup_py(unchanged_empty_descriptor):
54+
extension = PythonPackageIdentification()
55+
(unchanged_empty_descriptor.path / 'setup.py').write_text('')
56+
with pytest.raises(RuntimeError) as e:
57+
extension.identify(unchanged_empty_descriptor)
58+
assert e.match('not a Distutils setup script')
59+
60+
61+
def test_re_identify_if_non_python_package(package_descriptor):
62+
package_descriptor.name = 'other-package'
63+
package_descriptor.type = 'other'
64+
extension = PythonPackageIdentification()
65+
extension.identify(package_descriptor)
66+
assert package_descriptor.name == 'other-package'
67+
assert package_descriptor.type == 'other'
68+
69+
70+
def test_re_identify_python_if_same_python_package(package_descriptor):
71+
package_descriptor.name = 'my-package'
72+
package_descriptor.type = 'python'
73+
74+
extension = PythonPackageIdentification()
75+
(package_descriptor.path / 'setup.py').write_text(
76+
'import setuptools; setuptools.setup(name="my-package")')
77+
78+
extension.identify(package_descriptor)
79+
assert package_descriptor.name == 'my-package'
80+
assert package_descriptor.type == 'python'
81+
82+
83+
def test_re_identify_python_if_different_python_package(package_descriptor):
84+
package_descriptor.name = 'other-package'
85+
package_descriptor.type = 'python'
86+
87+
extension = PythonPackageIdentification()
88+
(package_descriptor.path / 'setup.py').write_text(
89+
'import setuptools; setuptools.setup(name="my-package")')
90+
91+
with pytest.raises(RuntimeError):
92+
extension.identify(package_descriptor)
93+
94+
assert package_descriptor.name == 'other-package'
95+
assert package_descriptor.type == 'python'
96+
97+
98+
def test_minimal_cfg(package_descriptor):
99+
extension = PythonPackageIdentification()
100+
101+
(package_descriptor.path / 'setup.py').write_text(
102+
'import setuptools; setuptools.setup()')
103+
(package_descriptor.path / 'setup.cfg').write_text(
104+
'[metadata]\nname = pkg-name')
105+
106+
extension.identify(package_descriptor)
107+
108+
# descriptor should be unchanged
109+
assert package_descriptor.name == 'pkg-name'
110+
assert package_descriptor.type == 'python'
111+
112+
113+
def test_requires(package_descriptor):
114+
extension = PythonPackageIdentification()
115+
116+
(package_descriptor.path / 'setup.py').write_text(
117+
'import setuptools; setuptools.setup()')
118+
119+
(package_descriptor.path / 'setup.cfg').write_text(
120+
'[metadata]\n'
121+
'name = pkg-name\n'
122+
'[options]\n'
123+
'setup_requires =\n'
124+
' setuptools; sys_platform != "imaginary_platform"\n'
125+
' imaginary-package; sys_platform == "imaginary_platform"\n'
126+
'install_requires =\n'
127+
' runA > 1.2.3\n'
128+
' runB\n'
129+
'tests_require = test == 2.0.0\n'
130+
# prevent trying to look for setup_requires in the Package Index
131+
'[easy_install]\n'
132+
'allow_hosts = localhost\n')
133+
134+
extension.identify(package_descriptor)
135+
assert package_descriptor.name == 'pkg-name'
136+
assert package_descriptor.type == 'python'
137+
assert package_descriptor.dependencies.keys() == {'build', 'run', 'test'}
138+
assert package_descriptor.dependencies == {
139+
'build': {'setuptools', 'imaginary-package'},
140+
'run': {'runA', 'runB'},
141+
'test': {'test'}
142+
}
143+
for dep in package_descriptor.dependencies['run']:
144+
if dep == 'runA':
145+
assert dep.metadata['version_gt'] == '1.2.3'
146+
147+
assert package_descriptor.dependencies['run']
148+
assert package_descriptor.dependencies['run'] == {'runA', 'runB'}
149+
150+
151+
def test_metadata_options(package_descriptor):
152+
(package_descriptor.path / 'setup.py').write_text(
153+
'import setuptools; setuptools.setup()')
154+
155+
(package_descriptor.path / 'setup.cfg').write_text(
156+
'[metadata]\n'
157+
'name = pkg-name\n'
158+
'[options]\n'
159+
'zip_safe = false\n'
160+
'packages = find:\n')
161+
162+
(package_descriptor.path / 'my_module').mkdir()
163+
(package_descriptor.path / 'my_module' / '__init__.py').touch()
164+
165+
extension = PythonPackageIdentification()
166+
extension.identify(package_descriptor)
167+
168+
options = package_descriptor.metadata['get_python_setup_options'](None)
169+
assert options['zip_safe'] is False
170+
assert options['packages'] == ['my_module']
171+
172+
173+
def test_metadata_options_dynamic(package_descriptor):
174+
(package_descriptor.path / 'setup.py').write_text(
175+
'import setuptools; setuptools.setup()')
176+
(package_descriptor.path / 'version_helper.py').write_text(
177+
'import os; version = os.environ["version"]'
178+
)
179+
180+
(package_descriptor.path / 'setup.cfg').write_text(
181+
'[metadata]\n'
182+
'name = my-package\n'
183+
'version = attr: version_helper.version\n'
184+
)
185+
16186
extension = PythonPackageIdentification()
187+
extension.identify(package_descriptor)
17188

18-
with TemporaryDirectory(prefix='test_colcon_') as basepath:
19-
desc = PackageDescriptor(basepath)
20-
desc.type = 'other'
21-
assert extension.identify(desc) is None
22-
assert desc.name is None
23-
24-
desc.type = None
25-
assert extension.identify(desc) is None
26-
assert desc.name is None
27-
assert desc.type is None
28-
29-
basepath = Path(basepath)
30-
(basepath / 'setup.py').write_text('')
31-
with pytest.raises(RuntimeError):
32-
extension.identify(desc)
33-
assert desc.name is None
34-
assert desc.type is None
35-
36-
(basepath / 'setup.cfg').write_text('')
37-
with pytest.raises(RuntimeError):
38-
extension.identify(desc)
39-
assert desc.name is None
40-
assert desc.type is None
41-
42-
(basepath / 'setup.py').write_text('raise ValueError()')
43-
with pytest.raises(RuntimeError) as e:
44-
extension.identify(desc)
45-
assert 'ValueError' in str(e.value)
46-
assert desc.name is None
47-
assert desc.type is None
48-
49-
(basepath / 'setup.py').write_text(
50-
'from setuptools import setup\n'
51-
'setup()\n')
52-
(basepath / 'setup.cfg').write_text(
53-
'[metadata]\n'
54-
'name = pkg-name\n')
55-
assert extension.identify(desc) is None
56-
assert desc.name == 'pkg-name'
57-
assert desc.type == 'python'
58-
59-
desc.name = 'other-name'
60-
with pytest.raises(RuntimeError) as e:
61-
extension.identify(desc)
62-
assert 'different' in str(e.value)
63-
assert desc.name == 'other-name'
64-
65-
(basepath / 'setup.cfg').write_text(
66-
'[metadata]\n'
67-
'name = other-name\n'
68-
'[options]\n'
69-
'setup_requires =\n'
70-
' setuptools; sys_platform != "imaginary_platform"\n'
71-
' imaginary-package; sys_platform == "imaginary_platform"\n'
72-
'install_requires =\n'
73-
' runA > 1.2.3\n'
74-
' runB\n'
75-
'tests_require = test == 2.0.0\n'
76-
'zip_safe = false\n'
77-
# prevent trying to look for setup_requires in the Package Index
78-
'[easy_install]\n'
79-
'allow_hosts = localhost\n')
80-
assert extension.identify(desc) is None
81-
assert desc.name == 'other-name'
82-
assert desc.type == 'python'
83-
assert set(desc.dependencies.keys()) == {'build', 'run', 'test'}
84-
assert desc.dependencies['build'] == {
85-
'setuptools', 'imaginary-package'}
86-
assert desc.dependencies['run'] == {'runA', 'runB'}
87-
dep = next(x for x in desc.dependencies['run'] if x == 'runA')
88-
assert dep.metadata['version_gt'] == '1.2.3'
89-
assert desc.dependencies['test'] == {'test'}
90-
91-
assert callable(desc.metadata['get_python_setup_options'])
92-
options = desc.metadata['get_python_setup_options'](None)
93-
assert 'zip_safe' in options
189+
for version in ('1.0', '1.1'):
190+
options = package_descriptor.metadata['get_python_setup_options'](
191+
{'version': version})
192+
assert options['metadata'].version == version
94193

95194

96195
def test_create_dependency_descriptor():

0 commit comments

Comments
 (0)