]> git.rkrishnan.org Git - tahoe-lafs/zfec.git/blob - zfec/setuptools-0.6c15dev.egg/setuptools/tests/test_resources.py
setup: bundle the latest zetuptoolz as unpacked source egg and change setup.py to...
[tahoe-lafs/zfec.git] / zfec / setuptools-0.6c15dev.egg / setuptools / tests / test_resources.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 # NOTE: the shebang and encoding lines are for ScriptHeaderTests; do not remove
4 from unittest import TestCase, makeSuite; from pkg_resources import *
5 from setuptools.command.easy_install import get_script_header, is_sh
6 import os, pkg_resources, sys, StringIO
7 try: frozenset
8 except NameError:
9     from sets import ImmutableSet as frozenset
10
11 class Metadata(EmptyProvider):
12     """Mock object to return metadata as if from an on-disk distribution"""
13
14     def __init__(self,*pairs):
15         self.metadata = dict(pairs)
16
17     def has_metadata(self,name):
18         return name in self.metadata
19
20     def get_metadata(self,name):
21         return self.metadata[name]
22
23     def get_metadata_lines(self,name):
24         return yield_lines(self.get_metadata(name))
25
26 class DistroTests(TestCase):
27
28     def testCollection(self):
29         # empty path should produce no distributions
30         ad = Environment([], platform=None, python=None)
31         self.assertEqual(list(ad), [])
32         self.assertEqual(ad['FooPkg'],[])
33         ad.add(Distribution.from_filename("FooPkg-1.3_1.egg"))
34         ad.add(Distribution.from_filename("FooPkg-1.4-py2.4-win32.egg"))
35         ad.add(Distribution.from_filename("FooPkg-1.2-py2.4.egg"))
36
37         # Name is in there now
38         self.failUnless(ad['FooPkg'])
39         # But only 1 package
40         self.assertEqual(list(ad), ['foopkg'])
41
42         # Distributions sort by version
43         self.assertEqual(
44             [dist.version for dist in ad['FooPkg']], ['1.4','1.3-1','1.2']
45         )
46         # Removing a distribution leaves sequence alone
47         ad.remove(ad['FooPkg'][1])
48         self.assertEqual(
49             [dist.version for dist in ad['FooPkg']], ['1.4','1.2']
50         )
51         # And inserting adds them in order
52         ad.add(Distribution.from_filename("FooPkg-1.9.egg"))
53         self.assertEqual(
54             [dist.version for dist in ad['FooPkg']], ['1.9','1.4','1.2']
55         )
56
57         ws = WorkingSet([])
58         foo12 = Distribution.from_filename("FooPkg-1.2-py2.4.egg")
59         foo14 = Distribution.from_filename("FooPkg-1.4-py2.4-win32.egg")
60         req, = parse_requirements("FooPkg>=1.3")
61
62         # Nominal case: no distros on path, should yield all applicable
63         self.assertEqual(ad.best_match(req,ws).version, '1.9')
64         # If a matching distro is already installed, should return only that
65         ws.add(foo14); self.assertEqual(ad.best_match(req,ws).version, '1.4')
66
67         # If the first matching distro is unsuitable, it's a version conflict
68         ws = WorkingSet([]); ws.add(foo12); ws.add(foo14)
69         self.assertRaises(VersionConflict, ad.best_match, req, ws)
70
71         # If more than one match on the path, the first one takes precedence
72         ws = WorkingSet([]); ws.add(foo14); ws.add(foo12); ws.add(foo14);
73         self.assertEqual(ad.best_match(req,ws).version, '1.4')
74
75     def checkFooPkg(self,d):
76         self.assertEqual(d.project_name, "FooPkg")
77         self.assertEqual(d.key, "foopkg")
78         self.assertEqual(d.version, "1.3-1")
79         self.assertEqual(d.py_version, "2.4")
80         self.assertEqual(d.platform, "win32")
81         self.assertEqual(d.parsed_version, parse_version("1.3-1"))
82
83     def testDistroBasics(self):
84         d = Distribution(
85             "/some/path",
86             project_name="FooPkg",version="1.3-1",py_version="2.4",platform="win32"
87         )
88         self.checkFooPkg(d)
89
90         d = Distribution("/some/path")
91         self.assertEqual(d.py_version, sys.version[:3])
92         self.assertEqual(d.platform, None)
93
94     def testDistroParse(self):
95         d = Distribution.from_filename("FooPkg-1.3_1-py2.4-win32.egg")
96         self.checkFooPkg(d)
97         d = Distribution.from_filename("FooPkg-1.3_1-py2.4-win32.egg-info")
98         self.checkFooPkg(d)
99
100     def testDistroMetadata(self):
101         d = Distribution(
102             "/some/path", project_name="FooPkg", py_version="2.4", platform="win32",
103             metadata = Metadata(
104                 ('PKG-INFO',"Metadata-Version: 1.0\nVersion: 1.3-1\n")
105             )
106         )
107         self.checkFooPkg(d)
108
109
110     def distRequires(self, txt):
111         return Distribution("/foo", metadata=Metadata(('depends.txt', txt)))
112
113     def checkRequires(self, dist, txt, extras=()):
114         self.assertEqual(
115             list(dist.requires(extras)),
116             list(parse_requirements(txt))
117         )
118
119     def testDistroDependsSimple(self):
120         for v in "Twisted>=1.5", "Twisted>=1.5\nZConfig>=2.0":
121             self.checkRequires(self.distRequires(v), v)
122
123
124     def testResolve(self):
125         ad = Environment([]); ws = WorkingSet([])
126         # Resolving no requirements -> nothing to install
127         self.assertEqual( list(ws.resolve([],ad)), [] )
128         # Request something not in the collection -> DistributionNotFound
129         self.assertRaises(
130             DistributionNotFound, ws.resolve, parse_requirements("Foo"), ad
131         )
132         Foo = Distribution.from_filename(
133             "/foo_dir/Foo-1.2.egg",
134             metadata=Metadata(('depends.txt', "[bar]\nBaz>=2.0"))
135         )
136         ad.add(Foo); ad.add(Distribution.from_filename("Foo-0.9.egg"))
137
138         # Request thing(s) that are available -> list to activate
139         for i in range(3):
140             targets = list(ws.resolve(parse_requirements("Foo"), ad))
141             self.assertEqual(targets, [Foo])
142             map(ws.add,targets)
143         self.assertRaises(VersionConflict, ws.resolve,
144             parse_requirements("Foo==0.9"), ad)
145         ws = WorkingSet([]) # reset
146
147         # Request an extra that causes an unresolved dependency for "Baz"
148         self.assertRaises(
149             DistributionNotFound, ws.resolve,parse_requirements("Foo[bar]"), ad
150         )
151         Baz = Distribution.from_filename(
152             "/foo_dir/Baz-2.1.egg", metadata=Metadata(('depends.txt', "Foo"))
153         )
154         ad.add(Baz)
155
156         # Activation list now includes resolved dependency
157         self.assertEqual(
158             list(ws.resolve(parse_requirements("Foo[bar]"), ad)), [Foo,Baz]
159         )
160         # Requests for conflicting versions produce VersionConflict
161         self.assertRaises( VersionConflict,
162             ws.resolve, parse_requirements("Foo==1.2\nFoo!=1.2"), ad
163         )
164
165     def testDistroDependsOptions(self):
166         d = self.distRequires("""
167             Twisted>=1.5
168             [docgen]
169             ZConfig>=2.0
170             docutils>=0.3
171             [fastcgi]
172             fcgiapp>=0.1""")
173         self.checkRequires(d,"Twisted>=1.5")
174         self.checkRequires(
175             d,"Twisted>=1.5 ZConfig>=2.0 docutils>=0.3".split(), ["docgen"]
176         )
177         self.checkRequires(
178             d,"Twisted>=1.5 fcgiapp>=0.1".split(), ["fastcgi"]
179         )
180         self.checkRequires(
181             d,"Twisted>=1.5 ZConfig>=2.0 docutils>=0.3 fcgiapp>=0.1".split(),
182             ["docgen","fastcgi"]
183         )
184         self.checkRequires(
185             d,"Twisted>=1.5 fcgiapp>=0.1 ZConfig>=2.0 docutils>=0.3".split(),
186             ["fastcgi", "docgen"]
187         )
188         self.assertRaises(UnknownExtra, d.requires, ["foo"])
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 class EntryPointTests(TestCase):
207
208     def assertfields(self, ep):
209         self.assertEqual(ep.name,"foo")
210         self.assertEqual(ep.module_name,"setuptools.tests.test_resources")
211         self.assertEqual(ep.attrs, ("EntryPointTests",))
212         self.assertEqual(ep.extras, ("x",))
213         self.failUnless(ep.load() is EntryPointTests)
214         self.assertEqual(
215             str(ep),
216             "foo = setuptools.tests.test_resources:EntryPointTests [x]"
217         )
218
219     def setUp(self):
220         self.dist = Distribution.from_filename(
221             "FooPkg-1.2-py2.4.egg", metadata=Metadata(('requires.txt','[x]')))
222
223     def testBasics(self):
224         ep = EntryPoint(
225             "foo", "setuptools.tests.test_resources", ["EntryPointTests"],
226             ["x"], self.dist
227         )
228         self.assertfields(ep)
229
230     def testParse(self):
231         s = "foo = setuptools.tests.test_resources:EntryPointTests [x]"
232         ep = EntryPoint.parse(s, self.dist)
233         self.assertfields(ep)
234
235         ep = EntryPoint.parse("bar baz=  spammity[PING]")
236         self.assertEqual(ep.name,"bar baz")
237         self.assertEqual(ep.module_name,"spammity")
238         self.assertEqual(ep.attrs, ())
239         self.assertEqual(ep.extras, ("ping",))
240
241         ep = EntryPoint.parse(" fizzly =  wocka:foo")
242         self.assertEqual(ep.name,"fizzly")
243         self.assertEqual(ep.module_name,"wocka")
244         self.assertEqual(ep.attrs, ("foo",))
245         self.assertEqual(ep.extras, ())
246
247     def testRejects(self):
248         for ep in [
249             "foo", "x=1=2", "x=a:b:c", "q=x/na", "fez=pish:tush-z", "x=f[a]>2",
250         ]:
251             try: EntryPoint.parse(ep)
252             except ValueError: pass
253             else: raise AssertionError("Should've been bad", ep)
254
255     def checkSubMap(self, m):
256         self.assertEqual(len(m), len(self.submap_expect))
257         for key, ep in self.submap_expect.iteritems():
258             self.assertEqual(repr(m.get(key)), repr(ep))
259
260     submap_expect = dict(
261         feature1=EntryPoint('feature1', 'somemodule', ['somefunction']),
262         feature2=EntryPoint('feature2', 'another.module', ['SomeClass'], ['extra1','extra2']),
263         feature3=EntryPoint('feature3', 'this.module', extras=['something'])
264     )
265     submap_str = """
266             # define features for blah blah
267             feature1 = somemodule:somefunction
268             feature2 = another.module:SomeClass [extra1,extra2]
269             feature3 = this.module [something]
270     """
271
272     def testParseList(self):
273         self.checkSubMap(EntryPoint.parse_group("xyz", self.submap_str))
274         self.assertRaises(ValueError, EntryPoint.parse_group, "x a", "foo=bar")
275         self.assertRaises(ValueError, EntryPoint.parse_group, "x",
276             ["foo=baz", "foo=bar"])
277
278     def testParseMap(self):
279         m = EntryPoint.parse_map({'xyz':self.submap_str})
280         self.checkSubMap(m['xyz'])
281         self.assertEqual(m.keys(),['xyz'])
282         m = EntryPoint.parse_map("[xyz]\n"+self.submap_str)
283         self.checkSubMap(m['xyz'])
284         self.assertEqual(m.keys(),['xyz'])
285         self.assertRaises(ValueError, EntryPoint.parse_map, ["[xyz]", "[xyz]"])
286         self.assertRaises(ValueError, EntryPoint.parse_map, self.submap_str)
287
288 class RequirementsTests(TestCase):
289
290     def testBasics(self):
291         r = Requirement.parse("Twisted>=1.2")
292         self.assertEqual(str(r),"Twisted>=1.2")
293         self.assertEqual(repr(r),"Requirement.parse('Twisted>=1.2')")
294         self.assertEqual(r, Requirement("Twisted", [('>=','1.2')], ()))
295         self.assertEqual(r, Requirement("twisTed", [('>=','1.2')], ()))
296         self.assertNotEqual(r, Requirement("Twisted", [('>=','2.0')], ()))
297         self.assertNotEqual(r, Requirement("Zope", [('>=','1.2')], ()))
298         self.assertNotEqual(r, Requirement("Zope", [('>=','3.0')], ()))
299         self.assertNotEqual(r, Requirement.parse("Twisted[extras]>=1.2"))
300
301     def testOrdering(self):
302         r1 = Requirement("Twisted", [('==','1.2c1'),('>=','1.2')], ())
303         r2 = Requirement("Twisted", [('>=','1.2'),('==','1.2c1')], ())
304         self.assertEqual(r1,r2)
305         self.assertEqual(str(r1),str(r2))
306         self.assertEqual(str(r2),"Twisted==1.2c1,>=1.2")
307
308     def testBasicContains(self):
309         r = Requirement("Twisted", [('>=','1.2')], ())
310         foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg")
311         twist11  = Distribution.from_filename("Twisted-1.1.egg")
312         twist12  = Distribution.from_filename("Twisted-1.2.egg")
313         self.failUnless(parse_version('1.2') in r)
314         self.failUnless(parse_version('1.1') not in r)
315         self.failUnless('1.2' in r)
316         self.failUnless('1.1' not in r)
317         self.failUnless(foo_dist not in r)
318         self.failUnless(twist11 not in r)
319         self.failUnless(twist12 in r)
320
321     def testAdvancedContains(self):
322         r, = parse_requirements("Foo>=1.2,<=1.3,==1.9,>2.0,!=2.5,<3.0,==4.5")
323         for v in ('1.2','1.2.2','1.3','1.9','2.0.1','2.3','2.6','3.0c1','4.5'):
324             self.failUnless(v in r, (v,r))
325         for v in ('1.2c1','1.3.1','1.5','1.9.1','2.0','2.5','3.0','4.0'):
326             self.failUnless(v not in r, (v,r))
327
328
329     def testOptionsAndHashing(self):
330         r1 = Requirement.parse("Twisted[foo,bar]>=1.2")
331         r2 = Requirement.parse("Twisted[bar,FOO]>=1.2")
332         r3 = Requirement.parse("Twisted[BAR,FOO]>=1.2.0")
333         self.assertEqual(r1,r2)
334         self.assertEqual(r1,r3)
335         self.assertEqual(r1.extras, ("foo","bar"))
336         self.assertEqual(r2.extras, ("bar","foo"))  # extras are normalized
337         self.assertEqual(hash(r1), hash(r2))
338         self.assertEqual(
339             hash(r1), hash(("twisted", ((">=",parse_version("1.2")),),
340                             frozenset(["foo","bar"])))
341         )
342
343     def testVersionEquality(self):
344         r1 = Requirement.parse("setuptools==0.3a2")
345         r2 = Requirement.parse("setuptools!=0.3a4")
346         d = Distribution.from_filename
347
348         self.failIf(d("setuptools-0.3a4.egg") in r1)
349         self.failIf(d("setuptools-0.3a1.egg") in r1)
350         self.failIf(d("setuptools-0.3a4.egg") in r2)
351
352         self.failUnless(d("setuptools-0.3a2.egg") in r1)
353         self.failUnless(d("setuptools-0.3a2.egg") in r2)
354         self.failUnless(d("setuptools-0.3a3.egg") in r2)
355         self.failUnless(d("setuptools-0.3a5.egg") in r2)
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370 class ParseTests(TestCase):
371
372     def testEmptyParse(self):
373         self.assertEqual(list(parse_requirements('')), [])
374
375     def testYielding(self):
376         for inp,out in [
377             ([], []), ('x',['x']), ([[]],[]), (' x\n y', ['x','y']),
378             (['x\n\n','y'], ['x','y']),
379         ]:
380             self.assertEqual(list(pkg_resources.yield_lines(inp)),out)
381
382     def testSplitting(self):
383         self.assertEqual(
384             list(
385                 pkg_resources.split_sections("""
386                     x
387                     [Y]
388                     z
389
390                     a
391                     [b ]
392                     # foo
393                     c
394                     [ d]
395                     [q]
396                     v
397                     """
398                 )
399             ),
400             [(None,["x"]), ("Y",["z","a"]), ("b",["c"]), ("d",[]), ("q",["v"])]
401         )
402         self.assertRaises(ValueError,list,pkg_resources.split_sections("[foo"))
403
404     def testSafeName(self):
405         self.assertEqual(safe_name("adns-python"), "adns-python")
406         self.assertEqual(safe_name("WSGI Utils"),  "WSGI-Utils")
407         self.assertEqual(safe_name("WSGI  Utils"), "WSGI-Utils")
408         self.assertEqual(safe_name("Money$$$Maker"), "Money-Maker")
409         self.assertNotEqual(safe_name("peak.web"), "peak-web")
410
411     def testSafeVersion(self):
412         self.assertEqual(safe_version("1.2-1"), "1.2-1")
413         self.assertEqual(safe_version("1.2 alpha"),  "1.2.alpha")
414         self.assertEqual(safe_version("2.3.4 20050521"), "2.3.4.20050521")
415         self.assertEqual(safe_version("Money$$$Maker"), "Money-Maker")
416         self.assertEqual(safe_version("peak.web"), "peak.web")
417
418     def testSimpleRequirements(self):
419         self.assertEqual(
420             list(parse_requirements('Twis-Ted>=1.2-1')),
421             [Requirement('Twis-Ted',[('>=','1.2-1')], ())]
422         )
423         self.assertEqual(
424             list(parse_requirements('Twisted >=1.2, \ # more\n<2.0')),
425             [Requirement('Twisted',[('>=','1.2'),('<','2.0')], ())]
426         )
427         self.assertEqual(
428             Requirement.parse("FooBar==1.99a3"),
429             Requirement("FooBar", [('==','1.99a3')], ())
430         )
431         self.assertRaises(ValueError,Requirement.parse,">=2.3")
432         self.assertRaises(ValueError,Requirement.parse,"x\\")
433         self.assertRaises(ValueError,Requirement.parse,"x==2 q")
434         self.assertRaises(ValueError,Requirement.parse,"X==1\nY==2")
435         self.assertRaises(ValueError,Requirement.parse,"#")
436
437     def testVersionEquality(self):
438         def c(s1,s2):
439             p1, p2 = parse_version(s1),parse_version(s2)
440             self.assertEqual(p1,p2, (s1,s2,p1,p2))
441
442         c('1.2-rc1', '1.2rc1')
443         c('0.4', '0.4.0')
444         c('0.4.0.0', '0.4.0')
445         c('0.4.0-0', '0.4-0')
446         c('0pl1', '0.0pl1')
447         c('0pre1', '0.0c1')
448         c('0.0.0preview1', '0c1')
449         c('0.0c1', '0-rc1')
450         c('1.2a1', '1.2.a.1'); c('1.2...a', '1.2a')
451
452     def testVersionOrdering(self):
453         def c(s1,s2):
454             p1, p2 = parse_version(s1),parse_version(s2)
455             self.failUnless(p1<p2, (s1,s2,p1,p2))
456
457         c('2.1','2.1.1')
458         c('2a1','2b0')
459         c('2a1','2.1')
460         c('2.3a1', '2.3')
461         c('2.1-1', '2.1-2')
462         c('2.1-1', '2.1.1')
463         c('2.1', '2.1pl4')
464         c('2.1a0-20040501', '2.1')
465         c('1.1', '02.1')
466         c('A56','B27')
467         c('3.2', '3.2.pl0')
468         c('3.2-1', '3.2pl1')
469         c('3.2pl1', '3.2pl1-1')
470         c('0.4', '4.0')
471         c('0.0.4', '0.4.0')
472         c('0pl1', '0.4pl1')
473         c('2.1.0-rc1','2.1.0')
474         c('2.1dev','2.1a0')
475
476         torture ="""
477         0.80.1-3 0.80.1-2 0.80.1-1 0.79.9999+0.80.0pre4-1
478         0.79.9999+0.80.0pre2-3 0.79.9999+0.80.0pre2-2
479         0.77.2-1 0.77.1-1 0.77.0-1
480         """.split()
481
482         for p,v1 in enumerate(torture):
483             for v2 in torture[p+1:]:
484                 c(v2,v1)
485
486
487
488
489
490
491
492
493 class ScriptHeaderTests(TestCase):
494     non_ascii_exe = '/Users/José/bin/python'
495
496     def test_get_script_header(self):
497         if not sys.platform.startswith('java') or not is_sh(sys.executable):
498             # This test is for non-Jython platforms
499             self.assertEqual(get_script_header('#!/usr/local/bin/python'),
500                              '#!%s\n' % os.path.normpath(sys.executable))
501             self.assertEqual(get_script_header('#!/usr/bin/python -x'),
502                              '#!%s  -x\n' % os.path.normpath(sys.executable))
503             self.assertEqual(get_script_header('#!/usr/bin/python',
504                                                executable=self.non_ascii_exe),
505                              '#!%s -x\n' % self.non_ascii_exe)
506
507     def test_get_script_header_jython_workaround(self):
508         platform = sys.platform
509         sys.platform = 'java1.5.0_13'
510         stdout = sys.stdout
511         try:
512             # A mock sys.executable that uses a shebang line (this file)
513             exe = os.path.normpath(os.path.splitext(__file__)[0] + '.py')
514             self.assertEqual(
515                 get_script_header('#!/usr/local/bin/python', executable=exe),
516                 '#!/usr/bin/env %s\n' % exe)
517
518             # Ensure we generate what is basically a broken shebang line
519             # when there's options, with a warning emitted
520             sys.stdout = StringIO.StringIO()
521             self.assertEqual(get_script_header('#!/usr/bin/python -x',
522                                                executable=exe),
523                              '#!%s  -x\n' % exe)
524             self.assert_('Unable to adapt shebang line' in sys.stdout.getvalue())
525             sys.stdout = StringIO.StringIO()
526             self.assertEqual(get_script_header('#!/usr/bin/python',
527                                                executable=self.non_ascii_exe),
528                              '#!%s -x\n' % self.non_ascii_exe)
529             self.assert_('Unable to adapt shebang line' in sys.stdout.getvalue())
530         finally:
531             sys.platform = platform
532             sys.stdout = stdout
533