8ab7e9fc310d29a1ebb54025fc1b1fe7e959c785
[profile/ivi/python.git] / Lib / distutils / tests / test_dist.py
1 # -*- coding: utf8 -*-
2
3 """Tests for distutils.dist."""
4 import os
5 import StringIO
6 import sys
7 import unittest
8 import warnings
9 import textwrap
10
11 from distutils.dist import Distribution, fix_help_options, DistributionMetadata
12 from distutils.cmd import Command
13 import distutils.dist
14 from test.test_support import TESTFN, captured_stdout
15 from distutils.tests import support
16
17 class test_dist(Command):
18     """Sample distutils extension command."""
19
20     user_options = [
21         ("sample-option=", "S", "help text"),
22         ]
23
24     def initialize_options(self):
25         self.sample_option = None
26
27
28 class TestDistribution(Distribution):
29     """Distribution subclasses that avoids the default search for
30     configuration files.
31
32     The ._config_files attribute must be set before
33     .parse_config_files() is called.
34     """
35
36     def find_config_files(self):
37         return self._config_files
38
39
40 class DistributionTestCase(support.TempdirManager,
41                            support.LoggingSilencer,
42                            support.EnvironGuard,
43                            unittest.TestCase):
44
45     def setUp(self):
46         super(DistributionTestCase, self).setUp()
47         self.argv = sys.argv, sys.argv[:]
48         del sys.argv[1:]
49
50     def tearDown(self):
51         sys.argv = self.argv[0]
52         sys.argv[:] = self.argv[1]
53         super(DistributionTestCase, self).tearDown()
54
55     def create_distribution(self, configfiles=()):
56         d = TestDistribution()
57         d._config_files = configfiles
58         d.parse_config_files()
59         d.parse_command_line()
60         return d
61
62     def test_debug_mode(self):
63         with open(TESTFN, "w") as f:
64             f.write("[global]")
65             f.write("command_packages = foo.bar, splat")
66
67         files = [TESTFN]
68         sys.argv.append("build")
69
70         with captured_stdout() as stdout:
71             self.create_distribution(files)
72         stdout.seek(0)
73         self.assertEqual(stdout.read(), '')
74         distutils.dist.DEBUG = True
75         try:
76             with captured_stdout() as stdout:
77                 self.create_distribution(files)
78             stdout.seek(0)
79             self.assertEqual(stdout.read(), '')
80         finally:
81             distutils.dist.DEBUG = False
82
83     def test_command_packages_unspecified(self):
84         sys.argv.append("build")
85         d = self.create_distribution()
86         self.assertEqual(d.get_command_packages(), ["distutils.command"])
87
88     def test_command_packages_cmdline(self):
89         from distutils.tests.test_dist import test_dist
90         sys.argv.extend(["--command-packages",
91                          "foo.bar,distutils.tests",
92                          "test_dist",
93                          "-Ssometext",
94                          ])
95         d = self.create_distribution()
96         # let's actually try to load our test command:
97         self.assertEqual(d.get_command_packages(),
98                          ["distutils.command", "foo.bar", "distutils.tests"])
99         cmd = d.get_command_obj("test_dist")
100         self.assertTrue(isinstance(cmd, test_dist))
101         self.assertEqual(cmd.sample_option, "sometext")
102
103     def test_command_packages_configfile(self):
104         sys.argv.append("build")
105         self.addCleanup(os.unlink, TESTFN)
106         f = open(TESTFN, "w")
107         try:
108             print >>f, "[global]"
109             print >>f, "command_packages = foo.bar, splat"
110         finally:
111             f.close()
112
113         d = self.create_distribution([TESTFN])
114         self.assertEqual(d.get_command_packages(),
115                          ["distutils.command", "foo.bar", "splat"])
116
117         # ensure command line overrides config:
118         sys.argv[1:] = ["--command-packages", "spork", "build"]
119         d = self.create_distribution([TESTFN])
120         self.assertEqual(d.get_command_packages(),
121                          ["distutils.command", "spork"])
122
123         # Setting --command-packages to '' should cause the default to
124         # be used even if a config file specified something else:
125         sys.argv[1:] = ["--command-packages", "", "build"]
126         d = self.create_distribution([TESTFN])
127         self.assertEqual(d.get_command_packages(), ["distutils.command"])
128
129     def test_write_pkg_file(self):
130         # Check DistributionMetadata handling of Unicode fields
131         tmp_dir = self.mkdtemp()
132         my_file = os.path.join(tmp_dir, 'f')
133         klass = Distribution
134
135         dist = klass(attrs={'author': u'Mister Café',
136                             'name': 'my.package',
137                             'maintainer': u'Café Junior',
138                             'description': u'Café torréfié',
139                             'long_description': u'Héhéhé'})
140
141
142         # let's make sure the file can be written
143         # with Unicode fields. they are encoded with
144         # PKG_INFO_ENCODING
145         dist.metadata.write_pkg_file(open(my_file, 'w'))
146
147         # regular ascii is of course always usable
148         dist = klass(attrs={'author': 'Mister Cafe',
149                             'name': 'my.package',
150                             'maintainer': 'Cafe Junior',
151                             'description': 'Cafe torrefie',
152                             'long_description': 'Hehehe'})
153
154         my_file2 = os.path.join(tmp_dir, 'f2')
155         dist.metadata.write_pkg_file(open(my_file, 'w'))
156
157     def test_empty_options(self):
158         # an empty options dictionary should not stay in the
159         # list of attributes
160         klass = Distribution
161
162         # catching warnings
163         warns = []
164         def _warn(msg):
165             warns.append(msg)
166
167         old_warn = warnings.warn
168         warnings.warn = _warn
169         try:
170             dist = klass(attrs={'author': 'xxx',
171                                 'name': 'xxx',
172                                 'version': 'xxx',
173                                 'url': 'xxxx',
174                                 'options': {}})
175         finally:
176             warnings.warn = old_warn
177
178         self.assertEqual(len(warns), 0)
179
180     def test_finalize_options(self):
181
182         attrs = {'keywords': 'one,two',
183                  'platforms': 'one,two'}
184
185         dist = Distribution(attrs=attrs)
186         dist.finalize_options()
187
188         # finalize_option splits platforms and keywords
189         self.assertEqual(dist.metadata.platforms, ['one', 'two'])
190         self.assertEqual(dist.metadata.keywords, ['one', 'two'])
191
192     def test_get_command_packages(self):
193         dist = Distribution()
194         self.assertEqual(dist.command_packages, None)
195         cmds = dist.get_command_packages()
196         self.assertEqual(cmds, ['distutils.command'])
197         self.assertEqual(dist.command_packages,
198                          ['distutils.command'])
199
200         dist.command_packages = 'one,two'
201         cmds = dist.get_command_packages()
202         self.assertEqual(cmds, ['distutils.command', 'one', 'two'])
203
204
205     def test_announce(self):
206         # make sure the level is known
207         dist = Distribution()
208         args = ('ok',)
209         kwargs = {'level': 'ok2'}
210         self.assertRaises(ValueError, dist.announce, args, kwargs)
211
212     def test_find_config_files_disable(self):
213         # Ticket #1180: Allow user to disable their home config file.
214         temp_home = self.mkdtemp()
215         if os.name == 'posix':
216             user_filename = os.path.join(temp_home, ".pydistutils.cfg")
217         else:
218             user_filename = os.path.join(temp_home, "pydistutils.cfg")
219
220         with open(user_filename, 'w') as f:
221             f.write('[distutils]\n')
222
223         def _expander(path):
224             return temp_home
225
226         old_expander = os.path.expanduser
227         os.path.expanduser = _expander
228         try:
229             d = distutils.dist.Distribution()
230             all_files = d.find_config_files()
231
232             d = distutils.dist.Distribution(attrs={'script_args':
233                                             ['--no-user-cfg']})
234             files = d.find_config_files()
235         finally:
236             os.path.expanduser = old_expander
237
238         # make sure --no-user-cfg disables the user cfg file
239         self.assertEqual(len(all_files)-1, len(files))
240
241
242 class MetadataTestCase(support.TempdirManager, support.EnvironGuard,
243                        unittest.TestCase):
244
245     def setUp(self):
246         super(MetadataTestCase, self).setUp()
247         self.argv = sys.argv, sys.argv[:]
248
249     def tearDown(self):
250         sys.argv = self.argv[0]
251         sys.argv[:] = self.argv[1]
252         super(MetadataTestCase, self).tearDown()
253
254     def test_simple_metadata(self):
255         attrs = {"name": "package",
256                  "version": "1.0"}
257         dist = Distribution(attrs)
258         meta = self.format_metadata(dist)
259         self.assertTrue("Metadata-Version: 1.0" in meta)
260         self.assertTrue("provides:" not in meta.lower())
261         self.assertTrue("requires:" not in meta.lower())
262         self.assertTrue("obsoletes:" not in meta.lower())
263
264     def test_provides(self):
265         attrs = {"name": "package",
266                  "version": "1.0",
267                  "provides": ["package", "package.sub"]}
268         dist = Distribution(attrs)
269         self.assertEqual(dist.metadata.get_provides(),
270                          ["package", "package.sub"])
271         self.assertEqual(dist.get_provides(),
272                          ["package", "package.sub"])
273         meta = self.format_metadata(dist)
274         self.assertTrue("Metadata-Version: 1.1" in meta)
275         self.assertTrue("requires:" not in meta.lower())
276         self.assertTrue("obsoletes:" not in meta.lower())
277
278     def test_provides_illegal(self):
279         self.assertRaises(ValueError, Distribution,
280                           {"name": "package",
281                            "version": "1.0",
282                            "provides": ["my.pkg (splat)"]})
283
284     def test_requires(self):
285         attrs = {"name": "package",
286                  "version": "1.0",
287                  "requires": ["other", "another (==1.0)"]}
288         dist = Distribution(attrs)
289         self.assertEqual(dist.metadata.get_requires(),
290                          ["other", "another (==1.0)"])
291         self.assertEqual(dist.get_requires(),
292                          ["other", "another (==1.0)"])
293         meta = self.format_metadata(dist)
294         self.assertTrue("Metadata-Version: 1.1" in meta)
295         self.assertTrue("provides:" not in meta.lower())
296         self.assertTrue("Requires: other" in meta)
297         self.assertTrue("Requires: another (==1.0)" in meta)
298         self.assertTrue("obsoletes:" not in meta.lower())
299
300     def test_requires_illegal(self):
301         self.assertRaises(ValueError, Distribution,
302                           {"name": "package",
303                            "version": "1.0",
304                            "requires": ["my.pkg (splat)"]})
305
306     def test_obsoletes(self):
307         attrs = {"name": "package",
308                  "version": "1.0",
309                  "obsoletes": ["other", "another (<1.0)"]}
310         dist = Distribution(attrs)
311         self.assertEqual(dist.metadata.get_obsoletes(),
312                          ["other", "another (<1.0)"])
313         self.assertEqual(dist.get_obsoletes(),
314                          ["other", "another (<1.0)"])
315         meta = self.format_metadata(dist)
316         self.assertTrue("Metadata-Version: 1.1" in meta)
317         self.assertTrue("provides:" not in meta.lower())
318         self.assertTrue("requires:" not in meta.lower())
319         self.assertTrue("Obsoletes: other" in meta)
320         self.assertTrue("Obsoletes: another (<1.0)" in meta)
321
322     def test_obsoletes_illegal(self):
323         self.assertRaises(ValueError, Distribution,
324                           {"name": "package",
325                            "version": "1.0",
326                            "obsoletes": ["my.pkg (splat)"]})
327
328     def format_metadata(self, dist):
329         sio = StringIO.StringIO()
330         dist.metadata.write_pkg_file(sio)
331         return sio.getvalue()
332
333     def test_custom_pydistutils(self):
334         # fixes #2166
335         # make sure pydistutils.cfg is found
336         if os.name == 'posix':
337             user_filename = ".pydistutils.cfg"
338         else:
339             user_filename = "pydistutils.cfg"
340
341         temp_dir = self.mkdtemp()
342         user_filename = os.path.join(temp_dir, user_filename)
343         f = open(user_filename, 'w')
344         try:
345             f.write('.')
346         finally:
347             f.close()
348
349         try:
350             dist = Distribution()
351
352             # linux-style
353             if sys.platform in ('linux', 'darwin'):
354                 os.environ['HOME'] = temp_dir
355                 files = dist.find_config_files()
356                 self.assertTrue(user_filename in files)
357
358             # win32-style
359             if sys.platform == 'win32':
360                 # home drive should be found
361                 os.environ['HOME'] = temp_dir
362                 files = dist.find_config_files()
363                 self.assertTrue(user_filename in files,
364                              '%r not found in %r' % (user_filename, files))
365         finally:
366             os.remove(user_filename)
367
368     def test_fix_help_options(self):
369         help_tuples = [('a', 'b', 'c', 'd'), (1, 2, 3, 4)]
370         fancy_options = fix_help_options(help_tuples)
371         self.assertEqual(fancy_options[0], ('a', 'b', 'c'))
372         self.assertEqual(fancy_options[1], (1, 2, 3))
373
374     def test_show_help(self):
375         # smoke test, just makes sure some help is displayed
376         dist = Distribution()
377         sys.argv = []
378         dist.help = 1
379         dist.script_name = 'setup.py'
380         with captured_stdout() as s:
381             dist.parse_command_line()
382
383         output = [line for line in s.getvalue().split('\n')
384                   if line.strip() != '']
385         self.assertTrue(len(output) > 0)
386
387     def test_long_description(self):
388         long_desc = textwrap.dedent("""\
389         example::
390               We start here
391             and continue here
392           and end here.""")
393         attrs = {"name": "package",
394                  "version": "1.0",
395                  "long_description": long_desc}
396
397         dist = distutils.dist.Distribution(attrs)
398         meta = self.format_metadata(dist)
399         meta = meta.replace('\n' + 8 * ' ', '\n')
400         self.assertTrue(long_desc in meta)
401
402     def test_read_metadata(self):
403         attrs = {"name": "package",
404                  "version": "1.0",
405                  "long_description": "desc",
406                  "description": "xxx",
407                  "download_url": "http://example.com",
408                  "keywords": ['one', 'two'],
409                  "requires": ['foo']}
410
411         dist = Distribution(attrs)
412         metadata = dist.metadata
413
414         # write it then reloads it
415         PKG_INFO = StringIO.StringIO()
416         metadata.write_pkg_file(PKG_INFO)
417         PKG_INFO.seek(0)
418         metadata.read_pkg_file(PKG_INFO)
419
420         self.assertEqual(metadata.name, "package")
421         self.assertEqual(metadata.version, "1.0")
422         self.assertEqual(metadata.description, "xxx")
423         self.assertEqual(metadata.download_url, 'http://example.com')
424         self.assertEqual(metadata.keywords, ['one', 'two'])
425         self.assertEqual(metadata.platforms, ['UNKNOWN'])
426         self.assertEqual(metadata.obsoletes, None)
427         self.assertEqual(metadata.requires, ['foo'])
428
429 def test_suite():
430     suite = unittest.TestSuite()
431     suite.addTest(unittest.makeSuite(DistributionTestCase))
432     suite.addTest(unittest.makeSuite(MetadataTestCase))
433     return suite
434
435 if __name__ == "__main__":
436     unittest.main(defaultTest="test_suite")