Home | History | Annotate | Download | only in tests
      1 """Tests for distutils.core."""
      2 
      3 import io
      4 import distutils.core
      5 import os
      6 import shutil
      7 import sys
      8 import test.support
      9 from test.support import captured_stdout, run_unittest
     10 import unittest
     11 from distutils.tests import support
     12 from distutils import log
     13 
     14 # setup script that uses __file__
     15 setup_using___file__ = """\
     16 
     17 __file__
     18 
     19 from distutils.core import setup
     20 setup()
     21 """
     22 
     23 setup_prints_cwd = """\
     24 
     25 import os
     26 print(os.getcwd())
     27 
     28 from distutils.core import setup
     29 setup()
     30 """
     31 
     32 setup_does_nothing = """\
     33 from distutils.core import setup
     34 setup()
     35 """
     36 
     37 
     38 setup_defines_subclass = """\
     39 from distutils.core import setup
     40 from distutils.command.install import install as _install
     41 
     42 class install(_install):
     43     sub_commands = _install.sub_commands + ['cmd']
     44 
     45 setup(cmdclass={'install': install})
     46 """
     47 
     48 class CoreTestCase(support.EnvironGuard, unittest.TestCase):
     49 
     50     def setUp(self):
     51         super(CoreTestCase, self).setUp()
     52         self.old_stdout = sys.stdout
     53         self.cleanup_testfn()
     54         self.old_argv = sys.argv, sys.argv[:]
     55         self.addCleanup(log.set_threshold, log._global_log.threshold)
     56 
     57     def tearDown(self):
     58         sys.stdout = self.old_stdout
     59         self.cleanup_testfn()
     60         sys.argv = self.old_argv[0]
     61         sys.argv[:] = self.old_argv[1]
     62         super(CoreTestCase, self).tearDown()
     63 
     64     def cleanup_testfn(self):
     65         path = test.support.TESTFN
     66         if os.path.isfile(path):
     67             os.remove(path)
     68         elif os.path.isdir(path):
     69             shutil.rmtree(path)
     70 
     71     def write_setup(self, text, path=test.support.TESTFN):
     72         f = open(path, "w")
     73         try:
     74             f.write(text)
     75         finally:
     76             f.close()
     77         return path
     78 
     79     def test_run_setup_provides_file(self):
     80         # Make sure the script can use __file__; if that's missing, the test
     81         # setup.py script will raise NameError.
     82         distutils.core.run_setup(
     83             self.write_setup(setup_using___file__))
     84 
     85     def test_run_setup_preserves_sys_argv(self):
     86         # Make sure run_setup does not clobber sys.argv
     87         argv_copy = sys.argv.copy()
     88         distutils.core.run_setup(
     89             self.write_setup(setup_does_nothing))
     90         self.assertEqual(sys.argv, argv_copy)
     91 
     92     def test_run_setup_defines_subclass(self):
     93         # Make sure the script can use __file__; if that's missing, the test
     94         # setup.py script will raise NameError.
     95         dist = distutils.core.run_setup(
     96             self.write_setup(setup_defines_subclass))
     97         install = dist.get_command_obj('install')
     98         self.assertIn('cmd', install.sub_commands)
     99 
    100     def test_run_setup_uses_current_dir(self):
    101         # This tests that the setup script is run with the current directory
    102         # as its own current directory; this was temporarily broken by a
    103         # previous patch when TESTFN did not use the current directory.
    104         sys.stdout = io.StringIO()
    105         cwd = os.getcwd()
    106 
    107         # Create a directory and write the setup.py file there:
    108         os.mkdir(test.support.TESTFN)
    109         setup_py = os.path.join(test.support.TESTFN, "setup.py")
    110         distutils.core.run_setup(
    111             self.write_setup(setup_prints_cwd, path=setup_py))
    112 
    113         output = sys.stdout.getvalue()
    114         if output.endswith("\n"):
    115             output = output[:-1]
    116         self.assertEqual(cwd, output)
    117 
    118     def test_debug_mode(self):
    119         # this covers the code called when DEBUG is set
    120         sys.argv = ['setup.py', '--name']
    121         with captured_stdout() as stdout:
    122             distutils.core.setup(name='bar')
    123         stdout.seek(0)
    124         self.assertEqual(stdout.read(), 'bar\n')
    125 
    126         distutils.core.DEBUG = True
    127         try:
    128             with captured_stdout() as stdout:
    129                 distutils.core.setup(name='bar')
    130         finally:
    131             distutils.core.DEBUG = False
    132         stdout.seek(0)
    133         wanted = "options (after parsing config files):\n"
    134         self.assertEqual(stdout.readlines()[0], wanted)
    135 
    136 def test_suite():
    137     return unittest.makeSuite(CoreTestCase)
    138 
    139 if __name__ == "__main__":
    140     run_unittest(test_suite())
    141