Imported Upstream version 1.2.1
[platform/upstream/python-nose.git] / nose / commands.py
1 """
2 nosetests setuptools command
3 ----------------------------
4
5 The easiest way to run tests with nose is to use the `nosetests` setuptools
6 command::
7
8   python setup.py nosetests
9
10 This command has one *major* benefit over the standard `test` command: *all
11 nose plugins are supported*.
12
13 To configure the `nosetests` command, add a [nosetests] section to your
14 setup.cfg. The [nosetests] section can contain any command line arguments that
15 nosetests supports. The differences between issuing an option on the command
16 line and adding it to setup.cfg are:
17
18 * In setup.cfg, the -- prefix must be excluded
19 * In setup.cfg, command line flags that take no arguments must be given an
20   argument flag (1, T or TRUE for active, 0, F or FALSE for inactive)
21
22 Here's an example [nosetests] setup.cfg section::
23
24   [nosetests]
25   verbosity=1
26   detailed-errors=1
27   with-coverage=1
28   cover-package=nose
29   debug=nose.loader
30   pdb=1
31   pdb-failures=1
32
33 If you commonly run nosetests with a large number of options, using
34 the nosetests setuptools command and configuring with setup.cfg can
35 make running your tests much less tedious. (Note that the same options
36 and format supported in setup.cfg are supported in all other config
37 files, and the nosetests script will also load config files.)
38
39 Another reason to run tests with the command is that the command will
40 install packages listed in your `tests_require`, as well as doing a
41 complete build of your package before running tests. For packages with
42 dependencies or that build C extensions, using the setuptools command
43 can be more convenient than building by hand and running the nosetests
44 script.
45
46 Bootstrapping
47 -------------
48
49 If you are distributing your project and want users to be able to run tests
50 without having to install nose themselves, add nose to the setup_requires
51 section of your setup()::
52
53   setup(
54       # ...
55       setup_requires=['nose>=1.0']
56       )
57
58 This will direct setuptools to download and activate nose during the setup
59 process, making the ``nosetests`` command available.
60
61 """
62 try:
63     from setuptools import Command
64 except ImportError:
65     Command = nosetests = None
66 else:
67     from nose.config import Config, option_blacklist, user_config_files, \
68         flag, _bool
69     from nose.core import TestProgram
70     from nose.plugins import DefaultPluginManager
71
72
73     def get_user_options(parser):
74         """convert a optparse option list into a distutils option tuple list"""
75         opt_list = []
76         for opt in parser.option_list:
77             if opt._long_opts[0][2:] in option_blacklist: 
78                 continue
79             long_name = opt._long_opts[0][2:]
80             if opt.action not in ('store_true', 'store_false'):
81                 long_name = long_name + "="
82             short_name = None
83             if opt._short_opts:
84                 short_name =  opt._short_opts[0][1:]
85             opt_list.append((long_name, short_name, opt.help or ""))
86         return opt_list
87
88
89     class nosetests(Command):
90         description = "Run unit tests using nosetests"
91         __config = Config(files=user_config_files(),
92                           plugins=DefaultPluginManager())
93         __parser = __config.getParser()
94         user_options = get_user_options(__parser)
95
96         def initialize_options(self):
97             """create the member variables, but change hyphens to
98             underscores
99             """
100
101             self.option_to_cmds = {}
102             for opt in self.__parser.option_list:
103                 cmd_name = opt._long_opts[0][2:]
104                 option_name = cmd_name.replace('-', '_')
105                 self.option_to_cmds[option_name] = cmd_name
106                 setattr(self, option_name, None)
107             self.attr  = None
108
109         def finalize_options(self):
110             """nothing to do here"""
111             pass
112
113         def run(self):
114             """ensure tests are capable of being run, then
115             run nose.main with a reconstructed argument list"""
116             if getattr(self.distribution, 'use_2to3', False):
117                 # If we run 2to3 we can not do this inplace:
118
119                 # Ensure metadata is up-to-date
120                 self.reinitialize_command('build_py', inplace=0)
121                 self.run_command('build_py')
122                 bpy_cmd = self.get_finalized_command("build_py")
123                 build_path = bpy_cmd.build_lib
124
125                 # Build extensions
126                 self.reinitialize_command('egg_info', egg_base=build_path)
127                 self.run_command('egg_info')
128
129                 self.reinitialize_command('build_ext', inplace=0)
130                 self.run_command('build_ext')
131             else:
132                 self.run_command('egg_info')
133
134                 # Build extensions in-place
135                 self.reinitialize_command('build_ext', inplace=1)
136                 self.run_command('build_ext')
137
138             if self.distribution.install_requires:
139                 self.distribution.fetch_build_eggs(
140                     self.distribution.install_requires)
141             if self.distribution.tests_require:
142                 self.distribution.fetch_build_eggs(
143                     self.distribution.tests_require)
144
145             ei_cmd = self.get_finalized_command("egg_info")
146             argv = ['nosetests', ei_cmd.egg_base] 
147             for (option_name, cmd_name) in self.option_to_cmds.items():
148                 if option_name in option_blacklist:
149                     continue
150                 value = getattr(self, option_name)
151                 if value is not None:
152                     argv.extend(
153                         self.cfgToArg(option_name.replace('_', '-'), value))
154             TestProgram(argv=argv, config=self.__config)
155
156         def cfgToArg(self, optname, value):
157             argv = []
158             if flag(value):
159                 if _bool(value):
160                     argv.append('--' + optname)
161             else:
162                 argv.extend(['--' + optname, value])
163             return argv