1"""develop tests 2""" 3 4from __future__ import absolute_import, unicode_literals 5 6import os 7import site 8import sys 9import io 10import subprocess 11import platform 12 13from setuptools.extern import six 14from setuptools.command import test 15 16import pytest 17 18from setuptools.command.develop import develop 19from setuptools.dist import Distribution 20from . import contexts 21from . import namespaces 22 23SETUP_PY = """\ 24from setuptools import setup 25 26setup(name='foo', 27 packages=['foo'], 28 use_2to3=True, 29) 30""" 31 32INIT_PY = """print "foo" 33""" 34 35 36@pytest.yield_fixture 37def temp_user(monkeypatch): 38 with contexts.tempdir() as user_base: 39 with contexts.tempdir() as user_site: 40 monkeypatch.setattr('site.USER_BASE', user_base) 41 monkeypatch.setattr('site.USER_SITE', user_site) 42 yield 43 44 45@pytest.yield_fixture 46def test_env(tmpdir, temp_user): 47 target = tmpdir 48 foo = target.mkdir('foo') 49 setup = target / 'setup.py' 50 if setup.isfile(): 51 raise ValueError(dir(target)) 52 with setup.open('w') as f: 53 f.write(SETUP_PY) 54 init = foo / '__init__.py' 55 with init.open('w') as f: 56 f.write(INIT_PY) 57 with target.as_cwd(): 58 yield target 59 60 61class TestDevelop: 62 in_virtualenv = hasattr(sys, 'real_prefix') 63 in_venv = hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix 64 65 @pytest.mark.skipif( 66 in_virtualenv or in_venv, 67 reason="Cannot run when invoked in a virtualenv or venv") 68 def test_2to3_user_mode(self, test_env): 69 settings = dict( 70 name='foo', 71 packages=['foo'], 72 use_2to3=True, 73 version='0.0', 74 ) 75 dist = Distribution(settings) 76 dist.script_name = 'setup.py' 77 cmd = develop(dist) 78 cmd.user = 1 79 cmd.ensure_finalized() 80 cmd.install_dir = site.USER_SITE 81 cmd.user = 1 82 with contexts.quiet(): 83 cmd.run() 84 85 # let's see if we got our egg link at the right place 86 content = os.listdir(site.USER_SITE) 87 content.sort() 88 assert content == ['easy-install.pth', 'foo.egg-link'] 89 90 # Check that we are using the right code. 91 fn = os.path.join(site.USER_SITE, 'foo.egg-link') 92 with io.open(fn) as egg_link_file: 93 path = egg_link_file.read().split()[0].strip() 94 fn = os.path.join(path, 'foo', '__init__.py') 95 with io.open(fn) as init_file: 96 init = init_file.read().strip() 97 98 expected = 'print("foo")' if six.PY3 else 'print "foo"' 99 assert init == expected 100 101 def test_console_scripts(self, tmpdir): 102 """ 103 Test that console scripts are installed and that they reference 104 only the project by name and not the current version. 105 """ 106 pytest.skip( 107 "TODO: needs a fixture to cause 'develop' " 108 "to be invoked without mutating environment.") 109 settings = dict( 110 name='foo', 111 packages=['foo'], 112 version='0.0', 113 entry_points={ 114 'console_scripts': [ 115 'foocmd = foo:foo', 116 ], 117 }, 118 ) 119 dist = Distribution(settings) 120 dist.script_name = 'setup.py' 121 cmd = develop(dist) 122 cmd.ensure_finalized() 123 cmd.install_dir = tmpdir 124 cmd.run() 125 # assert '0.0' not in foocmd_text 126 127 128class TestResolver: 129 """ 130 TODO: These tests were written with a minimal understanding 131 of what _resolve_setup_path is intending to do. Come up with 132 more meaningful cases that look like real-world scenarios. 133 """ 134 def test_resolve_setup_path_cwd(self): 135 assert develop._resolve_setup_path('.', '.', '.') == '.' 136 137 def test_resolve_setup_path_one_dir(self): 138 assert develop._resolve_setup_path('pkgs', '.', 'pkgs') == '../' 139 140 def test_resolve_setup_path_one_dir_trailing_slash(self): 141 assert develop._resolve_setup_path('pkgs/', '.', 'pkgs') == '../' 142 143 144class TestNamespaces: 145 146 @staticmethod 147 def install_develop(src_dir, target): 148 149 develop_cmd = [ 150 sys.executable, 151 'setup.py', 152 'develop', 153 '--install-dir', str(target), 154 ] 155 with src_dir.as_cwd(): 156 with test.test.paths_on_pythonpath([str(target)]): 157 subprocess.check_call(develop_cmd) 158 159 @pytest.mark.skipif( 160 bool(os.environ.get("APPVEYOR")), 161 reason="https://github.com/pypa/setuptools/issues/851", 162 ) 163 @pytest.mark.skipif( 164 platform.python_implementation() == 'PyPy' and six.PY3, 165 reason="https://github.com/pypa/setuptools/issues/1202", 166 ) 167 def test_namespace_package_importable(self, tmpdir): 168 """ 169 Installing two packages sharing the same namespace, one installed 170 naturally using pip or `--single-version-externally-managed` 171 and the other installed using `develop` should leave the namespace 172 in tact and both packages reachable by import. 173 """ 174 pkg_A = namespaces.build_namespace_package(tmpdir, 'myns.pkgA') 175 pkg_B = namespaces.build_namespace_package(tmpdir, 'myns.pkgB') 176 target = tmpdir / 'packages' 177 # use pip to install to the target directory 178 install_cmd = [ 179 sys.executable, 180 '-m', 181 'pip', 182 'install', 183 str(pkg_A), 184 '-t', str(target), 185 ] 186 subprocess.check_call(install_cmd) 187 self.install_develop(pkg_B, target) 188 namespaces.make_site_dir(target) 189 try_import = [ 190 sys.executable, 191 '-c', 'import myns.pkgA; import myns.pkgB', 192 ] 193 with test.test.paths_on_pythonpath([str(target)]): 194 subprocess.check_call(try_import) 195 196 # additionally ensure that pkg_resources import works 197 pkg_resources_imp = [ 198 sys.executable, 199 '-c', 'import pkg_resources', 200 ] 201 with test.test.paths_on_pythonpath([str(target)]): 202 subprocess.check_call(pkg_resources_imp) 203