blob: e0c16dec82e68f6e1bbd66dd7209bacb8df6d3c0 [file] [log] [blame]
Tarek Ziade1231a4e2011-05-19 13:07:25 +02001import os
2import io
3import csv
4import imp
5import sys
6import shutil
7import zipfile
8import tempfile
9from os.path import relpath # separate import for backport concerns
10from hashlib import md5
Tarek Ziadea17d8882011-05-30 10:57:44 +020011from textwrap import dedent
Tarek Ziade1231a4e2011-05-19 13:07:25 +020012
Tarek Ziadea17d8882011-05-30 10:57:44 +020013from packaging.tests import unittest
14from packaging.tests.test_util import GlobTestCaseBase
15from packaging.tests.support import requires_zlib
16
17from packaging.config import get_resources_dests
Tarek Ziade1231a4e2011-05-19 13:07:25 +020018from packaging.errors import PackagingError
19from packaging.metadata import Metadata
20from packaging.tests import unittest, run_unittest, support, TESTFN
Tarek Ziade1231a4e2011-05-19 13:07:25 +020021from packaging.database import (
22 Distribution, EggInfoDistribution, get_distribution, get_distributions,
23 provides_distribution, obsoletes_distribution, get_file_users,
Tarek Ziadea17d8882011-05-30 10:57:44 +020024 enable_cache, disable_cache, distinfo_dirname, _yield_distributions,
25 get_file, get_file_path)
Tarek Ziade1231a4e2011-05-19 13:07:25 +020026
27# TODO Add a test for getting a distribution provided by another distribution
28# TODO Add a test for absolute pathed RECORD items (e.g. /etc/myapp/config.ini)
29# TODO Add tests from the former pep376 project (zipped site-packages, etc.)
30
31
32def get_hexdigest(filename):
33 with open(filename, 'rb') as file:
34 checksum = md5(file.read())
35 return checksum.hexdigest()
36
37
38def record_pieces(file):
39 path = relpath(file, sys.prefix)
40 digest = get_hexdigest(file)
41 size = os.path.getsize(file)
42 return [path, digest, size]
43
44
45class CommonDistributionTests:
46 """Mixin used to test the interface common to both Distribution classes.
47
48 Derived classes define cls, sample_dist, dirs and records. These
49 attributes are used in test methods. See source code for details.
50 """
51
52 def setUp(self):
53 super(CommonDistributionTests, self).setUp()
54 self.addCleanup(enable_cache)
55 disable_cache()
56 self.fake_dists_path = os.path.abspath(
57 os.path.join(os.path.dirname(__file__), 'fake_dists'))
58
59 def test_instantiation(self):
60 # check that useful attributes are here
61 name, version, distdir = self.sample_dist
62 here = os.path.abspath(os.path.dirname(__file__))
63 dist_path = os.path.join(here, 'fake_dists', distdir)
64
65 dist = self.dist = self.cls(dist_path)
66 self.assertEqual(dist.path, dist_path)
67 self.assertEqual(dist.name, name)
68 self.assertEqual(dist.metadata['Name'], name)
69 self.assertIsInstance(dist.metadata, Metadata)
70 self.assertEqual(dist.version, version)
71 self.assertEqual(dist.metadata['Version'], version)
72
Ezio Melotticad648c2011-05-19 21:25:10 +030073 @requires_zlib
Tarek Ziade1231a4e2011-05-19 13:07:25 +020074 def test_repr(self):
75 dist = self.cls(self.dirs[0])
76 # just check that the class name is in the repr
77 self.assertIn(self.cls.__name__, repr(dist))
78
Ezio Melotticad648c2011-05-19 21:25:10 +030079 @requires_zlib
Tarek Ziade1231a4e2011-05-19 13:07:25 +020080 def test_comparison(self):
81 # tests for __eq__ and __hash__
82 dist = self.cls(self.dirs[0])
83 dist2 = self.cls(self.dirs[0])
84 dist3 = self.cls(self.dirs[1])
85 self.assertIn(dist, {dist: True})
86 self.assertEqual(dist, dist)
87
88 self.assertIsNot(dist, dist2)
89 self.assertEqual(dist, dist2)
90 self.assertNotEqual(dist, dist3)
91 self.assertNotEqual(dist, ())
92
93 def test_list_installed_files(self):
94 for dir_ in self.dirs:
95 dist = self.cls(dir_)
96 for path, md5_, size in dist.list_installed_files():
97 record_data = self.records[dist.path]
98 self.assertIn(path, record_data)
99 self.assertEqual(md5_, record_data[path][0])
100 self.assertEqual(size, record_data[path][1])
101
102
103class TestDistribution(CommonDistributionTests, unittest.TestCase):
104
105 cls = Distribution
106 sample_dist = 'choxie', '2.0.0.9', 'choxie-2.0.0.9.dist-info'
107
108 def setUp(self):
109 super(TestDistribution, self).setUp()
110 self.dirs = [os.path.join(self.fake_dists_path, f)
111 for f in os.listdir(self.fake_dists_path)
112 if f.endswith('.dist-info')]
113
114 self.records = {}
115 for distinfo_dir in self.dirs:
116 record_file = os.path.join(distinfo_dir, 'RECORD')
117 with open(record_file, 'w') as file:
118 record_writer = csv.writer(
Tarek Ziadebe20be12011-05-21 19:45:48 +0200119 file, delimiter=',', quoting=csv.QUOTE_NONE,
120 lineterminator='\n')
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200121
122 dist_location = distinfo_dir.replace('.dist-info', '')
123
124 for path, dirs, files in os.walk(dist_location):
125 for f in files:
126 record_writer.writerow(record_pieces(
127 os.path.join(path, f)))
128 for file in ('INSTALLER', 'METADATA', 'REQUESTED'):
129 record_writer.writerow(record_pieces(
130 os.path.join(distinfo_dir, file)))
131 record_writer.writerow([relpath(record_file, sys.prefix)])
132
133 with open(record_file) as file:
Tarek Ziadebe20be12011-05-21 19:45:48 +0200134 record_reader = csv.reader(file, lineterminator='\n')
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200135 record_data = {}
136 for row in record_reader:
Tarek Ziadebe20be12011-05-21 19:45:48 +0200137 if row == []:
138 continue
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200139 path, md5_, size = (row[:] +
140 [None for i in range(len(row), 3)])
141 record_data[path] = md5_, size
142 self.records[distinfo_dir] = record_data
143
144 def tearDown(self):
145 for distinfo_dir in self.dirs:
146 record_file = os.path.join(distinfo_dir, 'RECORD')
Victor Stinner4c9706b2011-05-19 15:52:59 +0200147 open(record_file, 'wb').close()
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200148 super(TestDistribution, self).tearDown()
149
150 def test_instantiation(self):
151 super(TestDistribution, self).test_instantiation()
152 self.assertIsInstance(self.dist.requested, bool)
153
154 def test_uses(self):
155 # Test to determine if a distribution uses a specified file.
156 # Criteria to test against
157 distinfo_name = 'grammar-1.0a4'
158 distinfo_dir = os.path.join(self.fake_dists_path,
159 distinfo_name + '.dist-info')
160 true_path = [self.fake_dists_path, distinfo_name,
161 'grammar', 'utils.py']
162 true_path = relpath(os.path.join(*true_path), sys.prefix)
163 false_path = [self.fake_dists_path, 'towel_stuff-0.1', 'towel_stuff',
164 '__init__.py']
165 false_path = relpath(os.path.join(*false_path), sys.prefix)
166
167 # Test if the distribution uses the file in question
168 dist = Distribution(distinfo_dir)
169 self.assertTrue(dist.uses(true_path))
170 self.assertFalse(dist.uses(false_path))
171
172 def test_get_distinfo_file(self):
173 # Test the retrieval of dist-info file objects.
174 distinfo_name = 'choxie-2.0.0.9'
175 other_distinfo_name = 'grammar-1.0a4'
176 distinfo_dir = os.path.join(self.fake_dists_path,
177 distinfo_name + '.dist-info')
178 dist = Distribution(distinfo_dir)
179 # Test for known good file matches
180 distinfo_files = [
181 # Relative paths
182 'INSTALLER', 'METADATA',
183 # Absolute paths
184 os.path.join(distinfo_dir, 'RECORD'),
185 os.path.join(distinfo_dir, 'REQUESTED'),
186 ]
187
188 for distfile in distinfo_files:
189 with dist.get_distinfo_file(distfile) as value:
190 self.assertIsInstance(value, io.TextIOWrapper)
191 # Is it the correct file?
192 self.assertEqual(value.name,
193 os.path.join(distinfo_dir, distfile))
194
195 # Test an absolute path that is part of another distributions dist-info
196 other_distinfo_file = os.path.join(
197 self.fake_dists_path, other_distinfo_name + '.dist-info',
198 'REQUESTED')
199 self.assertRaises(PackagingError, dist.get_distinfo_file,
200 other_distinfo_file)
201 # Test for a file that should not exist
202 self.assertRaises(PackagingError, dist.get_distinfo_file,
203 'MAGICFILE')
204
205 def test_list_distinfo_files(self):
206 # Test for the iteration of RECORD path entries.
207 distinfo_name = 'towel_stuff-0.1'
208 distinfo_dir = os.path.join(self.fake_dists_path,
209 distinfo_name + '.dist-info')
210 dist = Distribution(distinfo_dir)
211 # Test for the iteration of the raw path
212 distinfo_record_paths = self.records[distinfo_dir].keys()
213 found = dist.list_distinfo_files()
214 self.assertEqual(sorted(found), sorted(distinfo_record_paths))
215 # Test for the iteration of local absolute paths
216 distinfo_record_paths = [os.path.join(sys.prefix, path)
217 for path in self.records[distinfo_dir]]
218 found = dist.list_distinfo_files(local=True)
219 self.assertEqual(sorted(found), sorted(distinfo_record_paths))
220
221 def test_get_resources_path(self):
222 distinfo_name = 'babar-0.1'
223 distinfo_dir = os.path.join(self.fake_dists_path,
224 distinfo_name + '.dist-info')
225 dist = Distribution(distinfo_dir)
226 resource_path = dist.get_resource_path('babar.png')
227 self.assertEqual(resource_path, 'babar.png')
228 self.assertRaises(KeyError, dist.get_resource_path, 'notexist')
229
230
231class TestEggInfoDistribution(CommonDistributionTests,
232 support.LoggingCatcher,
233 unittest.TestCase):
234
235 cls = EggInfoDistribution
236 sample_dist = 'bacon', '0.1', 'bacon-0.1.egg-info'
237
238 def setUp(self):
239 super(TestEggInfoDistribution, self).setUp()
240
241 self.dirs = [os.path.join(self.fake_dists_path, f)
242 for f in os.listdir(self.fake_dists_path)
243 if f.endswith('.egg') or f.endswith('.egg-info')]
244
245 self.records = {}
246
247 @unittest.skip('not implemented yet')
248 def test_list_installed_files(self):
249 # EggInfoDistribution defines list_installed_files but there is no
250 # test for it yet; someone with setuptools expertise needs to add a
251 # file with the list of installed files for one of the egg fake dists
252 # and write the support code to populate self.records (and then delete
253 # this method)
254 pass
255
256
257class TestDatabase(support.LoggingCatcher,
258 unittest.TestCase):
259
260 def setUp(self):
261 super(TestDatabase, self).setUp()
262 disable_cache()
263 # Setup the path environment with our fake distributions
264 current_path = os.path.abspath(os.path.dirname(__file__))
265 self.sys_path = sys.path[:]
266 self.fake_dists_path = os.path.join(current_path, 'fake_dists')
267 sys.path.insert(0, self.fake_dists_path)
268
269 def tearDown(self):
270 sys.path[:] = self.sys_path
271 enable_cache()
272 super(TestDatabase, self).tearDown()
273
274 def test_distinfo_dirname(self):
275 # Given a name and a version, we expect the distinfo_dirname function
276 # to return a standard distribution information directory name.
277
278 items = [
279 # (name, version, standard_dirname)
280 # Test for a very simple single word name and decimal version
281 # number
282 ('docutils', '0.5', 'docutils-0.5.dist-info'),
283 # Test for another except this time with a '-' in the name, which
284 # needs to be transformed during the name lookup
285 ('python-ldap', '2.5', 'python_ldap-2.5.dist-info'),
286 # Test for both '-' in the name and a funky version number
287 ('python-ldap', '2.5 a---5', 'python_ldap-2.5 a---5.dist-info'),
288 ]
289
290 # Loop through the items to validate the results
291 for name, version, standard_dirname in items:
292 dirname = distinfo_dirname(name, version)
293 self.assertEqual(dirname, standard_dirname)
294
Ezio Melotticad648c2011-05-19 21:25:10 +0300295 @requires_zlib
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200296 def test_get_distributions(self):
297 # Lookup all distributions found in the ``sys.path``.
298 # This test could potentially pick up other installed distributions
299 fake_dists = [('grammar', '1.0a4'), ('choxie', '2.0.0.9'),
300 ('towel-stuff', '0.1'), ('babar', '0.1')]
301 found_dists = []
302
303 # Verify the fake dists have been found.
304 dists = [dist for dist in get_distributions()]
305 for dist in dists:
306 self.assertIsInstance(dist, Distribution)
307 if (dist.name in dict(fake_dists) and
308 dist.path.startswith(self.fake_dists_path)):
309 found_dists.append((dist.name, dist.metadata['version'], ))
310 else:
311 # check that it doesn't find anything more than this
312 self.assertFalse(dist.path.startswith(self.fake_dists_path))
313 # otherwise we don't care what other distributions are found
314
315 # Finally, test that we found all that we were looking for
316 self.assertEqual(sorted(found_dists), sorted(fake_dists))
317
318 # Now, test if the egg-info distributions are found correctly as well
319 fake_dists += [('bacon', '0.1'), ('cheese', '2.0.2'),
320 ('coconuts-aster', '10.3'),
321 ('banana', '0.4'), ('strawberry', '0.6'),
322 ('truffles', '5.0'), ('nut', 'funkyversion')]
323 found_dists = []
324
325 dists = [dist for dist in get_distributions(use_egg_info=True)]
326 for dist in dists:
327 self.assertIsInstance(dist, (Distribution, EggInfoDistribution))
328 if (dist.name in dict(fake_dists) and
329 dist.path.startswith(self.fake_dists_path)):
330 found_dists.append((dist.name, dist.metadata['version']))
331 else:
332 self.assertFalse(dist.path.startswith(self.fake_dists_path))
333
334 self.assertEqual(sorted(fake_dists), sorted(found_dists))
335
Ezio Melotticad648c2011-05-19 21:25:10 +0300336 @requires_zlib
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200337 def test_get_distribution(self):
338 # Test for looking up a distribution by name.
339 # Test the lookup of the towel-stuff distribution
340 name = 'towel-stuff' # Note: This is different from the directory name
341
342 # Lookup the distribution
343 dist = get_distribution(name)
344 self.assertIsInstance(dist, Distribution)
345 self.assertEqual(dist.name, name)
346
347 # Verify that an unknown distribution returns None
348 self.assertIsNone(get_distribution('bogus'))
349
350 # Verify partial name matching doesn't work
351 self.assertIsNone(get_distribution('towel'))
352
353 # Verify that it does not find egg-info distributions, when not
354 # instructed to
355 self.assertIsNone(get_distribution('bacon'))
356 self.assertIsNone(get_distribution('cheese'))
357 self.assertIsNone(get_distribution('strawberry'))
358 self.assertIsNone(get_distribution('banana'))
359
360 # Now check that it works well in both situations, when egg-info
361 # is a file and directory respectively.
362 dist = get_distribution('cheese', use_egg_info=True)
363 self.assertIsInstance(dist, EggInfoDistribution)
364 self.assertEqual(dist.name, 'cheese')
365
366 dist = get_distribution('bacon', use_egg_info=True)
367 self.assertIsInstance(dist, EggInfoDistribution)
368 self.assertEqual(dist.name, 'bacon')
369
370 dist = get_distribution('banana', use_egg_info=True)
371 self.assertIsInstance(dist, EggInfoDistribution)
372 self.assertEqual(dist.name, 'banana')
373
374 dist = get_distribution('strawberry', use_egg_info=True)
375 self.assertIsInstance(dist, EggInfoDistribution)
376 self.assertEqual(dist.name, 'strawberry')
377
378 def test_get_file_users(self):
379 # Test the iteration of distributions that use a file.
380 name = 'towel_stuff-0.1'
381 path = os.path.join(self.fake_dists_path, name,
382 'towel_stuff', '__init__.py')
383 for dist in get_file_users(path):
384 self.assertIsInstance(dist, Distribution)
385 self.assertEqual(dist.name, name)
386
Ezio Melotticad648c2011-05-19 21:25:10 +0300387 @requires_zlib
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200388 def test_provides(self):
389 # Test for looking up distributions by what they provide
390 checkLists = lambda x, y: self.assertEqual(sorted(x), sorted(y))
391
392 l = [dist.name for dist in provides_distribution('truffles')]
393 checkLists(l, ['choxie', 'towel-stuff'])
394
395 l = [dist.name for dist in provides_distribution('truffles', '1.0')]
396 checkLists(l, ['choxie'])
397
398 l = [dist.name for dist in provides_distribution('truffles', '1.0',
399 use_egg_info=True)]
400 checkLists(l, ['choxie', 'cheese'])
401
402 l = [dist.name for dist in provides_distribution('truffles', '1.1.2')]
403 checkLists(l, ['towel-stuff'])
404
405 l = [dist.name for dist in provides_distribution('truffles', '1.1')]
406 checkLists(l, ['towel-stuff'])
407
408 l = [dist.name for dist in provides_distribution('truffles',
409 '!=1.1,<=2.0')]
410 checkLists(l, ['choxie'])
411
412 l = [dist.name for dist in provides_distribution('truffles',
413 '!=1.1,<=2.0',
414 use_egg_info=True)]
415 checkLists(l, ['choxie', 'bacon', 'cheese'])
416
417 l = [dist.name for dist in provides_distribution('truffles', '>1.0')]
418 checkLists(l, ['towel-stuff'])
419
420 l = [dist.name for dist in provides_distribution('truffles', '>1.5')]
421 checkLists(l, [])
422
423 l = [dist.name for dist in provides_distribution('truffles', '>1.5',
424 use_egg_info=True)]
425 checkLists(l, ['bacon'])
426
427 l = [dist.name for dist in provides_distribution('truffles', '>=1.0')]
428 checkLists(l, ['choxie', 'towel-stuff'])
429
430 l = [dist.name for dist in provides_distribution('strawberry', '0.6',
431 use_egg_info=True)]
432 checkLists(l, ['coconuts-aster'])
433
434 l = [dist.name for dist in provides_distribution('strawberry', '>=0.5',
435 use_egg_info=True)]
436 checkLists(l, ['coconuts-aster'])
437
438 l = [dist.name for dist in provides_distribution('strawberry', '>0.6',
439 use_egg_info=True)]
440 checkLists(l, [])
441
442 l = [dist.name for dist in provides_distribution('banana', '0.4',
443 use_egg_info=True)]
444 checkLists(l, ['coconuts-aster'])
445
446 l = [dist.name for dist in provides_distribution('banana', '>=0.3',
447 use_egg_info=True)]
448 checkLists(l, ['coconuts-aster'])
449
450 l = [dist.name for dist in provides_distribution('banana', '!=0.4',
451 use_egg_info=True)]
452 checkLists(l, [])
453
Ezio Melotticad648c2011-05-19 21:25:10 +0300454 @requires_zlib
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200455 def test_obsoletes(self):
456 # Test looking for distributions based on what they obsolete
457 checkLists = lambda x, y: self.assertEqual(sorted(x), sorted(y))
458
459 l = [dist.name for dist in obsoletes_distribution('truffles', '1.0')]
460 checkLists(l, [])
461
462 l = [dist.name for dist in obsoletes_distribution('truffles', '1.0',
463 use_egg_info=True)]
464 checkLists(l, ['cheese', 'bacon'])
465
466 l = [dist.name for dist in obsoletes_distribution('truffles', '0.8')]
467 checkLists(l, ['choxie'])
468
469 l = [dist.name for dist in obsoletes_distribution('truffles', '0.8',
470 use_egg_info=True)]
471 checkLists(l, ['choxie', 'cheese'])
472
473 l = [dist.name for dist in obsoletes_distribution('truffles', '0.9.6')]
474 checkLists(l, ['choxie', 'towel-stuff'])
475
476 l = [dist.name for dist in obsoletes_distribution('truffles',
477 '0.5.2.3')]
478 checkLists(l, ['choxie', 'towel-stuff'])
479
480 l = [dist.name for dist in obsoletes_distribution('truffles', '0.2')]
481 checkLists(l, ['towel-stuff'])
482
Ezio Melotticad648c2011-05-19 21:25:10 +0300483 @requires_zlib
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200484 def test_yield_distribution(self):
485 # tests the internal function _yield_distributions
486 checkLists = lambda x, y: self.assertEqual(sorted(x), sorted(y))
487
488 eggs = [('bacon', '0.1'), ('banana', '0.4'), ('strawberry', '0.6'),
489 ('truffles', '5.0'), ('cheese', '2.0.2'),
490 ('coconuts-aster', '10.3'), ('nut', 'funkyversion')]
491 dists = [('choxie', '2.0.0.9'), ('grammar', '1.0a4'),
492 ('towel-stuff', '0.1'), ('babar', '0.1')]
493
494 checkLists([], _yield_distributions(False, False))
495
496 found = [(dist.name, dist.metadata['Version'])
497 for dist in _yield_distributions(False, True)
498 if dist.path.startswith(self.fake_dists_path)]
499 checkLists(eggs, found)
500
501 found = [(dist.name, dist.metadata['Version'])
502 for dist in _yield_distributions(True, False)
503 if dist.path.startswith(self.fake_dists_path)]
504 checkLists(dists, found)
505
506 found = [(dist.name, dist.metadata['Version'])
507 for dist in _yield_distributions(True, True)
508 if dist.path.startswith(self.fake_dists_path)]
509 checkLists(dists + eggs, found)
510
511
Tarek Ziadea17d8882011-05-30 10:57:44 +0200512class DataFilesTestCase(GlobTestCaseBase):
513
514 def assertRulesMatch(self, rules, spec):
515 tempdir = self.build_files_tree(spec)
516 expected = self.clean_tree(spec)
517 result = get_resources_dests(tempdir, rules)
518 self.assertEqual(expected, result)
519
520 def clean_tree(self, spec):
521 files = {}
522 for path, value in spec.items():
523 if value is not None:
524 files[path] = value
525 return files
526
527 def test_simple_glob(self):
528 rules = [('', '*.tpl', '{data}')]
529 spec = {'coucou.tpl': '{data}/coucou.tpl',
530 'Donotwant': None}
531 self.assertRulesMatch(rules, spec)
532
533 def test_multiple_match(self):
534 rules = [('scripts', '*.bin', '{appdata}'),
535 ('scripts', '*', '{appscript}')]
536 spec = {'scripts/script.bin': '{appscript}/script.bin',
537 'Babarlikestrawberry': None}
538 self.assertRulesMatch(rules, spec)
539
540 def test_set_match(self):
541 rules = [('scripts', '*.{bin,sh}', '{appscript}')]
542 spec = {'scripts/script.bin': '{appscript}/script.bin',
543 'scripts/babar.sh': '{appscript}/babar.sh',
544 'Babarlikestrawberry': None}
545 self.assertRulesMatch(rules, spec)
546
547 def test_set_match_multiple(self):
548 rules = [('scripts', 'script{s,}.{bin,sh}', '{appscript}')]
549 spec = {'scripts/scripts.bin': '{appscript}/scripts.bin',
550 'scripts/script.sh': '{appscript}/script.sh',
551 'Babarlikestrawberry': None}
552 self.assertRulesMatch(rules, spec)
553
554 def test_set_match_exclude(self):
555 rules = [('scripts', '*', '{appscript}'),
556 ('', os.path.join('**', '*.sh'), None)]
557 spec = {'scripts/scripts.bin': '{appscript}/scripts.bin',
558 'scripts/script.sh': None,
559 'Babarlikestrawberry': None}
560 self.assertRulesMatch(rules, spec)
561
562 def test_glob_in_base(self):
563 rules = [('scrip*', '*.bin', '{appscript}')]
564 spec = {'scripts/scripts.bin': '{appscript}/scripts.bin',
565 'scripouille/babar.bin': '{appscript}/babar.bin',
566 'scriptortu/lotus.bin': '{appscript}/lotus.bin',
567 'Babarlikestrawberry': None}
568 self.assertRulesMatch(rules, spec)
569
570 def test_recursive_glob(self):
571 rules = [('', os.path.join('**', '*.bin'), '{binary}')]
572 spec = {'binary0.bin': '{binary}/binary0.bin',
573 'scripts/binary1.bin': '{binary}/scripts/binary1.bin',
574 'scripts/bin/binary2.bin': '{binary}/scripts/bin/binary2.bin',
575 'you/kill/pandabear.guy': None}
576 self.assertRulesMatch(rules, spec)
577
578 def test_final_exemple_glob(self):
579 rules = [
580 ('mailman/database/schemas/', '*', '{appdata}/schemas'),
581 ('', os.path.join('**', '*.tpl'), '{appdata}/templates'),
582 ('', os.path.join('developer-docs', '**', '*.txt'), '{doc}'),
583 ('', 'README', '{doc}'),
584 ('mailman/etc/', '*', '{config}'),
585 ('mailman/foo/', os.path.join('**', 'bar', '*.cfg'), '{config}/baz'),
586 ('mailman/foo/', os.path.join('**', '*.cfg'), '{config}/hmm'),
587 ('', 'some-new-semantic.sns', '{funky-crazy-category}'),
588 ]
589 spec = {
590 'README': '{doc}/README',
591 'some.tpl': '{appdata}/templates/some.tpl',
592 'some-new-semantic.sns':
593 '{funky-crazy-category}/some-new-semantic.sns',
594 'mailman/database/mailman.db': None,
595 'mailman/database/schemas/blah.schema':
596 '{appdata}/schemas/blah.schema',
597 'mailman/etc/my.cnf': '{config}/my.cnf',
598 'mailman/foo/some/path/bar/my.cfg':
599 '{config}/hmm/some/path/bar/my.cfg',
600 'mailman/foo/some/path/other.cfg':
601 '{config}/hmm/some/path/other.cfg',
602 'developer-docs/index.txt': '{doc}/developer-docs/index.txt',
603 'developer-docs/api/toc.txt': '{doc}/developer-docs/api/toc.txt',
604 }
605 self.maxDiff = None
606 self.assertRulesMatch(rules, spec)
607
608 def test_get_file(self):
609 # Create a fake dist
610 temp_site_packages = tempfile.mkdtemp()
611 self.addCleanup(shutil.rmtree, temp_site_packages)
612
613 dist_name = 'test'
614 dist_info = os.path.join(temp_site_packages, 'test-0.1.dist-info')
615 os.mkdir(dist_info)
616
617 metadata_path = os.path.join(dist_info, 'METADATA')
618 resources_path = os.path.join(dist_info, 'RESOURCES')
619
620 with open(metadata_path, 'w') as fp:
621 fp.write(dedent("""\
622 Metadata-Version: 1.2
623 Name: test
624 Version: 0.1
625 Summary: test
626 Author: me
627 """))
628
629 test_path = 'test.cfg'
630
631 fd, test_resource_path = tempfile.mkstemp()
632 os.close(fd)
633 self.addCleanup(os.remove, test_resource_path)
634
635 with open(test_resource_path, 'w') as fp:
636 fp.write('Config')
637
638 with open(resources_path, 'w') as fp:
639 fp.write('%s,%s' % (test_path, test_resource_path))
640
641 # Add fake site-packages to sys.path to retrieve fake dist
642 self.addCleanup(sys.path.remove, temp_site_packages)
643 sys.path.insert(0, temp_site_packages)
644
645 # Force packaging.database to rescan the sys.path
646 self.addCleanup(enable_cache)
647 disable_cache()
648
649 # Try to retrieve resources paths and files
650 self.assertEqual(get_file_path(dist_name, test_path),
651 test_resource_path)
652 self.assertRaises(KeyError, get_file_path, dist_name, 'i-dont-exist')
653
654 with get_file(dist_name, test_path) as fp:
655 self.assertEqual(fp.read(), 'Config')
656 self.assertRaises(KeyError, get_file, dist_name, 'i-dont-exist')
657
658
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200659def test_suite():
660 suite = unittest.TestSuite()
661 load = unittest.defaultTestLoader.loadTestsFromTestCase
662 suite.addTest(load(TestDistribution))
663 suite.addTest(load(TestEggInfoDistribution))
664 suite.addTest(load(TestDatabase))
Tarek Ziadea17d8882011-05-30 10:57:44 +0200665 suite.addTest(load(DataFilesTestCase))
Tarek Ziade1231a4e2011-05-19 13:07:25 +0200666 return suite
667
668
669if __name__ == "__main__":
670 unittest.main(defaultTest='test_suite')