diff options
Diffstat (limited to 'setuptools/tests')
-rw-r--r-- | setuptools/tests/__init__.py | 163 | ||||
-rw-r--r-- | setuptools/tests/py26compat.py | 14 | ||||
-rw-r--r-- | setuptools/tests/server.py | 56 | ||||
-rw-r--r-- | setuptools/tests/test_bdist_egg.py | 69 | ||||
-rw-r--r-- | setuptools/tests/test_develop.py | 62 | ||||
-rw-r--r-- | setuptools/tests/test_dist_info.py | 76 | ||||
-rw-r--r-- | setuptools/tests/test_easy_install.py | 263 | ||||
-rw-r--r-- | setuptools/tests/test_markerlib.py | 64 | ||||
-rw-r--r-- | setuptools/tests/test_packageindex.py | 60 | ||||
-rw-r--r-- | setuptools/tests/test_resources.py | 83 | ||||
-rw-r--r-- | setuptools/tests/test_sdist.py | 170 | ||||
-rw-r--r-- | setuptools/tests/test_test.py | 124 |
12 files changed, 1018 insertions, 186 deletions
diff --git a/setuptools/tests/__init__.py b/setuptools/tests/__init__.py index 669bb826..298141a7 100644 --- a/setuptools/tests/__init__.py +++ b/setuptools/tests/__init__.py @@ -1,17 +1,20 @@ """Tests for the 'setuptools' package""" -from unittest import TestSuite, TestCase, makeSuite, defaultTestLoader -import distutils.core, distutils.cmd +import sys +import os +import unittest +import doctest +import distutils.core +import distutils.cmd from distutils.errors import DistutilsOptionError, DistutilsPlatformError from distutils.errors import DistutilsSetupError -import setuptools, setuptools.dist -from setuptools import Feature from distutils.core import Extension -extract_constant, get_module_constant = None, None +from distutils.version import LooseVersion from setuptools.compat import func_code -from setuptools.depends import * -from distutils.version import StrictVersion, LooseVersion -from distutils.util import convert_path -import sys, os.path + +import setuptools.dist +import setuptools.depends as dep +from setuptools import Feature +from setuptools.depends import Require def additional_tests(): import doctest, unittest @@ -36,55 +39,60 @@ def makeSetup(**args): try: return setuptools.setup(**args) finally: - distutils.core_setup_stop_after = None - - + distutils.core._setup_stop_after = None -class DependsTests(TestCase): +class DependsTests(unittest.TestCase): def testExtractConst(self): - if not extract_constant: return # skip on non-bytecode platforms + if not hasattr(dep, 'extract_constant'): + # skip on non-bytecode platforms + return def f1(): - global x,y,z + global x, y, z x = "test" y = z fc = func_code(f1) # unrecognized name - self.assertEqual(extract_constant(fc,'q', -1), None) + self.assertEqual(dep.extract_constant(fc,'q', -1), None) # constant assigned - self.assertEqual(extract_constant(fc,'x', -1), "test") + self.assertEqual(dep.extract_constant(fc,'x', -1), "test") # expression assigned - self.assertEqual(extract_constant(fc,'y', -1), -1) + self.assertEqual(dep.extract_constant(fc,'y', -1), -1) # recognized name, not assigned - self.assertEqual(extract_constant(fc,'z', -1), None) - + self.assertEqual(dep.extract_constant(fc,'z', -1), None) def testFindModule(self): - self.assertRaises(ImportError, find_module, 'no-such.-thing') - self.assertRaises(ImportError, find_module, 'setuptools.non-existent') - f,p,i = find_module('setuptools.tests'); f.close() + self.assertRaises(ImportError, dep.find_module, 'no-such.-thing') + self.assertRaises(ImportError, dep.find_module, 'setuptools.non-existent') + f,p,i = dep.find_module('setuptools.tests') + f.close() def testModuleExtract(self): - if not get_module_constant: return # skip on non-bytecode platforms + if not hasattr(dep, 'get_module_constant'): + # skip on non-bytecode platforms + return + from email import __version__ self.assertEqual( - get_module_constant('email','__version__'), __version__ + dep.get_module_constant('email','__version__'), __version__ ) self.assertEqual( - get_module_constant('sys','version'), sys.version + dep.get_module_constant('sys','version'), sys.version ) self.assertEqual( - get_module_constant('setuptools.tests','__doc__'),__doc__ + dep.get_module_constant('setuptools.tests','__doc__'),__doc__ ) def testRequire(self): - if not extract_constant: return # skip on non-bytecode platforms + if not hasattr(dep, 'extract_constant'): + # skip on non-bytecode platformsh + return req = Require('Email','1.0.3','email') @@ -96,21 +104,21 @@ class DependsTests(TestCase): from email import __version__ self.assertEqual(req.get_version(), __version__) - self.assert_(req.version_ok('1.0.9')) - self.assert_(not req.version_ok('0.9.1')) - self.assert_(not req.version_ok('unknown')) + self.assertTrue(req.version_ok('1.0.9')) + self.assertTrue(not req.version_ok('0.9.1')) + self.assertTrue(not req.version_ok('unknown')) - self.assert_(req.is_present()) - self.assert_(req.is_current()) + self.assertTrue(req.is_present()) + self.assertTrue(req.is_current()) req = Require('Email 3000','03000','email',format=LooseVersion) - self.assert_(req.is_present()) - self.assert_(not req.is_current()) - self.assert_(not req.version_ok('unknown')) + self.assertTrue(req.is_present()) + self.assertTrue(not req.is_current()) + self.assertTrue(not req.version_ok('unknown')) req = Require('Do-what-I-mean','1.0','d-w-i-m') - self.assert_(not req.is_present()) - self.assert_(not req.is_current()) + self.assertTrue(not req.is_present()) + self.assertTrue(not req.is_current()) req = Require('Tests', None, 'tests', homepage="http://example.com") self.assertEqual(req.format, None) @@ -120,11 +128,11 @@ class DependsTests(TestCase): self.assertEqual(req.homepage, 'http://example.com') paths = [os.path.dirname(p) for p in __path__] - self.assert_(req.is_present(paths)) - self.assert_(req.is_current(paths)) + self.assertTrue(req.is_present(paths)) + self.assertTrue(req.is_current(paths)) -class DistroTests(TestCase): +class DistroTests(unittest.TestCase): def setUp(self): self.e1 = Extension('bar.ext',['bar.c']) @@ -137,10 +145,8 @@ class DistroTests(TestCase): package_dir = {}, ) - def testDistroType(self): - self.assert_(isinstance(self.dist,setuptools.dist.Distribution)) - + self.assertTrue(isinstance(self.dist,setuptools.dist.Distribution)) def testExcludePackage(self): self.dist.exclude_package('a') @@ -159,12 +165,6 @@ class DistroTests(TestCase): # test removals from unspecified options makeSetup().exclude_package('x') - - - - - - def testIncludeExclude(self): # remove an extension self.dist.exclude(ext_modules=[self.e1]) @@ -191,20 +191,17 @@ class DistroTests(TestCase): dist.exclude(packages=['a'], py_modules=['b'], ext_modules=[self.e2]) def testContents(self): - self.assert_(self.dist.has_contents_for('a')) + self.assertTrue(self.dist.has_contents_for('a')) self.dist.exclude_package('a') - self.assert_(not self.dist.has_contents_for('a')) + self.assertTrue(not self.dist.has_contents_for('a')) - self.assert_(self.dist.has_contents_for('b')) + self.assertTrue(self.dist.has_contents_for('b')) self.dist.exclude_package('b') - self.assert_(not self.dist.has_contents_for('b')) + self.assertTrue(not self.dist.has_contents_for('b')) - self.assert_(self.dist.has_contents_for('c')) + self.assertTrue(self.dist.has_contents_for('c')) self.dist.exclude_package('c') - self.assert_(not self.dist.has_contents_for('c')) - - - + self.assertTrue(not self.dist.has_contents_for('c')) def testInvalidIncludeExclude(self): self.assertRaises(DistutilsSetupError, @@ -234,20 +231,7 @@ class DistroTests(TestCase): ) - - - - - - - - - - - - - -class FeatureTests(TestCase): +class FeatureTests(unittest.TestCase): def setUp(self): self.req = Require('Distutils','1.0.3','distutils') @@ -271,12 +255,12 @@ class FeatureTests(TestCase): ) def testDefaults(self): - self.assert_(not + self.assertTrue(not Feature( "test",standard=True,remove='x',available=False ).include_by_default() ) - self.assert_( + self.assertTrue( Feature("test",standard=True,remove='x').include_by_default() ) # Feature must have either kwargs, removes, or require_features @@ -290,33 +274,33 @@ class FeatureTests(TestCase): def testFeatureOptions(self): dist = self.dist - self.assert_( + self.assertTrue( ('with-dwim',None,'include DWIM') in dist.feature_options ) - self.assert_( + self.assertTrue( ('without-dwim',None,'exclude DWIM (default)') in dist.feature_options ) - self.assert_( + self.assertTrue( ('with-bar',None,'include bar (default)') in dist.feature_options ) - self.assert_( + self.assertTrue( ('without-bar',None,'exclude bar') in dist.feature_options ) self.assertEqual(dist.feature_negopt['without-foo'],'with-foo') self.assertEqual(dist.feature_negopt['without-bar'],'with-bar') self.assertEqual(dist.feature_negopt['without-dwim'],'with-dwim') - self.assert_(not 'without-baz' in dist.feature_negopt) + self.assertTrue(not 'without-baz' in dist.feature_negopt) def testUseFeatures(self): dist = self.dist self.assertEqual(dist.with_foo,1) self.assertEqual(dist.with_bar,0) self.assertEqual(dist.with_baz,1) - self.assert_(not 'bar_et' in dist.py_modules) - self.assert_(not 'pkg.bar' in dist.packages) - self.assert_('pkg.baz' in dist.packages) - self.assert_('scripts/baz_it' in dist.scripts) - self.assert_(('libfoo','foo/foofoo.c') in dist.libraries) + self.assertTrue(not 'bar_et' in dist.py_modules) + self.assertTrue(not 'pkg.bar' in dist.packages) + self.assertTrue('pkg.baz' in dist.packages) + self.assertTrue('scripts/baz_it' in dist.scripts) + self.assertTrue(('libfoo','foo/foofoo.c') in dist.libraries) self.assertEqual(dist.ext_modules,[]) self.assertEqual(dist.require_features, [self.req]) @@ -329,11 +313,11 @@ class FeatureTests(TestCase): SystemExit, makeSetup, features = {'x':Feature('x', remove='y')} ) -class TestCommandTests(TestCase): +class TestCommandTests(unittest.TestCase): def testTestIsCommand(self): test_cmd = makeSetup().get_command_obj('test') - self.assert_(isinstance(test_cmd, distutils.cmd.Command)) + self.assertTrue(isinstance(test_cmd, distutils.cmd.Command)) def testLongOptSuiteWNoDefault(self): ts1 = makeSetup(script_args=['test','--test-suite=foo.tests.suite']) @@ -365,8 +349,3 @@ class TestCommandTests(TestCase): ts5 = makeSetup().get_command_obj('test') ts5.ensure_finalized() self.assertEqual(ts5.test_suite, None) - - - - - diff --git a/setuptools/tests/py26compat.py b/setuptools/tests/py26compat.py new file mode 100644 index 00000000..d4fb891a --- /dev/null +++ b/setuptools/tests/py26compat.py @@ -0,0 +1,14 @@ +import unittest + +try: + # provide skipIf for Python 2.4-2.6 + skipIf = unittest.skipIf +except AttributeError: + def skipIf(condition, reason): + def skipper(func): + def skip(*args, **kwargs): + return + if condition: + return skip + return func + return skipper diff --git a/setuptools/tests/server.py b/setuptools/tests/server.py index c70fab7b..c7343340 100644 --- a/setuptools/tests/server.py +++ b/setuptools/tests/server.py @@ -1,7 +1,9 @@ """Basic http server for tests to simulate PyPI or custom indexes """ import sys -from threading import Thread +import time +import threading +import BaseHTTPServer from setuptools.compat import (urllib2, URLError, HTTPServer, SimpleHTTPRequestHandler) @@ -16,32 +18,64 @@ class IndexServer(HTTPServer): # The index files should be located in setuptools/tests/indexes s.stop() """ - def __init__(self): - HTTPServer.__init__(self, ('', 0), SimpleHTTPRequestHandler) + def __init__(self, server_address=('', 0), + RequestHandlerClass=SimpleHTTPRequestHandler): + HTTPServer.__init__(self, server_address, RequestHandlerClass) self._run = True def serve(self): - while True: + while self._run: self.handle_request() - if not self._run: break def start(self): - self.thread = Thread(target=self.serve) + self.thread = threading.Thread(target=self.serve) self.thread.start() def stop(self): - """self.shutdown is not supported on python < 2.6""" + "Stop the server" + + # Let the server finish the last request and wait for a new one. + time.sleep(0.1) + + # self.shutdown is not supported on python < 2.6, so just + # set _run to false, and make a request, causing it to + # terminate. self._run = False + url = 'http://127.0.0.1:%(server_port)s/' % vars(self) try: - if sys.version > '2.6': - urllib2.urlopen('http://127.0.0.1:%s/' % self.server_port, - None, 5) + if sys.version_info >= (2, 6): + urllib2.urlopen(url, timeout=5) else: - urllib2.urlopen('http://127.0.0.1:%s/' % self.server_port) + urllib2.urlopen(url) except URLError: + # ignore any errors; all that's important is the request pass self.thread.join() def base_url(self): port = self.server_port return 'http://127.0.0.1:%s/setuptools/tests/indexes/' % port + +class RequestRecorder(BaseHTTPServer.BaseHTTPRequestHandler): + def do_GET(self): + requests = vars(self.server).setdefault('requests', []) + requests.append(self) + self.send_response(200, 'OK') + +class MockServer(HTTPServer, threading.Thread): + """ + A simple HTTP Server that records the requests made to it. + """ + def __init__(self, server_address=('', 0), + RequestHandlerClass=RequestRecorder): + HTTPServer.__init__(self, server_address, RequestHandlerClass) + threading.Thread.__init__(self) + self.setDaemon(True) + self.requests = [] + + def run(self): + self.serve_forever() + + def url(self): + return 'http://localhost:%(server_port)s/' % vars(self) + url = property(url) diff --git a/setuptools/tests/test_bdist_egg.py b/setuptools/tests/test_bdist_egg.py new file mode 100644 index 00000000..7da122cc --- /dev/null +++ b/setuptools/tests/test_bdist_egg.py @@ -0,0 +1,69 @@ +"""develop tests +""" +import sys +import os, re, shutil, tempfile, unittest +import tempfile +import site +from StringIO import StringIO + +from distutils.errors import DistutilsError +from setuptools.command.bdist_egg import bdist_egg +from setuptools.command import easy_install as easy_install_pkg +from setuptools.dist import Distribution + +SETUP_PY = """\ +from setuptools import setup + +setup(name='foo', py_modules=['hi']) +""" + +class TestDevelopTest(unittest.TestCase): + + def setUp(self): + self.dir = tempfile.mkdtemp() + self.old_cwd = os.getcwd() + os.chdir(self.dir) + f = open('setup.py', 'w') + f.write(SETUP_PY) + f.close() + f = open('hi.py', 'w') + f.write('1\n') + f.close() + if sys.version >= "2.6": + self.old_base = site.USER_BASE + site.USER_BASE = tempfile.mkdtemp() + self.old_site = site.USER_SITE + site.USER_SITE = tempfile.mkdtemp() + + def tearDown(self): + os.chdir(self.old_cwd) + shutil.rmtree(self.dir) + if sys.version >= "2.6": + shutil.rmtree(site.USER_BASE) + shutil.rmtree(site.USER_SITE) + site.USER_BASE = self.old_base + site.USER_SITE = self.old_site + + def test_bdist_egg(self): + dist = Distribution(dict( + script_name='setup.py', + script_args=['bdist_egg'], + name='foo', + py_modules=['hi'] + )) + os.makedirs(os.path.join('build', 'src')) + old_stdout = sys.stdout + sys.stdout = o = StringIO() + try: + dist.parse_command_line() + dist.run_commands() + finally: + sys.stdout = old_stdout + + # let's see if we got our egg link at the right place + [content] = os.listdir('dist') + self.assertTrue(re.match('foo-0.0.0-py[23].\d.egg$', content)) + +def test_suite(): + return unittest.makeSuite(TestDevelopTest) + diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index 752a70e9..ecd2212d 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -14,38 +14,62 @@ from setuptools.dist import Distribution SETUP_PY = """\ from setuptools import setup -setup(name='foo') +setup(name='foo', + packages=['foo'], + use_2to3=True, +) +""" + +INIT_PY = """print "foo" """ class TestDevelopTest(unittest.TestCase): def setUp(self): + if sys.version < "2.6" or hasattr(sys, 'real_prefix'): + return + + # Directory structure self.dir = tempfile.mkdtemp() + os.mkdir(os.path.join(self.dir, 'foo')) + # setup.py setup = os.path.join(self.dir, 'setup.py') f = open(setup, 'w') f.write(SETUP_PY) f.close() self.old_cwd = os.getcwd() + # foo/__init__.py + init = os.path.join(self.dir, 'foo', '__init__.py') + f = open(init, 'w') + f.write(INIT_PY) + f.close() + os.chdir(self.dir) - if sys.version >= "2.6": - self.old_base = site.USER_BASE - site.USER_BASE = tempfile.mkdtemp() - self.old_site = site.USER_SITE - site.USER_SITE = tempfile.mkdtemp() + self.old_base = site.USER_BASE + site.USER_BASE = tempfile.mkdtemp() + self.old_site = site.USER_SITE + site.USER_SITE = tempfile.mkdtemp() def tearDown(self): + if sys.version < "2.6" or hasattr(sys, 'real_prefix'): + return + os.chdir(self.old_cwd) shutil.rmtree(self.dir) - if sys.version >= "2.6": - shutil.rmtree(site.USER_BASE) - shutil.rmtree(site.USER_SITE) - site.USER_BASE = self.old_base - site.USER_SITE = self.old_site + shutil.rmtree(site.USER_BASE) + shutil.rmtree(site.USER_SITE) + site.USER_BASE = self.old_base + site.USER_SITE = self.old_site def test_develop(self): if sys.version < "2.6" or hasattr(sys, 'real_prefix'): return - dist = Distribution() + dist = Distribution( + dict(name='foo', + packages=['foo'], + use_2to3=True, + version='0.0', + )) dist.script_name = 'setup.py' cmd = develop(dist) cmd.user = 1 @@ -53,7 +77,7 @@ class TestDevelopTest(unittest.TestCase): cmd.install_dir = site.USER_SITE cmd.user = 1 old_stdout = sys.stdout - sys.stdout = StringIO() + #sys.stdout = StringIO() try: cmd.run() finally: @@ -62,9 +86,17 @@ class TestDevelopTest(unittest.TestCase): # let's see if we got our egg link at the right place content = os.listdir(site.USER_SITE) content.sort() - self.assertEquals(content, ['UNKNOWN.egg-link', 'easy-install.pth']) + self.assertEqual(content, ['easy-install.pth', 'foo.egg-link']) + + # Check that we are using the right code. + path = open(os.path.join(site.USER_SITE, 'foo.egg-link'), 'rt').read().split()[0].strip() + init = open(os.path.join(path, 'foo', '__init__.py'), 'rt').read().strip() + if sys.version < "3": + self.assertEqual(init, 'print "foo"') + else: + self.assertEqual(init, 'print("foo")') - def test_develop_with_setup_requires(self): + def notest_develop_with_setup_requires(self): wanted = ("Could not find suitable distribution for " "Requirement.parse('I-DONT-EXIST')") diff --git a/setuptools/tests/test_dist_info.py b/setuptools/tests/test_dist_info.py new file mode 100644 index 00000000..623ccc47 --- /dev/null +++ b/setuptools/tests/test_dist_info.py @@ -0,0 +1,76 @@ +"""Test .dist-info style distributions. +""" +import os +import shutil +import tempfile +import unittest +import textwrap + +try: + import ast +except: + pass + +import pkg_resources + +from setuptools.tests.py26compat import skipIf + +def DALS(s): + "dedent and left-strip" + return textwrap.dedent(s).lstrip() + +class TestDistInfo(unittest.TestCase): + + def test_distinfo(self): + dists = {} + for d in pkg_resources.find_distributions(self.tmpdir): + dists[d.project_name] = d + + assert len(dists) == 2, dists + + unversioned = dists['UnversionedDistribution'] + versioned = dists['VersionedDistribution'] + + assert versioned.version == '2.718' # from filename + assert unversioned.version == '0.3' # from METADATA + + @skipIf('ast' not in globals(), + "ast is used to test conditional dependencies (Python >= 2.6)") + def test_conditional_dependencies(self): + requires = [pkg_resources.Requirement.parse('splort==4'), + pkg_resources.Requirement.parse('quux>=1.1')] + + for d in pkg_resources.find_distributions(self.tmpdir): + self.assertEqual(d.requires(), requires[:1]) + self.assertEqual(d.requires(extras=('baz',)), requires) + self.assertEqual(d.extras, ['baz']) + + def setUp(self): + self.tmpdir = tempfile.mkdtemp() + versioned = os.path.join(self.tmpdir, + 'VersionedDistribution-2.718.dist-info') + os.mkdir(versioned) + open(os.path.join(versioned, 'METADATA'), 'w+').write(DALS( + """ + Metadata-Version: 1.2 + Name: VersionedDistribution + Requires-Dist: splort (4) + Provides-Extra: baz + Requires-Dist: quux (>=1.1); extra == 'baz' + """)) + + unversioned = os.path.join(self.tmpdir, + 'UnversionedDistribution.dist-info') + os.mkdir(unversioned) + open(os.path.join(unversioned, 'METADATA'), 'w+').write(DALS( + """ + Metadata-Version: 1.2 + Name: UnversionedDistribution + Version: 0.3 + Requires-Dist: splort (==4) + Provides-Extra: baz + Requires-Dist: quux (>=1.1); extra == 'baz' + """)) + + def tearDown(self): + shutil.rmtree(self.tmpdir) diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index af5644c5..aab4b617 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -1,17 +1,28 @@ """Easy install Tests """ import sys -import os, shutil, tempfile, unittest +import os +import shutil +import tempfile +import unittest import site -from setuptools.compat import StringIO, next +from setuptools.compat import StringIO, BytesIO, next +from setuptools.compat import urlparse +import textwrap +import tarfile +import distutils.core + +from setuptools.sandbox import run_setup, SandboxViolation from setuptools.command.easy_install import easy_install, get_script_args, main from setuptools.command.easy_install import PthDistributions from setuptools.command import easy_install as easy_install_pkg from setuptools.dist import Distribution from pkg_resources import Distribution as PRDistribution +import setuptools.tests.server try: - import multiprocessing + # import multiprocessing solely for the purpose of testing its existence + __import__('multiprocessing') import logging _LOG = logging.getLogger('test_easy_install') logging.basicConfig(level=logging.INFO, stream=sys.stderr) @@ -58,7 +69,7 @@ class TestEasyInstallTest(unittest.TestCase): try: cmd.install_site_py() sitepy = os.path.join(cmd.install_dir, 'site.py') - self.assert_(os.path.exists(sitepy)) + self.assertTrue(os.path.exists(sitepy)) finally: shutil.rmtree(cmd.install_dir) @@ -67,11 +78,11 @@ class TestEasyInstallTest(unittest.TestCase): old_platform = sys.platform try: - name, script = next(get_script_args(dist)) + name, script = [i for i in next(get_script_args(dist))][0:2] finally: sys.platform = old_platform - self.assertEquals(script, WANTED) + self.assertEqual(script, WANTED) def test_no_setup_cfg(self): # makes sure easy_install as a command (main) @@ -92,7 +103,7 @@ class TestEasyInstallTest(unittest.TestCase): opts = self.command_options if 'easy_install' in opts: assert 'find_links' not in opts['easy_install'], msg - return self._old_parse_command_line + return self._old_parse_command_line() Distribution._old_parse_command_line = Distribution.parse_command_line Distribution.parse_command_line = _parse_command_line @@ -100,33 +111,36 @@ class TestEasyInstallTest(unittest.TestCase): old_wd = os.getcwd() try: os.chdir(dir) - main([]) + reset_setup_stop_context( + lambda: self.assertRaises(SystemExit, main, []) + ) finally: os.chdir(old_wd) shutil.rmtree(dir) + Distribution.parse_command_line = Distribution._old_parse_command_line def test_no_find_links(self): # new option '--no-find-links', that blocks find-links added at # the project level dist = Distribution() cmd = easy_install(dist) - cmd.check_pth_processing = lambda : True + cmd.check_pth_processing = lambda: True cmd.no_find_links = True cmd.find_links = ['link1', 'link2'] cmd.install_dir = os.path.join(tempfile.mkdtemp(), 'ok') cmd.args = ['ok'] cmd.ensure_finalized() - self.assertEquals(cmd.package_index.scanned_urls, {}) + self.assertEqual(cmd.package_index.scanned_urls, {}) # let's try without it (default behavior) cmd = easy_install(dist) - cmd.check_pth_processing = lambda : True + cmd.check_pth_processing = lambda: True cmd.find_links = ['link1', 'link2'] cmd.install_dir = os.path.join(tempfile.mkdtemp(), 'ok') cmd.args = ['ok'] cmd.ensure_finalized() keys = sorted(cmd.package_index.scanned_urls.keys()) - self.assertEquals(keys, ['link1', 'link2']) + self.assertEqual(keys, ['link1', 'link2']) class TestPTHFileWriter(unittest.TestCase): @@ -135,15 +149,19 @@ class TestPTHFileWriter(unittest.TestCase): if a distribution is in site but also the cwd ''' pth = PthDistributions('does-not_exist', [os.getcwd()]) - self.assert_(not pth.dirty) + self.assertTrue(not pth.dirty) pth.add(PRDistribution(os.getcwd())) - self.assert_(pth.dirty) + self.assertTrue(pth.dirty) def test_add_from_site_is_ignored(self): - pth = PthDistributions('does-not_exist', ['/test/location/does-not-have-to-exist']) - self.assert_(not pth.dirty) - pth.add(PRDistribution('/test/location/does-not-have-to-exist')) - self.assert_(not pth.dirty) + if os.name != 'nt': + location = '/test/location/does-not-have-to-exist' + else: + location = 'c:\\does_not_exist' + pth = PthDistributions('does-not_exist', [location, ]) + self.assertTrue(not pth.dirty) + pth.add(PRDistribution(location)) + self.assertTrue(not pth.dirty) class TestUserInstallTest(unittest.TestCase): @@ -168,7 +186,7 @@ class TestUserInstallTest(unittest.TestCase): def tearDown(self): os.chdir(self.old_cwd) shutil.rmtree(self.dir) - if sys.version >= "2.6": + if sys.version >= "2.6": shutil.rmtree(site.USER_BASE) shutil.rmtree(site.USER_SITE) site.USER_BASE = self.old_base @@ -220,7 +238,7 @@ class TestUserInstallTest(unittest.TestCase): sys.path.append(target) old_ppath = os.environ.get('PYTHONPATH') - os.environ['PYTHONPATH'] = ':'.join(sys.path) + os.environ['PYTHONPATH'] = os.path.pathsep.join(sys.path) try: dist = Distribution() dist.script_name = 'setup.py' @@ -230,13 +248,212 @@ class TestUserInstallTest(unittest.TestCase): cmd.ensure_finalized() cmd.local_index.scan([new_location]) res = cmd.easy_install('foo') - self.assertEquals(res.location, new_location) + self.assertEqual(os.path.realpath(res.location), + os.path.realpath(new_location)) finally: sys.path.remove(target) - shutil.rmtree(new_location) - shutil.rmtree(target) + for basedir in [new_location, target, ]: + if not os.path.exists(basedir) or not os.path.isdir(basedir): + continue + try: + shutil.rmtree(basedir) + except: + pass if old_ppath is not None: os.environ['PYTHONPATH'] = old_ppath else: del os.environ['PYTHONPATH'] + def test_setup_requires(self): + """Regression test for issue #318 + + Ensures that a package with setup_requires can be installed when + distribute is installed in the user site-packages without causing a + SandboxViolation. + """ + + test_setup_attrs = { + 'name': 'test_pkg', 'version': '0.0', + 'setup_requires': ['foobar'], + 'dependency_links': [os.path.abspath(self.dir)] + } + + test_pkg = os.path.join(self.dir, 'test_pkg') + test_setup_py = os.path.join(test_pkg, 'setup.py') + test_setup_cfg = os.path.join(test_pkg, 'setup.cfg') + os.mkdir(test_pkg) + + f = open(test_setup_py, 'w') + f.write(textwrap.dedent("""\ + import setuptools + setuptools.setup(**%r) + """ % test_setup_attrs)) + f.close() + + foobar_path = os.path.join(self.dir, 'foobar-0.1.tar.gz') + make_trivial_sdist( + foobar_path, + textwrap.dedent("""\ + import setuptools + setuptools.setup( + name='foobar', + version='0.1' + ) + """)) + + old_stdout = sys.stdout + old_stderr = sys.stderr + sys.stdout = StringIO() + sys.stderr = StringIO() + try: + reset_setup_stop_context( + lambda: run_setup(test_setup_py, ['install']) + ) + except SandboxViolation: + self.fail('Installation caused SandboxViolation') + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + + +class TestSetupRequires(unittest.TestCase): + + def test_setup_requires_honors_fetch_params(self): + """ + When easy_install installs a source distribution which specifies + setup_requires, it should honor the fetch parameters (such as + allow-hosts, index-url, and find-links). + """ + # set up a server which will simulate an alternate package index. + p_index = setuptools.tests.server.MockServer() + p_index.start() + netloc = 1 + p_index_loc = urlparse(p_index.url)[netloc] + if p_index_loc.endswith(':0'): + # Some platforms (Jython) don't find a port to which to bind, + # so skip this test for them. + return + + # I realize this is all-but-impossible to read, because it was + # ported from some well-factored, safe code using 'with'. If you + # need to maintain this code, consider making the changes in + # the parent revision (of this comment) and then port the changes + # back for Python 2.4 (or deprecate Python 2.4). + + def install(dist_file): + def install_at(temp_install_dir): + def install_env(): + ei_params = ['--index-url', p_index.url, + '--allow-hosts', p_index_loc, + '--exclude-scripts', '--install-dir', temp_install_dir, + dist_file] + def install_clean_reset(): + def install_clean_argv(): + # attempt to install the dist. It should fail because + # it doesn't exist. + self.assertRaises(SystemExit, + easy_install_pkg.main, ei_params) + argv_context(install_clean_argv, ['easy_install']) + reset_setup_stop_context(install_clean_reset) + environment_context(install_env, PYTHONPATH=temp_install_dir) + tempdir_context(install_at) + + # create an sdist that has a build-time dependency. + self.create_sdist(install) + + # there should have been two or three requests to the server + # (three happens on Python 3.3a) + self.assertTrue(2 <= len(p_index.requests) <= 3) + self.assertEqual(p_index.requests[0].path, '/does-not-exist/') + + def create_sdist(self, installer): + """ + Create an sdist with a setup_requires dependency (of something that + doesn't exist) and invoke installer on it. + """ + def build_sdist(dir): + dist_path = os.path.join(dir, 'distribute-test-fetcher-1.0.tar.gz') + make_trivial_sdist( + dist_path, + textwrap.dedent(""" + import setuptools + setuptools.setup( + name="distribute-test-fetcher", + version="1.0", + setup_requires = ['does-not-exist'], + ) + """).lstrip()) + installer(dist_path) + tempdir_context(build_sdist) + + +def make_trivial_sdist(dist_path, setup_py): + """Create a simple sdist tarball at dist_path, containing just a + setup.py, the contents of which are provided by the setup_py string. + """ + + setup_py_file = tarfile.TarInfo(name='setup.py') + try: + # Python 3 (StringIO gets converted to io module) + MemFile = BytesIO + except AttributeError: + MemFile = StringIO + setup_py_bytes = MemFile(setup_py.encode('utf-8')) + setup_py_file.size = len(setup_py_bytes.getvalue()) + dist = tarfile.open(dist_path, 'w:gz') + try: + dist.addfile(setup_py_file, fileobj=setup_py_bytes) + finally: + dist.close() + + +def tempdir_context(f, cd=lambda dir:None): + """ + Invoke f in the context + """ + temp_dir = tempfile.mkdtemp() + orig_dir = os.getcwd() + try: + cd(temp_dir) + f(temp_dir) + finally: + cd(orig_dir) + shutil.rmtree(temp_dir) + +def environment_context(f, **updates): + """ + Invoke f in the context + """ + old_env = os.environ.copy() + os.environ.update(updates) + try: + f() + finally: + for key in updates: + del os.environ[key] + os.environ.update(old_env) + +def argv_context(f, repl): + """ + Invoke f in the context + """ + old_argv = sys.argv[:] + sys.argv[:] = repl + try: + f() + finally: + sys.argv[:] = old_argv + +def reset_setup_stop_context(f): + """ + When the distribute tests are run using setup.py test, and then + one wants to invoke another setup() command (such as easy_install) + within those tests, it's necessary to reset the global variable + in distutils.core so that the setup() command will run naturally. + """ + setup_stop_after = distutils.core._setup_stop_after + distutils.core._setup_stop_after = None + try: + f() + finally: + distutils.core._setup_stop_after = setup_stop_after diff --git a/setuptools/tests/test_markerlib.py b/setuptools/tests/test_markerlib.py new file mode 100644 index 00000000..7ff2f584 --- /dev/null +++ b/setuptools/tests/test_markerlib.py @@ -0,0 +1,64 @@ +import os +import unittest +from setuptools.tests.py26compat import skipIf + +try: + import ast +except ImportError: + pass + +class TestMarkerlib(unittest.TestCase): + + @skipIf('ast' not in globals(), + "ast not available (Python < 2.6?)") + def test_markers(self): + from _markerlib import interpret, default_environment, compile + + os_name = os.name + + self.assert_(interpret("")) + + self.assert_(interpret("os.name != 'buuuu'")) + self.assert_(interpret("python_version > '1.0'")) + self.assert_(interpret("python_version < '5.0'")) + self.assert_(interpret("python_version <= '5.0'")) + self.assert_(interpret("python_version >= '1.0'")) + self.assert_(interpret("'%s' in os.name" % os_name)) + self.assert_(interpret("'buuuu' not in os.name")) + + self.assertFalse(interpret("os.name == 'buuuu'")) + self.assertFalse(interpret("python_version < '1.0'")) + self.assertFalse(interpret("python_version > '5.0'")) + self.assertFalse(interpret("python_version >= '5.0'")) + self.assertFalse(interpret("python_version <= '1.0'")) + self.assertFalse(interpret("'%s' not in os.name" % os_name)) + self.assertFalse(interpret("'buuuu' in os.name and python_version >= '5.0'")) + + environment = default_environment() + environment['extra'] = 'test' + self.assert_(interpret("extra == 'test'", environment)) + self.assertFalse(interpret("extra == 'doc'", environment)) + + def raises_nameError(): + try: + interpret("python.version == '42'") + except NameError: + pass + else: + raise Exception("Expected NameError") + + raises_nameError() + + def raises_syntaxError(): + try: + interpret("(x for x in (4,))") + except SyntaxError: + pass + else: + raise Exception("Expected SyntaxError") + + raises_syntaxError() + + statement = "python_version == '5'" + self.assertEqual(compile(statement).__doc__, statement) + diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py index cabbb48c..d9e50224 100644 --- a/setuptools/tests/test_packageindex.py +++ b/setuptools/tests/test_packageindex.py @@ -1,26 +1,27 @@ """Package Index Tests """ -# More would be better! import sys -import os, shutil, tempfile, unittest +import unittest import pkg_resources from setuptools.compat import urllib2, httplib, HTTPError +import distutils.errors import setuptools.package_index from setuptools.tests.server import IndexServer class TestPackageIndex(unittest.TestCase): - def test_bad_urls(self): + def test_bad_url_bad_port(self): index = setuptools.package_index.PackageIndex() url = 'http://127.0.0.1:0/nonesuch/test_package_index' try: v = index.open_url(url) except Exception: v = sys.exc_info()[1] - self.assert_(url in str(v)) + self.assertTrue(url in str(v)) else: - self.assert_(isinstance(v, HTTPError)) + self.assertTrue(isinstance(v, HTTPError)) + def test_bad_url_typo(self): # issue 16 # easy_install inquant.contentmirror.plone breaks because of a typo # in its home URL @@ -33,9 +34,14 @@ class TestPackageIndex(unittest.TestCase): v = index.open_url(url) except Exception: v = sys.exc_info()[1] - self.assert_(url in str(v)) + self.assertTrue(url in str(v)) else: - self.assert_(isinstance(v, HTTPError)) + self.assertTrue(isinstance(v, HTTPError)) + + def test_bad_url_bad_status_line(self): + index = setuptools.package_index.PackageIndex( + hosts=('www.example.com',) + ) def _urlopen(*args): raise httplib.BadStatusLine('line') @@ -48,20 +54,35 @@ class TestPackageIndex(unittest.TestCase): v = index.open_url(url) except Exception: v = sys.exc_info()[1] - self.assert_('line' in str(v)) + self.assertTrue('line' in str(v)) else: raise AssertionError('Should have raise here!') finally: urllib2.urlopen = old_urlopen + def test_bad_url_double_scheme(self): + """ + A bad URL with a double scheme should raise a DistutilsError. + """ + index = setuptools.package_index.PackageIndex( + hosts=('www.example.com',) + ) + # issue 20 url = 'http://http://svn.pythonpaste.org/Paste/wphp/trunk' try: index.open_url(url) - except Exception: - v = sys.exc_info()[1] - self.assert_('nonnumeric port' in str(v)) - + except distutils.errors.DistutilsError: + error = sys.exc_info()[1] + msg = unicode(error) + assert 'nonnumeric port' in msg or 'getaddrinfo failed' in msg or 'Name or service not known' in msg + return + raise RuntimeError("Did not raise") + + def test_bad_url_screwy_href(self): + index = setuptools.package_index.PackageIndex( + hosts=('www.example.com',) + ) # issue #160 if sys.version_info[0] == 2 and sys.version_info[1] == 7: @@ -71,13 +92,12 @@ class TestPackageIndex(unittest.TestCase): 'http://www.famfamfam.com/">') index.process_index(url, page) - def test_url_ok(self): index = setuptools.package_index.PackageIndex( hosts=('www.example.com',) ) url = 'file:///tmp/test_package_index' - self.assert_(index.url_ok(url, True)) + self.assertTrue(index.url_ok(url, True)) def test_links_priority(self): """ @@ -94,6 +114,10 @@ class TestPackageIndex(unittest.TestCase): is used -> Distribute should use the link from pypi, not the external one. """ + if sys.platform.startswith('java'): + # Skip this test on jython because binding to :0 fails + return + # start an index server server = IndexServer() server.start() @@ -106,11 +130,11 @@ class TestPackageIndex(unittest.TestCase): server.stop() # the distribution has been found - self.assert_('foobar' in pi) + self.assertTrue('foobar' in pi) # we have only one link, because links are compared without md5 - self.assert_(len(pi['foobar'])==1) + self.assertTrue(len(pi['foobar'])==1) # the link should be from the index - self.assert_('correct_md5' in pi['foobar'][0].location) + self.assertTrue('correct_md5' in pi['foobar'][0].location) def test_parse_bdist_wininst(self): self.assertEqual(setuptools.package_index.parse_bdist_wininst( @@ -121,5 +145,3 @@ class TestPackageIndex(unittest.TestCase): 'reportlab-2.5.win-amd64-py2.7.exe'), ('reportlab-2.5', '2.7', 'win-amd64')) self.assertEqual(setuptools.package_index.parse_bdist_wininst( 'reportlab-2.5.win-amd64.exe'), ('reportlab-2.5', None, 'win-amd64')) - - diff --git a/setuptools/tests/test_resources.py b/setuptools/tests/test_resources.py index 57536221..4b3d50a8 100644 --- a/setuptools/tests/test_resources.py +++ b/setuptools/tests/test_resources.py @@ -9,6 +9,16 @@ try: frozenset except NameError: from sets import ImmutableSet as frozenset +def safe_repr(obj, short=False): + """ copied from Python2.7""" + try: + result = repr(obj) + except Exception: + result = object.__repr__(obj) + if not short or len(result) < _MAX_LENGTH: + return result + return result[:_MAX_LENGTH] + ' [truncated]...' + class Metadata(EmptyProvider): """Mock object to return metadata as if from an on-disk distribution""" @@ -36,7 +46,7 @@ class DistroTests(TestCase): ad.add(Distribution.from_filename("FooPkg-1.2-py2.4.egg")) # Name is in there now - self.assert_(ad['FooPkg']) + self.assertTrue(ad['FooPkg']) # But only 1 package self.assertEqual(list(ad), ['foopkg']) @@ -219,7 +229,7 @@ class EntryPointTests(TestCase): self.assertEqual(ep.module_name,"setuptools.tests.test_resources") self.assertEqual(ep.attrs, ("EntryPointTests",)) self.assertEqual(ep.extras, ("x",)) - self.assert_(ep.load() is EntryPointTests) + self.assertTrue(ep.load() is EntryPointTests) self.assertEqual( str(ep), "foo = setuptools.tests.test_resources:EntryPointTests [x]" @@ -319,20 +329,20 @@ class RequirementsTests(TestCase): foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg") twist11 = Distribution.from_filename("Twisted-1.1.egg") twist12 = Distribution.from_filename("Twisted-1.2.egg") - self.assert_(parse_version('1.2') in r) - self.assert_(parse_version('1.1') not in r) - self.assert_('1.2' in r) - self.assert_('1.1' not in r) - self.assert_(foo_dist not in r) - self.assert_(twist11 not in r) - self.assert_(twist12 in r) + self.assertTrue(parse_version('1.2') in r) + self.assertTrue(parse_version('1.1') not in r) + self.assertTrue('1.2' in r) + self.assertTrue('1.1' not in r) + self.assertTrue(foo_dist not in r) + self.assertTrue(twist11 not in r) + self.assertTrue(twist12 in r) def testAdvancedContains(self): r, = parse_requirements("Foo>=1.2,<=1.3,==1.9,>2.0,!=2.5,<3.0,==4.5") for v in ('1.2','1.2.2','1.3','1.9','2.0.1','2.3','2.6','3.0c1','4.5'): - self.assert_(v in r, (v,r)) + self.assertTrue(v in r, (v,r)) for v in ('1.2c1','1.3.1','1.5','1.9.1','2.0','2.5','3.0','4.0'): - self.assert_(v not in r, (v,r)) + self.assertTrue(v not in r, (v,r)) def testOptionsAndHashing(self): @@ -354,14 +364,14 @@ class RequirementsTests(TestCase): r2 = Requirement.parse("foo!=0.3a4") d = Distribution.from_filename - self.assert_(d("foo-0.3a4.egg") not in r1) - self.assert_(d("foo-0.3a1.egg") not in r1) - self.assert_(d("foo-0.3a4.egg") not in r2) + self.assertTrue(d("foo-0.3a4.egg") not in r1) + self.assertTrue(d("foo-0.3a1.egg") not in r1) + self.assertTrue(d("foo-0.3a4.egg") not in r2) - self.assert_(d("foo-0.3a2.egg") in r1) - self.assert_(d("foo-0.3a2.egg") in r2) - self.assert_(d("foo-0.3a3.egg") in r2) - self.assert_(d("foo-0.3a5.egg") in r2) + self.assertTrue(d("foo-0.3a2.egg") in r1) + self.assertTrue(d("foo-0.3a2.egg") in r2) + self.assertTrue(d("foo-0.3a3.egg") in r2) + self.assertTrue(d("foo-0.3a5.egg") in r2) def testDistributeSetuptoolsOverride(self): # Plain setuptools or distribute mean we return distribute. @@ -468,27 +478,29 @@ class ParseTests(TestCase): p1, p2 = parse_version(s1),parse_version(s2) self.assertEqual(p1,p2, (s1,s2,p1,p2)) - c('1.2-rc1', '1.2rc1') c('0.4', '0.4.0') c('0.4.0.0', '0.4.0') c('0.4.0-0', '0.4-0') c('0pl1', '0.0pl1') c('0pre1', '0.0c1') c('0.0.0preview1', '0c1') - c('0.0c1', '0-rc1') + c('0.0c1', '0rc1') c('1.2a1', '1.2.a.1'); c('1.2...a', '1.2a') def testVersionOrdering(self): def c(s1,s2): p1, p2 = parse_version(s1),parse_version(s2) - self.assert_(p1<p2, (s1,s2,p1,p2)) + self.assertTrue(p1<p2, (s1,s2,p1,p2)) c('2.1','2.1.1') + c('2.1.0','2.10') c('2a1','2b0') + c('2b1','2c0') c('2a1','2.1') c('2.3a1', '2.3') c('2.1-1', '2.1-2') c('2.1-1', '2.1.1') + c('2.1', '2.1.1-1') c('2.1', '2.1pl4') c('2.1a0-20040501', '2.1') c('1.1', '02.1') @@ -499,8 +511,20 @@ class ParseTests(TestCase): c('0.4', '4.0') c('0.0.4', '0.4.0') c('0pl1', '0.4pl1') - c('2.1.0-rc1','2.1.0') c('2.1dev','2.1a0') + c('2.1.0rc1','2.1.0') + c('2.1.0','2.1.0-rc0') + c('2.1.0','2.1.0-a') + c('2.1.0','2.1.0-alpha') + c('2.1.0','2.1.0-foo') + c('1.0','1.0-1') + c('1.0-1','1.0.1') + c('1.0a','1.0b') + c('1.0dev','1.0rc1') + c('1.0pre','1.0') + c('1.0pre','1.0') + c('1.0a','1.0-a') + c('1.0rc1','1.0-rc1') torture =""" 0.80.1-3 0.80.1-2 0.80.1-1 0.79.9999+0.80.0pre4-1 @@ -554,12 +578,12 @@ class ScriptHeaderTests(TestCase): self.assertEqual(get_script_header('#!/usr/bin/python -x', executable=exe), '#!%s -x\n' % exe) - self.assert_('Unable to adapt shebang line' in sys.stdout.getvalue()) + self.assertTrue('Unable to adapt shebang line' in sys.stdout.getvalue()) sys.stdout = sys.stderr = StringIO() self.assertEqual(get_script_header('#!/usr/bin/python', executable=self.non_ascii_exe), '#!%s -x\n' % self.non_ascii_exe) - self.assert_('Unable to adapt shebang line' in sys.stdout.getvalue()) + self.assertTrue('Unable to adapt shebang line' in sys.stdout.getvalue()) finally: sys.platform = platform sys.stdout = stdout @@ -581,6 +605,13 @@ class NamespaceTests(TestCase): pkg_resources._namespace_packages = self._ns_pkgs.copy() sys.path = self._prev_sys_path[:] + def _assertIn(self, member, container): + """ assertIn and assertTrue does not exist in Python2.3""" + if member not in container: + standardMsg = '%s not found in %s' % (safe_repr(member), + safe_repr(container)) + self.fail(self._formatMessage(msg, standardMsg)) + def test_two_levels_deep(self): """ Test nested namespace packages @@ -604,13 +635,13 @@ class NamespaceTests(TestCase): pkg2_init.write(ns_str) pkg2_init.close() import pkg1 - self.assertTrue("pkg1" in pkg_resources._namespace_packages.keys()) + self._assertIn("pkg1", pkg_resources._namespace_packages.keys()) try: import pkg1.pkg2 except ImportError: self.fail("Distribute tried to import the parent namespace package") # check the _namespace_packages dict - self.assertTrue("pkg1.pkg2" in pkg_resources._namespace_packages.keys()) + self._assertIn("pkg1.pkg2", pkg_resources._namespace_packages.keys()) self.assertEqual(pkg_resources._namespace_packages["pkg1"], ["pkg1.pkg2"]) # check the __path__ attribute contains both paths self.assertEqual(pkg1.pkg2.__path__, [ diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py new file mode 100644 index 00000000..7e2f0a49 --- /dev/null +++ b/setuptools/tests/test_sdist.py @@ -0,0 +1,170 @@ +# -*- coding: utf-8 -*- +"""sdist tests""" + + +import os +import shutil +import sys +import tempfile +import unittest +from StringIO import StringIO + + +from setuptools.command.sdist import sdist +from setuptools.dist import Distribution + + +SETUP_ATTRS = { + 'name': 'sdist_test', + 'version': '0.0', + 'packages': ['sdist_test'], + 'package_data': {'sdist_test': ['*.txt']} +} + + +SETUP_PY = """\ +from setuptools import setup + +setup(**%r) +""" % SETUP_ATTRS + + +class TestSdistTest(unittest.TestCase): + def setUp(self): + self.temp_dir = tempfile.mkdtemp() + f = open(os.path.join(self.temp_dir, 'setup.py'), 'w') + f.write(SETUP_PY) + f.close() + # Set up the rest of the test package + test_pkg = os.path.join(self.temp_dir, 'sdist_test') + os.mkdir(test_pkg) + # *.rst was not included in package_data, so c.rst should not be + # automatically added to the manifest when not under version control + for fname in ['__init__.py', 'a.txt', 'b.txt', 'c.rst']: + # Just touch the files; their contents are irrelevant + open(os.path.join(test_pkg, fname), 'w').close() + + self.old_cwd = os.getcwd() + os.chdir(self.temp_dir) + + def tearDown(self): + os.chdir(self.old_cwd) + shutil.rmtree(self.temp_dir) + + def test_package_data_in_sdist(self): + """Regression test for pull request #4: ensures that files listed in + package_data are included in the manifest even if they're not added to + version control. + """ + + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + cmd = sdist(dist) + cmd.ensure_finalized() + + # squelch output + old_stdout = sys.stdout + old_stderr = sys.stderr + sys.stdout = StringIO() + sys.stderr = StringIO() + try: + cmd.run() + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + + manifest = cmd.filelist.files + + self.assertTrue(os.path.join('sdist_test', 'a.txt') in manifest) + self.assertTrue(os.path.join('sdist_test', 'b.txt') in manifest) + self.assertTrue(os.path.join('sdist_test', 'c.rst') not in manifest) + + def test_filelist_is_fully_composed(self): + # Test for #303. Requires HFS Plus to fail. + + # Add file with non-ASCII filename + filename = os.path.join('sdist_test', 'smörbröd.py') + open(filename, 'w').close() + + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + cmd = sdist(dist) + cmd.ensure_finalized() + + # squelch output + old_stdout = sys.stdout + old_stderr = sys.stderr + sys.stdout = StringIO() + sys.stderr = StringIO() + try: + cmd.run() + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + + self.assertTrue(filename in cmd.filelist.files) + + def test_manifest_is_written_in_utf8(self): + # Test for #303. + + # Add file with non-ASCII filename + filename = os.path.join('sdist_test', 'smörbröd.py') + open(filename, 'w').close() + + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + cmd = sdist(dist) + cmd.ensure_finalized() + + # squelch output + old_stdout = sys.stdout + old_stderr = sys.stderr + sys.stdout = StringIO() + sys.stderr = StringIO() + try: + cmd.run() + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + + manifest = open(os.path.join('sdist_test.egg-info', 'SOURCES.txt'), 'rbU') + contents = manifest.read() + manifest.close() + self.assertTrue(len(contents)) + + # This must not fail: + contents.decode('UTF-8') + + def test_manifest_is_read_in_utf8(self): + # Test for #303. + + # Add file with non-ASCII filename + filename = os.path.join('sdist_test', 'smörbröd.py') + open(filename, 'w').close() + + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + cmd = sdist(dist) + cmd.ensure_finalized() + + # squelch output + old_stdout = sys.stdout + old_stderr = sys.stderr + sys.stdout = StringIO() + sys.stderr = StringIO() + try: + cmd.run() + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + + cmd.filelist.files = [] + cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') + cmd.read_manifest() + + self.assertTrue(filename in cmd.filelist.files) + + +def test_suite(): + return unittest.defaultTestLoader.loadTestsFromName(__name__) + diff --git a/setuptools/tests/test_test.py b/setuptools/tests/test_test.py new file mode 100644 index 00000000..ad7cbd0f --- /dev/null +++ b/setuptools/tests/test_test.py @@ -0,0 +1,124 @@ +# -*- coding: UTF-8 -*- + +"""develop tests +""" +import sys +import os, shutil, tempfile, unittest +import tempfile +import site +from StringIO import StringIO + +from distutils.errors import DistutilsError +from setuptools.command.test import test +from setuptools.command import easy_install as easy_install_pkg +from setuptools.dist import Distribution + +SETUP_PY = """\ +from setuptools import setup + +setup(name='foo', + packages=['name', 'name.space', 'name.space.tests'], + namespace_packages=['name'], + test_suite='name.space.tests.test_suite', +) +""" + +NS_INIT = """# -*- coding: Latin-1 -*- +# Söme Arbiträry Ünicode to test Issüé 310 +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) +""" +# Make sure this is Latin-1 binary, before writing: +if sys.version_info < (3,): + NS_INIT = NS_INIT.decode('UTF-8') +NS_INIT = NS_INIT.encode('Latin-1') + +TEST_PY = """import unittest + +class TestTest(unittest.TestCase): + def test_test(self): + print "Foo" # Should fail under Python 3 unless 2to3 is used + +test_suite = unittest.makeSuite(TestTest) +""" + +class TestTestTest(unittest.TestCase): + + def setUp(self): + if sys.version < "2.6" or hasattr(sys, 'real_prefix'): + return + + # Directory structure + self.dir = tempfile.mkdtemp() + os.mkdir(os.path.join(self.dir, 'name')) + os.mkdir(os.path.join(self.dir, 'name', 'space')) + os.mkdir(os.path.join(self.dir, 'name', 'space', 'tests')) + # setup.py + setup = os.path.join(self.dir, 'setup.py') + f = open(setup, 'wt') + f.write(SETUP_PY) + f.close() + self.old_cwd = os.getcwd() + # name/__init__.py + init = os.path.join(self.dir, 'name', '__init__.py') + f = open(init, 'wb') + f.write(NS_INIT) + f.close() + # name/space/__init__.py + init = os.path.join(self.dir, 'name', 'space', '__init__.py') + f = open(init, 'wt') + f.write('#empty\n') + f.close() + # name/space/tests/__init__.py + init = os.path.join(self.dir, 'name', 'space', 'tests', '__init__.py') + f = open(init, 'wt') + f.write(TEST_PY) + f.close() + + os.chdir(self.dir) + self.old_base = site.USER_BASE + site.USER_BASE = tempfile.mkdtemp() + self.old_site = site.USER_SITE + site.USER_SITE = tempfile.mkdtemp() + + def tearDown(self): + if sys.version < "2.6" or hasattr(sys, 'real_prefix'): + return + + os.chdir(self.old_cwd) + shutil.rmtree(self.dir) + shutil.rmtree(site.USER_BASE) + shutil.rmtree(site.USER_SITE) + site.USER_BASE = self.old_base + site.USER_SITE = self.old_site + + def test_test(self): + if sys.version < "2.6" or hasattr(sys, 'real_prefix'): + return + + dist = Distribution(dict( + name='foo', + packages=['name', 'name.space', 'name.space.tests'], + namespace_packages=['name'], + test_suite='name.space.tests.test_suite', + use_2to3=True, + )) + dist.script_name = 'setup.py' + cmd = test(dist) + cmd.user = 1 + cmd.ensure_finalized() + cmd.install_dir = site.USER_SITE + cmd.user = 1 + old_stdout = sys.stdout + sys.stdout = StringIO() + try: + try: # try/except/finally doesn't work in Python 2.4, so we need nested try-statements. + cmd.run() + except SystemExit: # The test runner calls sys.exit, stop that making an error. + pass + finally: + sys.stdout = old_stdout +
\ No newline at end of file |