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