distlib-0.2.2/0000775000000000000000000000000012656456062011661 5ustar rootrootdistlib-0.2.2/tests/0000775000000000000000000000000012656456062013023 5ustar rootrootdistlib-0.2.2/tests/LONG_DESC.txt0000664000000000000000000000236612027456516015124 0ustar rootrootCLVault ======= CLVault uses Keyring to provide a command-line utility to safely store and retrieve passwords. Install it using pip or the setup.py script:: $ python setup.py install $ pip install clvault Once it's installed, you will have three scripts installed in your Python scripts folder, you can use to list, store and retrieve passwords:: $ clvault-set blog Set your password: Set the associated username (can be blank): tarek Set a description (can be blank): My blog password Password set. $ clvault-get blog The username is "tarek" The password has been copied in your clipboard $ clvault-list Registered services: blog My blog password *clvault-set* takes a service name then prompt you for a password, and some optional information about your service. The password is safely stored in a keyring while the description is saved in a ``.clvault`` file in your home directory. This file is created automatically the first time the command is used. *clvault-get* copies the password for a given service in your clipboard, and displays the associated user if any. *clvault-list* lists all registered services, with their description when given. Project page: http://bitbucket.org/tarek/clvault distlib-0.2.2/tests/foofoo/0000775000000000000000000000000012656456062014312 5ustar rootrootdistlib-0.2.2/tests/foofoo/nested/0000775000000000000000000000000012656456062015574 5ustar rootrootdistlib-0.2.2/tests/foofoo/nested/nested_resource.bin0000664000000000000000000000001412027616104021435 0ustar rootrootnested data distlib-0.2.2/tests/foofoo/foo_resource.bin0000664000000000000000000000001212027456516017463 0ustar rootrootmore_data distlib-0.2.2/tests/foofoo/bar/0000775000000000000000000000000012656456062015056 5ustar rootrootdistlib-0.2.2/tests/foofoo/bar/bar_resource.bin0000664000000000000000000000000512027456516020212 0ustar rootrootdata distlib-0.2.2/tests/foofoo/bar/baz.py0000664000000000000000000000001612027456516016175 0ustar rootroot# This is baz distlib-0.2.2/tests/foofoo/bar/__init__.py0000664000000000000000000000001012027456516017152 0ustar rootroot# empty distlib-0.2.2/tests/foofoo/__init__.py0000664000000000000000000000001012027456516016406 0ustar rootroot# empty distlib-0.2.2/tests/scripts/0000775000000000000000000000000012656456062014512 5ustar rootrootdistlib-0.2.2/tests/scripts/script3.py0000664000000000000000000000003612030440036016426 0ustar rootroot#!/usr/local/bin/python pass distlib-0.2.2/tests/scripts/script1.py0000664000000000000000000000004012030437742016431 0ustar rootroot#! /usr/bin/env python2.3 pass distlib-0.2.2/tests/scripts/uwsgi_part0000664000000000000000000000175012644723040016612 0ustar rootrootELF>pA@8.@8 @$!@@@@@88@8@@@   n nHЂ   n nTT@T@DDPtd LLd4d4QtdRtd  n n``/lib64/ld-linux-x86-64.so.2GNUGNU3sjhӂ̏s(  ¼2 URYHJ{C  9V#@A B aJtLP#`8 D4J(DG l9 I@YJ$#h@I(!& P@$DB @ G@d+ ,H 3@<4JHTq +> ~ PM |'8Dh 1`F6$ZPRPTHvp%k1  Bjdh"8 / dU pdistlib-0.2.2/tests/scripts/script2.py0000664000000000000000000000003012030437772016434 0ustar rootroot#!/usr/bin/python pass distlib-0.2.2/tests/scripts/foo.py0000664000000000000000000000013612030701410015617 0ustar rootrootdef main(): print('Hello from foo') def other_main(): print('Hello again from foo') distlib-0.2.2/tests/scripts/shell.sh0000664000000000000000000000002212030440162016123 0ustar rootroot#!/bin/sh exit 0 distlib-0.2.2/tests/scripts/script5.py0000664000000000000000000000003712445642006016444 0ustar rootroot#!python -mzippy.activate pass distlib-0.2.2/tests/scripts/script4.py0000664000000000000000000000002012031044274016425 0ustar rootroot#!pythonw pass distlib-0.2.2/tests/PKG-INFO0000664000000000000000000000371012027456516014115 0ustar rootrootMetadata-Version: 1.2 Name: CLVault Version: 0.5 Summary: Command-Line utility to store and retrieve passwords Home-page: http://bitbucket.org/tarek/clvault Author: Tarek Ziade Author-email: tarek@ziade.org License: PSF Keywords: keyring,password,crypt Requires-Dist: foo; sys.platform == 'okook' Requires-Dist: bar; sys.platform == '%s' Platform: UNKNOWN Description: CLVault |======= | |CLVault uses Keyring to provide a command-line utility to safely store |and retrieve passwords. | |Install it using pip or the setup.py script:: | | $ python setup.py install | | $ pip install clvault | |Once it's installed, you will have three scripts installed in your |Python scripts folder, you can use to list, store and retrieve passwords:: | | $ clvault-set blog | Set your password: | Set the associated username (can be blank): tarek | Set a description (can be blank): My blog password | Password set. | | $ clvault-get blog | The username is "tarek" | The password has been copied in your clipboard | | $ clvault-list | Registered services: | blog My blog password | | |*clvault-set* takes a service name then prompt you for a password, and some |optional information about your service. The password is safely stored in |a keyring while the description is saved in a ``.clvault`` file in your |home directory. This file is created automatically the first time the command |is used. | |*clvault-get* copies the password for a given service in your clipboard, and |displays the associated user if any. | |*clvault-list* lists all registered services, with their description when |given. | | |Project page: http://bitbucket.org/tarek/clvault | distlib-0.2.2/tests/minimext-0.1-cp32-cp32mu-linux_x86_64.whl0000664000000000000000000001760712137475420021720 0ustar rootrootPKbB_h0Dminimext.cpython-32mu.so /.ErK@h<6uiWQW4s۴=f`]ݼr7x꣗r v+E?TD4=00Bǰk/E#?N?_D~ 9qIt]JeҺiEr=NXDbF ѯ6eV&#iH%}-.#3-lޚO$DyցL="SFL<49#bKH2Zf&n#V 0P8Y۾u$$|$#c(CI8`.ۅ _'=.\Yr…t*/%"wk_R <-@|I!y0? =ҡ2. EԳ%+ y?ߪPCYΜk34>sO!]=3'Fmd۝g$WsP][,.Olٜ]Īhۿ<M-^n{mYv ;1@}ӡex³@:О;}GoU3~Xd+`MLXRh>~Qܲ/[wn[ #޲z}Uȍ-7׶vQہ-s+ =p3|܊ü-|]lq@Exm=M`w|{!&:z ۄvIjB{tjZ.߁@*mCVL|ҹ<]:|k[{<wyB{KԮ [j>K7#bU t ";x?>>>>W1X]IY{oTLo?dT{crFrQ&ZYѐG=vYG}&QLn:rN6V9 ,,aRQ:x,e,վ%wdOv}wxRj$u]Ph>m) - 7_ȥ "Y" B2>N u" 35 0Xomo1 ,"A5tTFJKn+eutCt^;v'o a""aPVX&#Yt6 n.e|;;$e)k탔-@8Fç(kEOu҇=Cu]1wӒ*ߡ1Oх{X-s*yXڻ~_n@%K]=a^/G=Щ\e݌)q'Sa{?'qz礇^Kƒ0K}𐇕 K< h/B过 2f $ޭEP 3l}د"s6C8q\9*Ÿ#ɎdLz˜MGQ~$GR3s6ehNp '@W#=RVp"ս=j球J <^96cX_O@QwbL&?UF?% >#kHjQ{ s Rv Gj~j(zjm_mN MC? Y=ʔaExVtҋ; &([-2X 4SːjVjp6UĦR9 ?hp¼gБ/ iH@Am:@]?PH{ 4X*4R1ß IĞL@Z B?x~!:аM{m/mJ@ڽSjePr=yYlQyh=HZDX 4NP!tΐ* 3O_Gx+{\FTzBM!E1dx9]΁"S&Ep.ǡAqI+eiR" Z1kEYtleL|>)>mvґyW%Bݨe>5(vtZye_\Yjn, H[oӶڴ|Yu_o3,A9>0̺!EDgrk+rc > 쵷PCг2 a(_w]E*'zg"Cx&Fʪ 6ė%&+Xkhxz?? Pw\ՔOW~U*щנK3-/u8D&s'2AQU |!J> ֖KiIH{&m5,)7GTB)rY"ڶiWFb~ x 9/]Y>N,[ͩ yaI,q)tLM4%PFW=sPI: @=qiR~ G̏Co)C03L- 'dFW#䨧]7{nMsܨ=M+A}ayt^?,}qrϣd\0e^ة8{c4v̈́8z5 )UlA ּqt< b8o2rm]5\iWB;*޳WAF WSo@ӀGdBo]u2%&ԐPU!a_9n|8OV&mSWT6"u`D`)FX@.Z;^^n8&V2| 7#CGd\W$ qm)ip/=vOĹH|t *ٝ62"; ӂٕ;*.pL T$,ٝ.GHFf`PL:3yaz*v堇|aј'Q5A)~Iy |$匬2M9mD \kX KN;hF܈! p\e"ɤ& ғ0eԂh&DIxiqD\"dF/4cͺJ 20%LqBX)-od' -9D.8?D ;HԄygh-4QxJإo|vGr]"i^vrovL!"v Jk;"he.D`Ner3oqR"KA&ǹc R7saD&[.i),"d rSrYSp$1,H&.F# JMĺcT6ƈ0Cj&Zó5@fمbn NS*HD$gA8q@7tgF.Z5Z6TDqy 00&POMR3QGGf9j+%: i*g}t-u9a-Tp.7 g:O1*)W*xh| 2ԹPr*;PFrZh1nL5R-X0pda"p .MIOnN.w1U/UbW Fp!U/SyhW؁:LVUonpS+ $zRU XPJd+Ef_ VNݪXFnOQYW/=W1Y~EH~#w /7.:_7s7In[DN !9~}*㗹9!tƐ4?&eGE._BwΉOi.Qc7Ϳj(ϻݴ'J;*7SSGoK.d?q~+dBZzQx\m21΂F2:*^@_@}b /X|nL^{=w}:ėU'?L/7'^-'~w_i3N|^?*{]pvw܉oi'zs^2ΫND;_:5vt'w ?~J"iEӋg‰y6z|qk=. 9~ׇe{ХzN?O5nx&*\zCb!WXEL=t?uqğkz}-?xğxVy/rwǭ7"(O=6w'ZߟwGuwE"_/ӱ{?Nt >,ri;;pmMW6o/Uh ѻh$[s=%1iXF<ܸ& z" P""TOYq mըU>yZw%ѪBEq3wGAUmlٰn%׶ojmi7Yy}KKkj^~bzs׋/O47~oQ?PKbBP%,!minimext-0.1.dist-info/EXTENSIONSRPPM(QB *K2trKjPKbB`'4minimext-0.1.dist-info/METADATAm0}P"p0GA&ŶU!fKv&G-8g4xY#.Iħcl4H fxA&X1Ի]iq,iԦg-Qp9wfJnvs _h$ѣ4-~PV$dݼo->i9F=/PKbBXKceminimext-0.1.dist-info/WHEEL HM K-*ϳR03rOK-J,/RH,.LR033KI-3 /, (-JJY)%r$[)$邈Rݜ̼Ҋ x3PKbByTuminimext-0.1.dist-info/RECORDu1v0ݳ$:($X eC BDH/ 6(rUܠ1M6@t?˥O..we]g- N29#5\*oEA W]<2Byl?L(Q`zj"]Dk(EPlϧK׼vl%rQho$0t] پb~y2Z:0tN6Iay>'y 0PKbB_h0Dminimext.cpython-32mu.soPKbBP%,!minimext-0.1.dist-info/EXTENSIONSPKbB`'46minimext-0.1.dist-info/METADATAPKbBXKce%minimext-0.1.dist-info/WHEELPKbByTuminimext-0.1.dist-info/RECORDPKwdistlib-0.2.2/tests/keys/0000775000000000000000000000000012656456062013776 5ustar rootrootdistlib-0.2.2/tests/keys/trustdb.gpg0000644000000000000000000000240012103337440016137 0ustar rootrootgpgQ   *U,}B\Pb`? 6Vb\ӆ܍distlib-0.2.2/tests/keys/random_seed0000644000000000000000000000113012103337440016153 0ustar rootroot2ö1fڡn DhPIp-ߏ:44.qqUSr܊~Q@YxAFqZnIToc9>? Fdk_2[~#*IpReZkpB :e>%:=o#&?V>x[YK5p 2;d]D] )jhk٩S$<m;JN0J6VVzZ5W ~̼0d:ŽtxCKbp<84\Kk@ 3~6!|9.I Ojc:_v<fVE TUmN LoέbtwœCWo ?ȴ]@Zw;LƸ\4[3.W]I.>H]E[cth#pUκPuGk VWP&lbЉoD稝2y>vED:&>LaC3.^l1 0zCpۜKCmqvG? 8-3P&b SPsdistlib-0.2.2/tests/keys/secring.gpg0000644000000000000000000000503212103337440016106 0ustar rootrootQ 5dQí}//1I͇` yڸX uMնRy(JJ5RLe:fC.iq+$"%P_H s8&jj0o+҄J_>.hs&sEg£-nSӏ-#ƚ6EZG#_MQI/I[cjHl#LuO[hbdk ET{[72`e\s99 l(H=а.];r!,#/7~2$#Vo^yva=>DywpS^*2I-mS[bgC"rsȡ!t2IRoġ=C |bn ʹH~;S)in7Oy57+j_"N؁Hvo?u FmK]`[jG +m'^@C3^uG% Dx 2t|dSC&h}v) 1Uh)J*U0z}a_hF[0d eS,d֠n޴>_%v!niŮmɼe+7^mjCUL}@1d9 ᄰtEw v!Hl,UL)3ҀkuzR-M9 %`U&OCڬ/2z+qH܏E} {TĤdʹ7}5dfi8"Q    b`?'2LV)1SHg3(7cO9bCCCx)n84{SE=w 윖-!tAR25TK &E]0 Gu&d!u߆V;ӭ1!9Mc?@RQ?8kAf8@emC;AӰa32P)QV.\֊@%5b? uUר:h!3˶MuKf}Y\Y]=W$E ؄Q 艬OT$ܺ#:(-vΜn^ JcK|{‘9b%, BƵ(X{fV<:(S$}#ޔ. E/ִ-vS pq챱S>{r[ ^VE*hk,y=V1n  qu!S-IH-@lTrOvQ&gkk>?za֛Eq2Śs [72`ٽoU@c1BǟpfI&{\%l>0:s7; ̗٧6']T>YR$ik`U_|4ft~'>IP3?$1D5Y?R{!4y}OPHf2vMc9kL|Ǧj 9RfIFkQDJ'-1+8ow,| uŴ,Mc.CM騕 rD&Sqz}]vD8?%5Z&i8R _LݢG`A;lu6ioG=-JZ&v`U3lzjY RTVʣkc8V n ߥ 8(/ >D]NxC(@U)lm#,J\W!(&Vyɪ]/ۯ.G8b3ZmA&R4t[>. Is۰k .=Q!J6a݌]q tbEvEc!PQ;/c;HZƳ;'I;oGVH\r1ժ!=[^d#Zcg`2nCᾰKR /#‰ Q  b`?4hB=~/umjCәgʛ&?yOX=U Jzέ{+2FjwiV -!%o=<3b3.7Eαd)렁PzWr.w0_N.hs&sEg£-nSӏ-#ƚ6EZG#_MQI/I[cjHl#LuO[hbdk ET{1Test User (A test user) 8"Q    b`?'2LV)1SHg3(7cO9bCCCx)n84{SE=w 윖-!tAR25TK &E]0 Gu&d!u߆V;ӭ1!9Mc?@RQ?8kAf8@emC;AӰa32P)QV.\֊@%5b? uUר:h!3˶MuKf}Y\Y]=W$E ؄ Q 艬OT$ܺ#:(-vΜn^ JcK|{‘9b%, BƵ(X{fV<:(S$}#ޔ. E/ִ-vS pq챱S>{r[ ^VE*hk,y=V1n  qu!S-IH-@lTrOvQ&gkk>?za֛Eq2Śs  Q  b`?4hB=~/umjCәgʛ&?yOX=U Jzέ{+2FjwiV -!%o=<3b3.7Eαd)렁PzWr.w0_N" % \ (util.strclass(self.__class__), self.testsRun, len(self.errors), len(self.failures)) distlib-0.2.2/tests/unittest2/util.py0000664000000000000000000000540512030667514016307 0ustar rootroot"""Various utility functions.""" __unittest = True _MAX_LENGTH = 80 def safe_repr(obj, short=False): try: result = repr(obj) except Exception: result = object.__repr__(obj) if not short or len(result) < _MAX_LENGTH: return result return result[:_MAX_LENGTH] + ' [truncated]...' def safe_str(obj): try: return str(obj) except Exception: return object.__str__(obj) def strclass(cls): return "%s.%s" % (cls.__module__, cls.__name__) def sorted_list_difference(expected, actual): """Finds elements in only one or the other of two, sorted input lists. Returns a two-element tuple of lists. The first list contains those elements in the "expected" list but not in the "actual" list, and the second contains those elements in the "actual" list but not in the "expected" list. Duplicate elements in either input list are ignored. """ i = j = 0 missing = [] unexpected = [] while True: try: e = expected[i] a = actual[j] if e < a: missing.append(e) i += 1 while expected[i] == e: i += 1 elif e > a: unexpected.append(a) j += 1 while actual[j] == a: j += 1 else: i += 1 try: while expected[i] == e: i += 1 finally: j += 1 while actual[j] == a: j += 1 except IndexError: missing.extend(expected[i:]) unexpected.extend(actual[j:]) break return missing, unexpected def unorderable_list_difference(expected, actual, ignore_duplicate=False): """Same behavior as sorted_list_difference but for lists of unorderable items (like dicts). As it does a linear search per item (remove) it has O(n*n) performance. """ missing = [] unexpected = [] while expected: item = expected.pop() try: actual.remove(item) except ValueError: missing.append(item) if ignore_duplicate: for lst in expected, actual: try: while True: lst.remove(item) except ValueError: pass if ignore_duplicate: while actual: item = actual.pop() unexpected.append(item) try: while True: actual.remove(item) except ValueError: pass return missing, unexpected # anything left in actual is unexpected return missing, actual distlib-0.2.2/tests/unittest2/loader.py0000664000000000000000000003215512030667514016602 0ustar rootroot"""Loading unittests.""" import os import re import sys import traceback import types import unittest from fnmatch import fnmatch from unittest2 import case, suite try: from os.path import relpath except ImportError: from unittest2.compatibility import relpath __unittest = True def _CmpToKey(mycmp): 'Convert a cmp= function into a key= function' class K(object): def __init__(self, obj): self.obj = obj def __lt__(self, other): return mycmp(self.obj, other.obj) == -1 return K # what about .pyc or .pyo (etc) # we would need to avoid loading the same tests multiple times # from '.py', '.pyc' *and* '.pyo' VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE) def _make_failed_import_test(name, suiteClass): message = 'Failed to import test module: %s' % name if hasattr(traceback, 'format_exc'): # Python 2.3 compatibility # format_exc returns two frames of discover.py as well message += '\n%s' % traceback.format_exc() return _make_failed_test('ModuleImportFailure', name, ImportError(message), suiteClass) def _make_failed_load_tests(name, exception, suiteClass): return _make_failed_test('LoadTestsFailure', name, exception, suiteClass) def _make_failed_test(classname, methodname, exception, suiteClass): def testFailure(self): raise exception attrs = {methodname: testFailure} TestClass = type(classname, (case.TestCase,), attrs) return suiteClass((TestClass(methodname),)) class TestLoader(unittest.TestLoader): """ This class is responsible for loading tests according to various criteria and returning them wrapped in a TestSuite """ testMethodPrefix = 'test' sortTestMethodsUsing = cmp suiteClass = suite.TestSuite _top_level_dir = None def loadTestsFromTestCase(self, testCaseClass): """Return a suite of all tests cases contained in testCaseClass""" if issubclass(testCaseClass, suite.TestSuite): raise TypeError("Test cases should not be derived from TestSuite." " Maybe you meant to derive from TestCase?") testCaseNames = self.getTestCaseNames(testCaseClass) if not testCaseNames and hasattr(testCaseClass, 'runTest'): testCaseNames = ['runTest'] loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) return loaded_suite def loadTestsFromModule(self, module, use_load_tests=True): """Return a suite of all tests cases contained in the given module""" tests = [] for name in dir(module): obj = getattr(module, name) if isinstance(obj, type) and issubclass(obj, unittest.TestCase): tests.append(self.loadTestsFromTestCase(obj)) load_tests = getattr(module, 'load_tests', None) tests = self.suiteClass(tests) if use_load_tests and load_tests is not None: try: return load_tests(self, tests, None) except Exception, e: return _make_failed_load_tests(module.__name__, e, self.suiteClass) return tests def loadTestsFromName(self, name, module=None): """Return a suite of all tests cases given a string specifier. The name may resolve either to a module, a test case class, a test method within a test case class, or a callable object which returns a TestCase or TestSuite instance. The method optionally resolves the names relative to a given module. """ parts = name.split('.') if module is None: parts_copy = parts[:] while parts_copy: try: module = __import__('.'.join(parts_copy)) break except ImportError: del parts_copy[-1] if not parts_copy: raise parts = parts[1:] obj = module for part in parts: parent, obj = obj, getattr(obj, part) if isinstance(obj, types.ModuleType): return self.loadTestsFromModule(obj) elif isinstance(obj, type) and issubclass(obj, unittest.TestCase): return self.loadTestsFromTestCase(obj) elif (isinstance(obj, types.UnboundMethodType) and isinstance(parent, type) and issubclass(parent, case.TestCase)): return self.suiteClass([parent(obj.__name__)]) elif isinstance(obj, unittest.TestSuite): return obj elif hasattr(obj, '__call__'): test = obj() if isinstance(test, unittest.TestSuite): return test elif isinstance(test, unittest.TestCase): return self.suiteClass([test]) else: raise TypeError("calling %s returned %s, not a test" % (obj, test)) else: raise TypeError("don't know how to make test from: %s" % obj) def loadTestsFromNames(self, names, module=None): """Return a suite of all tests cases found using the given sequence of string specifiers. See 'loadTestsFromName()'. """ suites = [self.loadTestsFromName(name, module) for name in names] return self.suiteClass(suites) def getTestCaseNames(self, testCaseClass): """Return a sorted sequence of method names found within testCaseClass """ def isTestMethod(attrname, testCaseClass=testCaseClass, prefix=self.testMethodPrefix): return attrname.startswith(prefix) and \ hasattr(getattr(testCaseClass, attrname), '__call__') testFnNames = filter(isTestMethod, dir(testCaseClass)) if self.sortTestMethodsUsing: testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing)) return testFnNames def discover(self, start_dir, pattern='test*.py', top_level_dir=None): """Find and return all test modules from the specified start directory, recursing into subdirectories to find them. Only test files that match the pattern will be loaded. (Using shell style pattern matching.) All test modules must be importable from the top level of the project. If the start directory is not the top level directory then the top level directory must be specified separately. If a test package name (directory with '__init__.py') matches the pattern then the package will be checked for a 'load_tests' function. If this exists then it will be called with loader, tests, pattern. If load_tests exists then discovery does *not* recurse into the package, load_tests is responsible for loading all tests in the package. The pattern is deliberately not stored as a loader attribute so that packages can continue discovery themselves. top_level_dir is stored so load_tests does not need to pass this argument in to loader.discover(). """ set_implicit_top = False if top_level_dir is None and self._top_level_dir is not None: # make top_level_dir optional if called from load_tests in a package top_level_dir = self._top_level_dir elif top_level_dir is None: set_implicit_top = True top_level_dir = start_dir top_level_dir = os.path.abspath(top_level_dir) if not top_level_dir in sys.path: # all test modules must be importable from the top level directory # should we *unconditionally* put the start directory in first # in sys.path to minimise likelihood of conflicts between installed # modules and development versions? sys.path.insert(0, top_level_dir) self._top_level_dir = top_level_dir is_not_importable = False if os.path.isdir(os.path.abspath(start_dir)): start_dir = os.path.abspath(start_dir) if start_dir != top_level_dir: is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py')) else: # support for discovery from dotted module names try: __import__(start_dir) except ImportError: is_not_importable = True else: the_module = sys.modules[start_dir] top_part = start_dir.split('.')[0] start_dir = os.path.abspath(os.path.dirname((the_module.__file__))) if set_implicit_top: self._top_level_dir = os.path.abspath(os.path.dirname(os.path.dirname(sys.modules[top_part].__file__))) sys.path.remove(top_level_dir) if is_not_importable: raise ImportError('Start directory is not importable: %r' % start_dir) tests = list(self._find_tests(start_dir, pattern)) return self.suiteClass(tests) def _get_name_from_path(self, path): path = os.path.splitext(os.path.normpath(path))[0] _relpath = relpath(path, self._top_level_dir) assert not os.path.isabs(_relpath), "Path must be within the project" assert not _relpath.startswith('..'), "Path must be within the project" name = _relpath.replace(os.path.sep, '.') return name def _get_module_from_name(self, name): __import__(name) return sys.modules[name] def _match_path(self, path, full_path, pattern): # override this method to use alternative matching strategy return fnmatch(path, pattern) def _find_tests(self, start_dir, pattern): """Used by discovery. Yields test suites it loads.""" paths = os.listdir(start_dir) for path in paths: full_path = os.path.join(start_dir, path) if os.path.isfile(full_path): if not VALID_MODULE_NAME.match(path): # valid Python identifiers only continue if not self._match_path(path, full_path, pattern): continue # if the test file matches, load it name = self._get_name_from_path(full_path) try: module = self._get_module_from_name(name) except: yield _make_failed_import_test(name, self.suiteClass) else: mod_file = os.path.abspath(getattr(module, '__file__', full_path)) realpath = os.path.splitext(mod_file)[0] fullpath_noext = os.path.splitext(full_path)[0] if realpath.lower() != fullpath_noext.lower(): module_dir = os.path.dirname(realpath) mod_name = os.path.splitext(os.path.basename(full_path))[0] expected_dir = os.path.dirname(full_path) msg = ("%r module incorrectly imported from %r. Expected %r. " "Is this module globally installed?") raise ImportError(msg % (mod_name, module_dir, expected_dir)) yield self.loadTestsFromModule(module) elif os.path.isdir(full_path): if not os.path.isfile(os.path.join(full_path, '__init__.py')): continue load_tests = None tests = None if fnmatch(path, pattern): # only check load_tests if the package directory itself matches the filter name = self._get_name_from_path(full_path) package = self._get_module_from_name(name) load_tests = getattr(package, 'load_tests', None) tests = self.loadTestsFromModule(package, use_load_tests=False) if load_tests is None: if tests is not None: # tests loaded from package file yield tests # recurse into the package for test in self._find_tests(full_path, pattern): yield test else: try: yield load_tests(self, tests, pattern) except Exception, e: yield _make_failed_load_tests(package.__name__, e, self.suiteClass) defaultTestLoader = TestLoader() def _makeLoader(prefix, sortUsing, suiteClass=None): loader = TestLoader() loader.sortTestMethodsUsing = sortUsing loader.testMethodPrefix = prefix if suiteClass: loader.suiteClass = suiteClass return loader def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp): return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass) def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=suite.TestSuite): return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass) def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=suite.TestSuite): return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module) distlib-0.2.2/tests/unittest2/main.py0000664000000000000000000002225312105312152016242 0ustar rootroot"""Unittest main program""" import sys import os import types from unittest2 import loader, runner try: from unittest2.signals import installHandler except ImportError: installHandler = None __unittest = True FAILFAST = " -f, --failfast Stop on first failure\n" CATCHBREAK = " -c, --catch Catch control-C and display results\n" BUFFEROUTPUT = " -b, --buffer Buffer stdout and stderr during test runs\n" USAGE_AS_MAIN = """\ Usage: %(progName)s [options] [tests] Options: -h, --help Show this message -v, --verbose Verbose output -q, --quiet Minimal output %(failfast)s%(catchbreak)s%(buffer)s Examples: %(progName)s test_module - run tests from test_module %(progName)s test_module.TestClass - run tests from test_module.TestClass %(progName)s test_module.TestClass.test_method - run specified test method [tests] can be a list of any number of test modules, classes and test methods. Alternative Usage: %(progName)s discover [options] Options: -v, --verbose Verbose output %(failfast)s%(catchbreak)s%(buffer)s -s directory Directory to start discovery ('.' default) -p pattern Pattern to match test files ('test*.py' default) -t directory Top level directory of project (default to start directory) For test discovery all test modules must be importable from the top level directory of the project. """ USAGE_FROM_MODULE = """\ Usage: %(progName)s [options] [test] [...] Options: -h, --help Show this message -v, --verbose Verbose output -q, --quiet Minimal output %(failfast)s%(catchbreak)s%(buffer)s Examples: %(progName)s - run default set of tests %(progName)s MyTestSuite - run suite 'MyTestSuite' %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething %(progName)s MyTestCase - run all 'test*' test methods in MyTestCase """ class TestProgram(object): """A command-line program that runs a set of tests; this is primarily for making test modules conveniently executable. """ USAGE = USAGE_FROM_MODULE # defaults for testing failfast = catchbreak = buffer = progName = None def __init__(self, module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=loader.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None): if isinstance(module, basestring): self.module = __import__(module) for part in module.split('.')[1:]: self.module = getattr(self.module, part) else: self.module = module if argv is None: argv = sys.argv self.exit = exit self.verbosity = verbosity self.failfast = failfast self.catchbreak = catchbreak self.buffer = buffer self.defaultTest = defaultTest self.testRunner = testRunner self.testLoader = testLoader self.progName = os.path.basename(argv[0]) self.parseArgs(argv) self.runTests() def usageExit(self, msg=None): if msg: print msg usage = {'progName': self.progName, 'catchbreak': '', 'failfast': '', 'buffer': ''} if self.failfast != False: usage['failfast'] = FAILFAST if self.catchbreak != False and installHandler is not None: usage['catchbreak'] = CATCHBREAK if self.buffer != False: usage['buffer'] = BUFFEROUTPUT print self.USAGE % usage sys.exit(2) def parseArgs(self, argv): if len(argv) > 1 and argv[1].lower() == 'discover': self._do_discovery(argv[2:]) return import getopt long_opts = ['help', 'verbose', 'quiet', 'failfast', 'catch', 'buffer'] try: options, args = getopt.getopt(argv[1:], 'hHvqfcb', long_opts) for opt, value in options: if opt in ('-h','-H','--help'): self.usageExit() if opt in ('-q','--quiet'): self.verbosity = 0 if opt in ('-v','--verbose'): self.verbosity = 2 if opt in ('-f','--failfast'): if self.failfast is None: self.failfast = True # Should this raise an exception if -f is not valid? if opt in ('-c','--catch'): if self.catchbreak is None and installHandler is not None: self.catchbreak = True # Should this raise an exception if -c is not valid? if opt in ('-b','--buffer'): if self.buffer is None: self.buffer = True # Should this raise an exception if -b is not valid? if len(args) == 0 and self.defaultTest is None: # createTests will load tests from self.module self.testNames = None elif len(args) > 0: self.testNames = args if __name__ == '__main__': # to support python -m unittest ... self.module = None else: self.testNames = (self.defaultTest,) self.createTests() except getopt.error, msg: self.usageExit(msg) def createTests(self): if self.testNames is None: self.test = self.testLoader.loadTestsFromModule(self.module) else: self.test = self.testLoader.loadTestsFromNames(self.testNames, self.module) def _do_discovery(self, argv, Loader=loader.TestLoader): # handle command line args for test discovery self.progName = '%s discover' % self.progName import optparse parser = optparse.OptionParser() parser.prog = self.progName parser.add_option('-v', '--verbose', dest='verbose', default=False, help='Verbose output', action='store_true') if self.failfast != False: parser.add_option('-f', '--failfast', dest='failfast', default=False, help='Stop on first fail or error', action='store_true') if self.catchbreak != False and installHandler is not None: parser.add_option('-c', '--catch', dest='catchbreak', default=False, help='Catch ctrl-C and display results so far', action='store_true') if self.buffer != False: parser.add_option('-b', '--buffer', dest='buffer', default=False, help='Buffer stdout and stderr during tests', action='store_true') parser.add_option('-s', '--start-directory', dest='start', default='.', help="Directory to start discovery ('.' default)") parser.add_option('-p', '--pattern', dest='pattern', default='test*.py', help="Pattern to match tests ('test*.py' default)") parser.add_option('-t', '--top-level-directory', dest='top', default=None, help='Top level directory of project (defaults to start directory)') options, args = parser.parse_args(argv) if len(args) > 3: self.usageExit() for name, value in zip(('start', 'pattern', 'top'), args): setattr(options, name, value) # only set options from the parsing here # if they weren't set explicitly in the constructor if self.failfast is None: self.failfast = options.failfast if self.catchbreak is None and installHandler is not None: self.catchbreak = options.catchbreak if self.buffer is None: self.buffer = options.buffer if options.verbose: self.verbosity = 2 start_dir = options.start pattern = options.pattern top_level_dir = options.top loader = Loader() self.test = loader.discover(start_dir, pattern, top_level_dir) def runTests(self): if self.catchbreak: installHandler() if self.testRunner is None: self.testRunner = runner.TextTestRunner if isinstance(self.testRunner, (type, types.ClassType)): try: testRunner = self.testRunner(verbosity=self.verbosity, failfast=self.failfast, buffer=self.buffer) except TypeError: # didn't accept the verbosity, buffer or failfast arguments testRunner = self.testRunner() else: # it is assumed to be a TestRunner instance testRunner = self.testRunner self.result = testRunner.run(self.test) if self.exit: sys.exit(not self.result.wasSuccessful()) main = TestProgram def main_(): TestProgram.USAGE = USAGE_AS_MAIN main(module=None) distlib-0.2.2/tests/unittest2/runner.py0000664000000000000000000001514512030667514016645 0ustar rootroot"""Running tests""" import sys import time import unittest from unittest2 import result try: from unittest2.signals import registerResult except ImportError: def registerResult(_): pass __unittest = True class _WritelnDecorator(object): """Used to decorate file-like objects with a handy 'writeln' method""" def __init__(self,stream): self.stream = stream def __getattr__(self, attr): if attr in ('stream', '__getstate__'): raise AttributeError(attr) return getattr(self.stream,attr) def writeln(self, arg=None): if arg: self.write(arg) self.write('\n') # text-mode streams translate to \r\n if needed class TextTestResult(result.TestResult): """A test result class that can print formatted text results to a stream. Used by TextTestRunner. """ separator1 = '=' * 70 separator2 = '-' * 70 def __init__(self, stream, descriptions, verbosity): super(TextTestResult, self).__init__() self.stream = stream self.showAll = verbosity > 1 self.dots = verbosity == 1 self.descriptions = descriptions def getDescription(self, test): doc_first_line = test.shortDescription() if self.descriptions and doc_first_line: return '\n'.join((str(test), doc_first_line)) else: return str(test) def startTest(self, test): super(TextTestResult, self).startTest(test) if self.showAll: self.stream.write(self.getDescription(test)) self.stream.write(" ... ") self.stream.flush() def addSuccess(self, test): super(TextTestResult, self).addSuccess(test) if self.showAll: self.stream.writeln("ok") elif self.dots: self.stream.write('.') self.stream.flush() def addError(self, test, err): super(TextTestResult, self).addError(test, err) if self.showAll: self.stream.writeln("ERROR") elif self.dots: self.stream.write('E') self.stream.flush() def addFailure(self, test, err): super(TextTestResult, self).addFailure(test, err) if self.showAll: self.stream.writeln("FAIL") elif self.dots: self.stream.write('F') self.stream.flush() def addSkip(self, test, reason): super(TextTestResult, self).addSkip(test, reason) if self.showAll: self.stream.writeln("skipped %r" % (reason,)) elif self.dots: self.stream.write("s") self.stream.flush() def addExpectedFailure(self, test, err): super(TextTestResult, self).addExpectedFailure(test, err) if self.showAll: self.stream.writeln("expected failure") elif self.dots: self.stream.write("x") self.stream.flush() def addUnexpectedSuccess(self, test): super(TextTestResult, self).addUnexpectedSuccess(test) if self.showAll: self.stream.writeln("unexpected success") elif self.dots: self.stream.write("u") self.stream.flush() def printErrors(self): if self.dots or self.showAll: self.stream.writeln() self.printErrorList('ERROR', self.errors) self.printErrorList('FAIL', self.failures) def printErrorList(self, flavour, errors): for test, err in errors: self.stream.writeln(self.separator1) self.stream.writeln("%s: %s" % (flavour, self.getDescription(test))) self.stream.writeln(self.separator2) self.stream.writeln("%s" % err) def stopTestRun(self): super(TextTestResult, self).stopTestRun() self.printErrors() class TextTestRunner(unittest.TextTestRunner): """A test runner class that displays results in textual form. It prints out the names of tests as they are run, errors as they occur, and a summary of the results at the end of the test run. """ resultclass = TextTestResult def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None): self.stream = _WritelnDecorator(stream) self.descriptions = descriptions self.verbosity = verbosity self.failfast = failfast self.buffer = buffer if resultclass is not None: self.resultclass = resultclass def _makeResult(self): return self.resultclass(self.stream, self.descriptions, self.verbosity) def run(self, test): "Run the given test case or test suite." result = self._makeResult() result.failfast = self.failfast result.buffer = self.buffer registerResult(result) startTime = time.time() startTestRun = getattr(result, 'startTestRun', None) if startTestRun is not None: startTestRun() try: test(result) finally: stopTestRun = getattr(result, 'stopTestRun', None) if stopTestRun is not None: stopTestRun() else: result.printErrors() stopTime = time.time() timeTaken = stopTime - startTime if hasattr(result, 'separator2'): self.stream.writeln(result.separator2) run = result.testsRun self.stream.writeln("Ran %d test%s in %.3fs" % (run, run != 1 and "s" or "", timeTaken)) self.stream.writeln() expectedFails = unexpectedSuccesses = skipped = 0 try: results = map(len, (result.expectedFailures, result.unexpectedSuccesses, result.skipped)) expectedFails, unexpectedSuccesses, skipped = results except AttributeError: pass infos = [] if not result.wasSuccessful(): self.stream.write("FAILED") failed, errored = map(len, (result.failures, result.errors)) if failed: infos.append("failures=%d" % failed) if errored: infos.append("errors=%d" % errored) else: self.stream.write("OK") if skipped: infos.append("skipped=%d" % skipped) if expectedFails: infos.append("expected failures=%d" % expectedFails) if unexpectedSuccesses: infos.append("unexpected successes=%d" % unexpectedSuccesses) if infos: self.stream.writeln(" (%s)" % (", ".join(infos),)) else: self.stream.write("\n") return result distlib-0.2.2/tests/unittest2/compatibility.py0000664000000000000000000000406412030667514020203 0ustar rootrootimport os import sys try: from functools import wraps except ImportError: # only needed for Python 2.4 def wraps(_): def _wraps(func): return func return _wraps __unittest = True def _relpath_nt(path, start=os.path.curdir): """Return a relative version of a path""" if not path: raise ValueError("no path specified") start_list = os.path.abspath(start).split(os.path.sep) path_list = os.path.abspath(path).split(os.path.sep) if start_list[0].lower() != path_list[0].lower(): unc_path, rest = os.path.splitunc(path) unc_start, rest = os.path.splitunc(start) if bool(unc_path) ^ bool(unc_start): raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)" % (path, start)) else: raise ValueError("path is on drive %s, start on drive %s" % (path_list[0], start_list[0])) # Work out how much of the filepath is shared by start and path. for i in range(min(len(start_list), len(path_list))): if start_list[i].lower() != path_list[i].lower(): break else: i += 1 rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:] if not rel_list: return os.path.curdir return os.path.join(*rel_list) # default to posixpath definition def _relpath_posix(path, start=os.path.curdir): """Return a relative version of a path""" if not path: raise ValueError("no path specified") start_list = os.path.abspath(start).split(os.path.sep) path_list = os.path.abspath(path).split(os.path.sep) # Work out how much of the filepath is shared by start and path. i = len(os.path.commonprefix([start_list, path_list])) rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:] if not rel_list: return os.path.curdir return os.path.join(*rel_list) if os.path is sys.modules.get('ntpath'): relpath = _relpath_nt else: relpath = _relpath_posix distlib-0.2.2/tests/unittest2/collector.py0000664000000000000000000000044112030667514017313 0ustar rootrootimport os import sys from unittest2.loader import defaultTestLoader def collector(): # import __main__ triggers code re-execution __main__ = sys.modules['__main__'] setupDir = os.path.abspath(os.path.dirname(__main__.__file__)) return defaultTestLoader.discover(setupDir) distlib-0.2.2/tests/unittest2/test/0000775000000000000000000000000012656456062015743 5ustar rootrootdistlib-0.2.2/tests/unittest2/test/test_result.py0000664000000000000000000003430012105312152020646 0ustar rootrootimport sys import textwrap from StringIO import StringIO import unittest2 class Test_TestResult(unittest2.TestCase): # Note: there are not separate tests for TestResult.wasSuccessful(), # TestResult.errors, TestResult.failures, TestResult.testsRun or # TestResult.shouldStop because these only have meaning in terms of # other TestResult methods. # # Accordingly, tests for the aforenamed attributes are incorporated # in with the tests for the defining methods. ################################################################ def test_init(self): result = unittest2.TestResult() self.assertTrue(result.wasSuccessful()) self.assertEqual(len(result.errors), 0) self.assertEqual(len(result.failures), 0) self.assertEqual(result.testsRun, 0) self.assertEqual(result.shouldStop, False) self.assertIsNone(result._stdout_buffer) self.assertIsNone(result._stderr_buffer) # "This method can be called to signal that the set of tests being # run should be aborted by setting the TestResult's shouldStop # attribute to True." def test_stop(self): result = unittest2.TestResult() result.stop() self.assertEqual(result.shouldStop, True) # "Called when the test case test is about to be run. The default # implementation simply increments the instance's testsRun counter." def test_startTest(self): class Foo(unittest2.TestCase): def test_1(self): pass test = Foo('test_1') result = unittest2.TestResult() result.startTest(test) self.assertTrue(result.wasSuccessful()) self.assertEqual(len(result.errors), 0) self.assertEqual(len(result.failures), 0) self.assertEqual(result.testsRun, 1) self.assertEqual(result.shouldStop, False) result.stopTest(test) # "Called after the test case test has been executed, regardless of # the outcome. The default implementation does nothing." def test_stopTest(self): class Foo(unittest2.TestCase): def test_1(self): pass test = Foo('test_1') result = unittest2.TestResult() result.startTest(test) self.assertTrue(result.wasSuccessful()) self.assertEqual(len(result.errors), 0) self.assertEqual(len(result.failures), 0) self.assertEqual(result.testsRun, 1) self.assertEqual(result.shouldStop, False) result.stopTest(test) # Same tests as above; make sure nothing has changed self.assertTrue(result.wasSuccessful()) self.assertEqual(len(result.errors), 0) self.assertEqual(len(result.failures), 0) self.assertEqual(result.testsRun, 1) self.assertEqual(result.shouldStop, False) # "Called before and after tests are run. The default implementation does nothing." def test_startTestRun_stopTestRun(self): result = unittest2.TestResult() result.startTestRun() result.stopTestRun() # "addSuccess(test)" # ... # "Called when the test case test succeeds" # ... # "wasSuccessful() - Returns True if all tests run so far have passed, # otherwise returns False" # ... # "testsRun - The total number of tests run so far." # ... # "errors - A list containing 2-tuples of TestCase instances and # formatted tracebacks. Each tuple represents a test which raised an # unexpected exception. Contains formatted # tracebacks instead of sys.exc_info() results." # ... # "failures - A list containing 2-tuples of TestCase instances and # formatted tracebacks. Each tuple represents a test where a failure was # explicitly signalled using the TestCase.fail*() or TestCase.assert*() # methods. Contains formatted tracebacks instead # of sys.exc_info() results." def test_addSuccess(self): class Foo(unittest2.TestCase): def test_1(self): pass test = Foo('test_1') result = unittest2.TestResult() result.startTest(test) result.addSuccess(test) result.stopTest(test) self.assertTrue(result.wasSuccessful()) self.assertEqual(len(result.errors), 0) self.assertEqual(len(result.failures), 0) self.assertEqual(result.testsRun, 1) self.assertEqual(result.shouldStop, False) # "addFailure(test, err)" # ... # "Called when the test case test signals a failure. err is a tuple of # the form returned by sys.exc_info(): (type, value, traceback)" # ... # "wasSuccessful() - Returns True if all tests run so far have passed, # otherwise returns False" # ... # "testsRun - The total number of tests run so far." # ... # "errors - A list containing 2-tuples of TestCase instances and # formatted tracebacks. Each tuple represents a test which raised an # unexpected exception. Contains formatted # tracebacks instead of sys.exc_info() results." # ... # "failures - A list containing 2-tuples of TestCase instances and # formatted tracebacks. Each tuple represents a test where a failure was # explicitly signalled using the TestCase.fail*() or TestCase.assert*() # methods. Contains formatted tracebacks instead # of sys.exc_info() results." def test_addFailure(self): class Foo(unittest2.TestCase): def test_1(self): pass test = Foo('test_1') try: test.fail("foo") except: exc_info_tuple = sys.exc_info() result = unittest2.TestResult() result.startTest(test) result.addFailure(test, exc_info_tuple) result.stopTest(test) self.assertFalse(result.wasSuccessful()) self.assertEqual(len(result.errors), 0) self.assertEqual(len(result.failures), 1) self.assertEqual(result.testsRun, 1) self.assertEqual(result.shouldStop, False) test_case, formatted_exc = result.failures[0] self.assertTrue(test_case is test) self.assertIsInstance(formatted_exc, str) # "addError(test, err)" # ... # "Called when the test case test raises an unexpected exception err # is a tuple of the form returned by sys.exc_info(): # (type, value, traceback)" # ... # "wasSuccessful() - Returns True if all tests run so far have passed, # otherwise returns False" # ... # "testsRun - The total number of tests run so far." # ... # "errors - A list containing 2-tuples of TestCase instances and # formatted tracebacks. Each tuple represents a test which raised an # unexpected exception. Contains formatted # tracebacks instead of sys.exc_info() results." # ... # "failures - A list containing 2-tuples of TestCase instances and # formatted tracebacks. Each tuple represents a test where a failure was # explicitly signalled using the TestCase.fail*() or TestCase.assert*() # methods. Contains formatted tracebacks instead # of sys.exc_info() results." def test_addError(self): class Foo(unittest2.TestCase): def test_1(self): pass test = Foo('test_1') try: raise TypeError() except: exc_info_tuple = sys.exc_info() result = unittest2.TestResult() result.startTest(test) result.addError(test, exc_info_tuple) result.stopTest(test) self.assertFalse(result.wasSuccessful()) self.assertEqual(len(result.errors), 1) self.assertEqual(len(result.failures), 0) self.assertEqual(result.testsRun, 1) self.assertEqual(result.shouldStop, False) test_case, formatted_exc = result.errors[0] self.assertTrue(test_case is test) self.assertIsInstance(formatted_exc, str) def testGetDescriptionWithoutDocstring(self): result = unittest2.TextTestResult(None, True, 1) self.assertEqual( result.getDescription(self), 'testGetDescriptionWithoutDocstring (' + __name__ + '.Test_TestResult)') def testGetDescriptionWithOneLineDocstring(self): """Tests getDescription() for a method with a docstring.""" result = unittest2.TextTestResult(None, True, 1) self.assertEqual( result.getDescription(self), ('testGetDescriptionWithOneLineDocstring ' '(' + __name__ + '.Test_TestResult)\n' 'Tests getDescription() for a method with a docstring.')) def testGetDescriptionWithMultiLineDocstring(self): """Tests getDescription() for a method with a longer docstring. The second line of the docstring. """ result = unittest2.TextTestResult(None, True, 1) self.assertEqual( result.getDescription(self), ('testGetDescriptionWithMultiLineDocstring ' '(' + __name__ + '.Test_TestResult)\n' 'Tests getDescription() for a method with a longer ' 'docstring.')) def testStackFrameTrimming(self): class Frame(object): class tb_frame(object): f_globals = {} result = unittest2.TestResult() self.assertFalse(result._is_relevant_tb_level(Frame)) Frame.tb_frame.f_globals['__unittest'] = True self.assertTrue(result._is_relevant_tb_level(Frame)) def testFailFast(self): result = unittest2.TestResult() result._exc_info_to_string = lambda *_: '' result.failfast = True result.addError(None, None) self.assertTrue(result.shouldStop) result = unittest2.TestResult() result._exc_info_to_string = lambda *_: '' result.failfast = True result.addFailure(None, None) self.assertTrue(result.shouldStop) result = unittest2.TestResult() result._exc_info_to_string = lambda *_: '' result.failfast = True result.addUnexpectedSuccess(None) self.assertTrue(result.shouldStop) def testFailFastSetByRunner(self): runner = unittest2.TextTestRunner(stream=StringIO(), failfast=True) self.testRan = False def test(result): self.testRan = True self.assertTrue(result.failfast) runner.run(test) self.assertTrue(self.testRan) class TestOutputBuffering(unittest2.TestCase): def setUp(self): self._real_out = sys.stdout self._real_err = sys.stderr def tearDown(self): sys.stdout = self._real_out sys.stderr = self._real_err def testBufferOutputOff(self): real_out = self._real_out real_err = self._real_err result = unittest2.TestResult() self.assertFalse(result.buffer) self.assertIs(real_out, sys.stdout) self.assertIs(real_err, sys.stderr) result.startTest(self) self.assertIs(real_out, sys.stdout) self.assertIs(real_err, sys.stderr) def testBufferOutputStartTestAddSuccess(self): real_out = self._real_out real_err = self._real_err result = unittest2.TestResult() self.assertFalse(result.buffer) result.buffer = True self.assertIs(real_out, sys.stdout) self.assertIs(real_err, sys.stderr) result.startTest(self) self.assertIsNot(real_out, sys.stdout) self.assertIsNot(real_err, sys.stderr) self.assertIsInstance(sys.stdout, StringIO) self.assertIsInstance(sys.stderr, StringIO) self.assertIsNot(sys.stdout, sys.stderr) out_stream = sys.stdout err_stream = sys.stderr result._original_stdout = StringIO() result._original_stderr = StringIO() print 'foo' print >> sys.stderr, 'bar' self.assertEqual(out_stream.getvalue(), 'foo\n') self.assertEqual(err_stream.getvalue(), 'bar\n') self.assertEqual(result._original_stdout.getvalue(), '') self.assertEqual(result._original_stderr.getvalue(), '') result.addSuccess(self) result.stopTest(self) self.assertIs(sys.stdout, result._original_stdout) self.assertIs(sys.stderr, result._original_stderr) self.assertEqual(result._original_stdout.getvalue(), '') self.assertEqual(result._original_stderr.getvalue(), '') self.assertEqual(out_stream.getvalue(), '') self.assertEqual(err_stream.getvalue(), '') def getStartedResult(self): result = unittest2.TestResult() result.buffer = True result.startTest(self) return result def testBufferOutputAddErrorOrFailure(self): for message_attr, add_attr, include_error in [ ('errors', 'addError', True), ('failures', 'addFailure', False), ('errors', 'addError', True), ('failures', 'addFailure', False) ]: result = self.getStartedResult() result._original_stderr = StringIO() result._original_stdout = StringIO() print >> sys.stdout, 'foo' if include_error: print >> sys.stderr, 'bar' addFunction = getattr(result, add_attr) addFunction(self, (None, None, None)) result.stopTest(self) result_list = getattr(result, message_attr) self.assertEqual(len(result_list), 1) test, message = result_list[0] expectedOutMessage = textwrap.dedent(""" Stdout: foo """) expectedErrMessage = '' if include_error: expectedErrMessage = textwrap.dedent(""" Stderr: bar """) expectedFullMessage = 'None\n%s%s' % (expectedOutMessage, expectedErrMessage) self.assertIs(test, self) self.assertEqual(result._original_stdout.getvalue(), expectedOutMessage) self.assertEqual(result._original_stderr.getvalue(), expectedErrMessage) self.assertMultiLineEqual(message, expectedFullMessage) if __name__ == '__main__': unittest2.main() distlib-0.2.2/tests/unittest2/test/test_unittest2_with.py0000664000000000000000000001163212030667514022343 0ustar rootrootfrom __future__ import with_statement import unittest2 from unittest2.test.support import OldTestResult, catch_warnings import warnings # needed to enable the deprecation warnings warnings.simplefilter('default') class TestWith(unittest2.TestCase): """Tests that use the with statement live in this module so that all other tests can be run with Python 2.4. """ def testAssertRaisesExcValue(self): class ExceptionMock(Exception): pass def Stub(foo): raise ExceptionMock(foo) v = "particular value" ctx = self.assertRaises(ExceptionMock) with ctx: Stub(v) e = ctx.exception self.assertIsInstance(e, ExceptionMock) self.assertEqual(e.args[0], v) def test_assertRaises(self): def _raise(e): raise e self.assertRaises(KeyError, _raise, KeyError) self.assertRaises(KeyError, _raise, KeyError("key")) try: self.assertRaises(KeyError, lambda: None) except self.failureException, e: self.assertIn("KeyError not raised", e.args) else: self.fail("assertRaises() didn't fail") try: self.assertRaises(KeyError, _raise, ValueError) except ValueError: pass else: self.fail("assertRaises() didn't let exception pass through") with self.assertRaises(KeyError) as cm: try: raise KeyError except Exception, e: raise self.assertIs(cm.exception, e) with self.assertRaises(KeyError): raise KeyError("key") try: with self.assertRaises(KeyError): pass except self.failureException, e: self.assertIn("KeyError not raised", e.args) else: self.fail("assertRaises() didn't fail") try: with self.assertRaises(KeyError): raise ValueError except ValueError: pass else: self.fail("assertRaises() didn't let exception pass through") def test_assert_dict_unicode_error(self): with catch_warnings(record=True): # This causes a UnicodeWarning due to its craziness one = ''.join(chr(i) for i in range(255)) # this used to cause a UnicodeDecodeError constructing the failure msg with self.assertRaises(self.failureException): self.assertDictContainsSubset({'foo': one}, {'foo': u'\uFFFD'}) def test_formatMessage_unicode_error(self): with catch_warnings(record=True): # This causes a UnicodeWarning due to its craziness one = ''.join(chr(i) for i in range(255)) # this used to cause a UnicodeDecodeError constructing msg self._formatMessage(one, u'\uFFFD') def assertOldResultWarning(self, test, failures): with catch_warnings(record=True) as log: result = OldTestResult() test.run(result) self.assertEqual(len(result.failures), failures) warning, = log self.assertIs(warning.category, DeprecationWarning) def test_old_testresult(self): class Test(unittest2.TestCase): def testSkip(self): self.skipTest('foobar') @unittest2.expectedFailure def testExpectedFail(self): raise TypeError @unittest2.expectedFailure def testUnexpectedSuccess(self): pass for test_name, should_pass in (('testSkip', True), ('testExpectedFail', True), ('testUnexpectedSuccess', False)): test = Test(test_name) self.assertOldResultWarning(test, int(not should_pass)) def test_old_testresult_setup(self): class Test(unittest2.TestCase): def setUp(self): self.skipTest('no reason') def testFoo(self): pass self.assertOldResultWarning(Test('testFoo'), 0) def test_old_testresult_class(self): class Test(unittest2.TestCase): def testFoo(self): pass Test = unittest2.skip('no reason')(Test) self.assertOldResultWarning(Test('testFoo'), 0) def testPendingDeprecationMethodNames(self): """Test fail* methods pending deprecation, they will warn in 3.2. Do not use these methods. They will go away in 3.3. """ with catch_warnings(record=True): self.failIfEqual(3, 5) self.failUnlessEqual(3, 3) self.failUnlessAlmostEqual(2.0, 2.0) self.failIfAlmostEqual(3.0, 5.0) self.failUnless(True) self.failUnlessRaises(TypeError, lambda _: 3.14 + u'spam') self.failIf(False) if __name__ == '__main__': unittest2.main() distlib-0.2.2/tests/unittest2/test/test_break.py0000664000000000000000000002041112030667514020426 0ustar rootrootimport gc import os import weakref from cStringIO import StringIO try: import signal except ImportError: signal = None import unittest2 class TestBreak(unittest2.TestCase): def setUp(self): self._default_handler = signal.getsignal(signal.SIGINT) def tearDown(self): signal.signal(signal.SIGINT, self._default_handler) unittest2.signals._results = weakref.WeakKeyDictionary() unittest2.signals._interrupt_handler = None def testInstallHandler(self): default_handler = signal.getsignal(signal.SIGINT) unittest2.installHandler() self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler) try: pid = os.getpid() os.kill(pid, signal.SIGINT) except KeyboardInterrupt: self.fail("KeyboardInterrupt not handled") self.assertTrue(unittest2.signals._interrupt_handler.called) def testRegisterResult(self): result = unittest2.TestResult() unittest2.registerResult(result) for ref in unittest2.signals._results: if ref is result: break elif ref is not result: self.fail("odd object in result set") else: self.fail("result not found") def testInterruptCaught(self): default_handler = signal.getsignal(signal.SIGINT) result = unittest2.TestResult() unittest2.installHandler() unittest2.registerResult(result) self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler) def test(result): pid = os.getpid() os.kill(pid, signal.SIGINT) result.breakCaught = True self.assertTrue(result.shouldStop) try: test(result) except KeyboardInterrupt: self.fail("KeyboardInterrupt not handled") self.assertTrue(result.breakCaught) def testSecondInterrupt(self): result = unittest2.TestResult() unittest2.installHandler() unittest2.registerResult(result) def test(result): pid = os.getpid() os.kill(pid, signal.SIGINT) result.breakCaught = True self.assertTrue(result.shouldStop) os.kill(pid, signal.SIGINT) self.fail("Second KeyboardInterrupt not raised") try: test(result) except KeyboardInterrupt: pass else: self.fail("Second KeyboardInterrupt not raised") self.assertTrue(result.breakCaught) def testTwoResults(self): unittest2.installHandler() result = unittest2.TestResult() unittest2.registerResult(result) new_handler = signal.getsignal(signal.SIGINT) result2 = unittest2.TestResult() unittest2.registerResult(result2) self.assertEqual(signal.getsignal(signal.SIGINT), new_handler) result3 = unittest2.TestResult() def test(result): pid = os.getpid() os.kill(pid, signal.SIGINT) try: test(result) except KeyboardInterrupt: self.fail("KeyboardInterrupt not handled") self.assertTrue(result.shouldStop) self.assertTrue(result2.shouldStop) self.assertFalse(result3.shouldStop) def testHandlerReplacedButCalled(self): # If our handler has been replaced (is no longer installed) but is # called by the *new* handler, then it isn't safe to delay the # SIGINT and we should immediately delegate to the default handler unittest2.installHandler() handler = signal.getsignal(signal.SIGINT) def new_handler(frame, signum): handler(frame, signum) signal.signal(signal.SIGINT, new_handler) try: pid = os.getpid() os.kill(pid, signal.SIGINT) except KeyboardInterrupt: pass else: self.fail("replaced but delegated handler doesn't raise interrupt") def testRunner(self): # Creating a TextTestRunner with the appropriate argument should # register the TextTestResult it creates runner = unittest2.TextTestRunner(stream=StringIO()) result = runner.run(unittest2.TestSuite()) self.assertIn(result, unittest2.signals._results) def testWeakReferences(self): # Calling registerResult on a result should not keep it alive result = unittest2.TestResult() unittest2.registerResult(result) ref = weakref.ref(result) del result # For non-reference counting implementations gc.collect();gc.collect() self.assertIsNone(ref()) def testRemoveResult(self): result = unittest2.TestResult() unittest2.registerResult(result) unittest2.installHandler() self.assertTrue(unittest2.removeResult(result)) # Should this raise an error instead? self.assertFalse(unittest2.removeResult(unittest2.TestResult())) try: pid = os.getpid() os.kill(pid, signal.SIGINT) except KeyboardInterrupt: pass self.assertFalse(result.shouldStop) def testMainInstallsHandler(self): failfast = object() test = object() verbosity = object() result = object() default_handler = signal.getsignal(signal.SIGINT) class FakeRunner(object): initArgs = [] runArgs = [] def __init__(self, *args, **kwargs): self.initArgs.append((args, kwargs)) def run(self, test): self.runArgs.append(test) return result class Program(unittest2.TestProgram): def __init__(self, catchbreak): self.exit = False self.verbosity = verbosity self.failfast = failfast self.catchbreak = catchbreak self.testRunner = FakeRunner self.test = test self.result = None p = Program(False) p.runTests() self.assertEqual(FakeRunner.initArgs, [((), {'verbosity': verbosity, 'failfast': failfast, 'buffer': None})]) self.assertEqual(FakeRunner.runArgs, [test]) self.assertEqual(p.result, result) self.assertEqual(signal.getsignal(signal.SIGINT), default_handler) FakeRunner.initArgs = [] FakeRunner.runArgs = [] p = Program(True) p.runTests() self.assertEqual(FakeRunner.initArgs, [((), {'verbosity': verbosity, 'failfast': failfast, 'buffer': None})]) self.assertEqual(FakeRunner.runArgs, [test]) self.assertEqual(p.result, result) self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler) def testRemoveHandler(self): default_handler = signal.getsignal(signal.SIGINT) unittest2.installHandler() unittest2.removeHandler() self.assertEqual(signal.getsignal(signal.SIGINT), default_handler) # check that calling removeHandler multiple times has no ill-effect unittest2.removeHandler() self.assertEqual(signal.getsignal(signal.SIGINT), default_handler) def testRemoveHandlerAsDecorator(self): default_handler = signal.getsignal(signal.SIGINT) unittest2.installHandler() @unittest2.removeHandler def test(): self.assertEqual(signal.getsignal(signal.SIGINT), default_handler) test() self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler) # Should also skip some tests on Jython skipper = unittest2.skipUnless(hasattr(os, 'kill') and signal is not None, "test uses os.kill(...) and the signal module") TestBreak = skipper(TestBreak) if __name__ == '__main__': unittest2.main() distlib-0.2.2/tests/unittest2/test/test_assertions.py0000664000000000000000000002511112030667514021536 0ustar rootrootimport datetime import unittest2 class Test_Assertions(unittest2.TestCase): def test_AlmostEqual(self): self.assertAlmostEqual(1.00000001, 1.0) self.assertNotAlmostEqual(1.0000001, 1.0) self.assertRaises(self.failureException, self.assertAlmostEqual, 1.0000001, 1.0) self.assertRaises(self.failureException, self.assertNotAlmostEqual, 1.00000001, 1.0) self.assertAlmostEqual(1.1, 1.0, places=0) self.assertRaises(self.failureException, self.assertAlmostEqual, 1.1, 1.0, places=1) self.assertAlmostEqual(0, .1+.1j, places=0) self.assertNotAlmostEqual(0, .1+.1j, places=1) self.assertRaises(self.failureException, self.assertAlmostEqual, 0, .1+.1j, places=1) self.assertRaises(self.failureException, self.assertNotAlmostEqual, 0, .1+.1j, places=0) try: self.assertAlmostEqual(float('inf'), float('inf')) self.assertRaises(self.failureException, self.assertNotAlmostEqual, float('inf'), float('inf')) except ValueError: # float('inf') is invalid on Windows in Python 2.4 / 2.5 x = object() self.assertAlmostEqual(x, x) self.assertRaises(self.failureException, self.assertNotAlmostEqual, x, x) def test_AmostEqualWithDelta(self): self.assertAlmostEqual(1.1, 1.0, delta=0.5) self.assertAlmostEqual(1.0, 1.1, delta=0.5) self.assertNotAlmostEqual(1.1, 1.0, delta=0.05) self.assertNotAlmostEqual(1.0, 1.1, delta=0.05) self.assertRaises(self.failureException, self.assertAlmostEqual, 1.1, 1.0, delta=0.05) self.assertRaises(self.failureException, self.assertNotAlmostEqual, 1.1, 1.0, delta=0.5) self.assertRaises(TypeError, self.assertAlmostEqual, 1.1, 1.0, places=2, delta=2) self.assertRaises(TypeError, self.assertNotAlmostEqual, 1.1, 1.0, places=2, delta=2) first = datetime.datetime.now() second = first + datetime.timedelta(seconds=10) self.assertAlmostEqual(first, second, delta=datetime.timedelta(seconds=20)) self.assertNotAlmostEqual(first, second, delta=datetime.timedelta(seconds=5)) def testAssertNotRegexpMatches(self): self.assertNotRegexpMatches('Ala ma kota', r'r+') try: self.assertNotRegexpMatches('Ala ma kota', r'k.t', 'Message') except self.failureException, e: self.assertIn("'kot'", e.args[0]) self.assertIn('Message', e.args[0]) else: self.fail('assertNotRegexpMatches should have failed.') class TestLongMessage(unittest2.TestCase): """Test that the individual asserts honour longMessage. This actually tests all the message behaviour for asserts that use longMessage.""" def setUp(self): class TestableTestFalse(unittest2.TestCase): longMessage = False failureException = self.failureException def testTest(self): pass class TestableTestTrue(unittest2.TestCase): longMessage = True failureException = self.failureException def testTest(self): pass self.testableTrue = TestableTestTrue('testTest') self.testableFalse = TestableTestFalse('testTest') def testDefault(self): self.assertTrue(unittest2.TestCase.longMessage) def test_formatMsg(self): self.assertEquals(self.testableFalse._formatMessage(None, "foo"), "foo") self.assertEquals(self.testableFalse._formatMessage("foo", "bar"), "foo") self.assertEquals(self.testableTrue._formatMessage(None, "foo"), "foo") self.assertEquals(self.testableTrue._formatMessage("foo", "bar"), "bar : foo") # This blows up if _formatMessage uses string concatenation self.testableTrue._formatMessage(object(), 'foo') def assertMessages(self, methodName, args, errors): def getMethod(i): useTestableFalse = i < 2 if useTestableFalse: test = self.testableFalse else: test = self.testableTrue return getattr(test, methodName) for i, expected_regexp in enumerate(errors): testMethod = getMethod(i) kwargs = {} withMsg = i % 2 if withMsg: kwargs = {"msg": "oops"} self.assertRaisesRegexp(self.failureException, expected_regexp, lambda: testMethod(*args, **kwargs)) def testAssertTrue(self): self.assertMessages('assertTrue', (False,), ["^False is not True$", "^oops$", "^False is not True$", "^False is not True : oops$"]) def testAssertFalse(self): self.assertMessages('assertFalse', (True,), ["^True is not False$", "^oops$", "^True is not False$", "^True is not False : oops$"]) def testNotEqual(self): self.assertMessages('assertNotEqual', (1, 1), ["^1 == 1$", "^oops$", "^1 == 1$", "^1 == 1 : oops$"]) def testAlmostEqual(self): self.assertMessages('assertAlmostEqual', (1, 2), ["^1 != 2 within 7 places$", "^oops$", "^1 != 2 within 7 places$", "^1 != 2 within 7 places : oops$"]) def testNotAlmostEqual(self): self.assertMessages('assertNotAlmostEqual', (1, 1), ["^1 == 1 within 7 places$", "^oops$", "^1 == 1 within 7 places$", "^1 == 1 within 7 places : oops$"]) def test_baseAssertEqual(self): self.assertMessages('_baseAssertEqual', (1, 2), ["^1 != 2$", "^oops$", "^1 != 2$", "^1 != 2 : oops$"]) def testAssertSequenceEqual(self): # Error messages are multiline so not testing on full message # assertTupleEqual and assertListEqual delegate to this method self.assertMessages('assertSequenceEqual', ([], [None]), ["\+ \[None\]$", "^oops$", r"\+ \[None\]$", r"\+ \[None\] : oops$"]) def testAssertSetEqual(self): self.assertMessages('assertSetEqual', (set(), set([None])), ["None$", "^oops$", "None$", "None : oops$"]) def testAssertIn(self): self.assertMessages('assertIn', (None, []), ['^None not found in \[\]$', "^oops$", '^None not found in \[\]$', '^None not found in \[\] : oops$']) def testAssertNotIn(self): self.assertMessages('assertNotIn', (None, [None]), ['^None unexpectedly found in \[None\]$', "^oops$", '^None unexpectedly found in \[None\]$', '^None unexpectedly found in \[None\] : oops$']) def testAssertDictEqual(self): self.assertMessages('assertDictEqual', ({}, {'key': 'value'}), [r"\+ \{'key': 'value'\}$", "^oops$", "\+ \{'key': 'value'\}$", "\+ \{'key': 'value'\} : oops$"]) def testAssertDictContainsSubset(self): self.assertMessages('assertDictContainsSubset', ({'key': 'value'}, {}), ["^Missing: 'key'$", "^oops$", "^Missing: 'key'$", "^Missing: 'key' : oops$"]) def testAssertItemsEqual(self): self.assertMessages('assertItemsEqual', ([], [None]), [r"\[None\]$", "^oops$", r"\[None\]$", r"\[None\] : oops$"]) def testAssertMultiLineEqual(self): self.assertMessages('assertMultiLineEqual', ("", "foo"), [r"\+ foo$", "^oops$", r"\+ foo$", r"\+ foo : oops$"]) def testAssertLess(self): self.assertMessages('assertLess', (2, 1), ["^2 not less than 1$", "^oops$", "^2 not less than 1$", "^2 not less than 1 : oops$"]) def testAssertLessEqual(self): self.assertMessages('assertLessEqual', (2, 1), ["^2 not less than or equal to 1$", "^oops$", "^2 not less than or equal to 1$", "^2 not less than or equal to 1 : oops$"]) def testAssertGreater(self): self.assertMessages('assertGreater', (1, 2), ["^1 not greater than 2$", "^oops$", "^1 not greater than 2$", "^1 not greater than 2 : oops$"]) def testAssertGreaterEqual(self): self.assertMessages('assertGreaterEqual', (1, 2), ["^1 not greater than or equal to 2$", "^oops$", "^1 not greater than or equal to 2$", "^1 not greater than or equal to 2 : oops$"]) def testAssertIsNone(self): self.assertMessages('assertIsNone', ('not None',), ["^'not None' is not None$", "^oops$", "^'not None' is not None$", "^'not None' is not None : oops$"]) def testAssertIsNotNone(self): self.assertMessages('assertIsNotNone', (None,), ["^unexpectedly None$", "^oops$", "^unexpectedly None$", "^unexpectedly None : oops$"]) def testAssertIs(self): self.assertMessages('assertIs', (None, 'foo'), ["^None is not 'foo'$", "^oops$", "^None is not 'foo'$", "^None is not 'foo' : oops$"]) def testAssertIsNot(self): self.assertMessages('assertIsNot', (None, None), ["^unexpectedly identical: None$", "^oops$", "^unexpectedly identical: None$", "^unexpectedly identical: None : oops$"]) if __name__ == '__main__': unittest2.main() distlib-0.2.2/tests/unittest2/test/test_skipping.py0000664000000000000000000001151012030667514021166 0ustar rootrootfrom unittest2.test.support import LoggingResult import unittest2 class Test_TestSkipping(unittest2.TestCase): def test_skipping(self): class Foo(unittest2.TestCase): def test_skip_me(self): self.skipTest("skip") events = [] result = LoggingResult(events) test = Foo("test_skip_me") test.run(result) self.assertEqual(events, ['startTest', 'addSkip', 'stopTest']) self.assertEqual(result.skipped, [(test, "skip")]) # Try letting setUp skip the test now. class Foo(unittest2.TestCase): def setUp(self): self.skipTest("testing") def test_nothing(self): pass events = [] result = LoggingResult(events) test = Foo("test_nothing") test.run(result) self.assertEqual(events, ['startTest', 'addSkip', 'stopTest']) self.assertEqual(result.skipped, [(test, "testing")]) self.assertEqual(result.testsRun, 1) def test_skipping_decorators(self): op_table = ((unittest2.skipUnless, False, True), (unittest2.skipIf, True, False)) for deco, do_skip, dont_skip in op_table: class Foo(unittest2.TestCase): @deco(do_skip, "testing") def test_skip(self): pass @deco(dont_skip, "testing") def test_dont_skip(self): pass test_do_skip = Foo("test_skip") test_dont_skip = Foo("test_dont_skip") suite = unittest2.TestSuite([test_do_skip, test_dont_skip]) events = [] result = LoggingResult(events) suite.run(result) self.assertEqual(len(result.skipped), 1) expected = ['startTest', 'addSkip', 'stopTest', 'startTest', 'addSuccess', 'stopTest'] self.assertEqual(events, expected) self.assertEqual(result.testsRun, 2) self.assertEqual(result.skipped, [(test_do_skip, "testing")]) self.assertTrue(result.wasSuccessful()) def test_skip_class(self): class Foo(unittest2.TestCase): def test_1(self): record.append(1) # was originally a class decorator... Foo = unittest2.skip("testing")(Foo) record = [] result = unittest2.TestResult() test = Foo("test_1") suite = unittest2.TestSuite([test]) suite.run(result) self.assertEqual(result.skipped, [(test, "testing")]) self.assertEqual(record, []) def test_expected_failure(self): class Foo(unittest2.TestCase): @unittest2.expectedFailure def test_die(self): self.fail("help me!") events = [] result = LoggingResult(events) test = Foo("test_die") test.run(result) self.assertEqual(events, ['startTest', 'addExpectedFailure', 'stopTest']) self.assertEqual(result.expectedFailures[0][0], test) self.assertTrue(result.wasSuccessful()) def test_unexpected_success(self): class Foo(unittest2.TestCase): @unittest2.expectedFailure def test_die(self): pass events = [] result = LoggingResult(events) test = Foo("test_die") test.run(result) self.assertEqual(events, ['startTest', 'addUnexpectedSuccess', 'stopTest']) self.assertFalse(result.failures) self.assertEqual(result.unexpectedSuccesses, [test]) self.assertTrue(result.wasSuccessful()) def test_skip_doesnt_run_setup(self): class Foo(unittest2.TestCase): wasSetUp = False wasTornDown = False def setUp(self): Foo.wasSetUp = True def tornDown(self): Foo.wasTornDown = True @unittest2.skip('testing') def test_1(self): pass result = unittest2.TestResult() test = Foo("test_1") suite = unittest2.TestSuite([test]) suite.run(result) self.assertEqual(result.skipped, [(test, "testing")]) self.assertFalse(Foo.wasSetUp) self.assertFalse(Foo.wasTornDown) def test_decorated_skip(self): def decorator(func): def inner(*a): return func(*a) return inner class Foo(unittest2.TestCase): @decorator @unittest2.skip('testing') def test_1(self): pass result = unittest2.TestResult() test = Foo("test_1") suite = unittest2.TestSuite([test]) suite.run(result) self.assertEqual(result.skipped, [(test, "testing")]) if __name__ == '__main__': unittest2.main() distlib-0.2.2/tests/unittest2/test/test_loader.py0000664000000000000000000014034412030667514020620 0ustar rootrootimport sys import types import unittest2 class Test_TestLoader(unittest2.TestCase): ### Tests for TestLoader.loadTestsFromTestCase ################################################################ # "Return a suite of all tests cases contained in the TestCase-derived # class testCaseClass" def test_loadTestsFromTestCase(self): class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foo_bar(self): pass tests = unittest2.TestSuite([Foo('test_1'), Foo('test_2')]) loader = unittest2.TestLoader() self.assertEqual(loader.loadTestsFromTestCase(Foo), tests) # "Return a suite of all tests cases contained in the TestCase-derived # class testCaseClass" # # Make sure it does the right thing even if no tests were found def test_loadTestsFromTestCase__no_matches(self): class Foo(unittest2.TestCase): def foo_bar(self): pass empty_suite = unittest2.TestSuite() loader = unittest2.TestLoader() self.assertEqual(loader.loadTestsFromTestCase(Foo), empty_suite) # "Return a suite of all tests cases contained in the TestCase-derived # class testCaseClass" # # What happens if loadTestsFromTestCase() is given an object # that isn't a subclass of TestCase? Specifically, what happens # if testCaseClass is a subclass of TestSuite? # # This is checked for specifically in the code, so we better add a # test for it. def test_loadTestsFromTestCase__TestSuite_subclass(self): class NotATestCase(unittest2.TestSuite): pass loader = unittest2.TestLoader() try: loader.loadTestsFromTestCase(NotATestCase) except TypeError: pass else: self.fail('Should raise TypeError') # "Return a suite of all tests cases contained in the TestCase-derived # class testCaseClass" # # Make sure loadTestsFromTestCase() picks up the default test method # name (as specified by TestCase), even though the method name does # not match the default TestLoader.testMethodPrefix string def test_loadTestsFromTestCase__default_method_name(self): class Foo(unittest2.TestCase): def runTest(self): pass loader = unittest2.TestLoader() # This has to be false for the test to succeed self.assertFalse('runTest'.startswith(loader.testMethodPrefix)) suite = loader.loadTestsFromTestCase(Foo) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [Foo('runTest')]) ################################################################ ### /Tests for TestLoader.loadTestsFromTestCase ### Tests for TestLoader.loadTestsFromModule ################################################################ # "This method searches `module` for classes derived from TestCase" def test_loadTestsFromModule__TestCase_subclass(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testcase_1 = MyTestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromModule(m) self.assertIsInstance(suite, loader.suiteClass) expected = [loader.suiteClass([MyTestCase('test')])] self.assertEqual(list(suite), expected) # "This method searches `module` for classes derived from TestCase" # # What happens if no tests are found (no TestCase instances)? def test_loadTestsFromModule__no_TestCase_instances(self): m = types.ModuleType('m') loader = unittest2.TestLoader() suite = loader.loadTestsFromModule(m) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), []) # "This method searches `module` for classes derived from TestCase" # # What happens if no tests are found (TestCases instances, but no tests)? def test_loadTestsFromModule__no_TestCase_tests(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): pass m.testcase_1 = MyTestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromModule(m) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [loader.suiteClass()]) # "This method searches `module` for classes derived from TestCase"s # # What happens if loadTestsFromModule() is given something other # than a module? # # XXX Currently, it succeeds anyway. This flexibility # should either be documented or loadTestsFromModule() should # raise a TypeError # # XXX Certain people are using this behaviour. We'll add a test for it def test_loadTestsFromModule__not_a_module(self): class MyTestCase(unittest2.TestCase): def test(self): pass class NotAModule(object): test_2 = MyTestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromModule(NotAModule) reference = [unittest2.TestSuite([MyTestCase('test')])] self.assertEqual(list(suite), reference) # Check that loadTestsFromModule honors (or not) a module # with a load_tests function. def test_loadTestsFromModule__load_tests(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testcase_1 = MyTestCase load_tests_args = [] def load_tests(loader, tests, pattern): self.assertIsInstance(tests, unittest2.TestSuite) load_tests_args.extend((loader, tests, pattern)) return tests m.load_tests = load_tests loader = unittest2.TestLoader() suite = loader.loadTestsFromModule(m) self.assertIsInstance(suite, unittest2.TestSuite) self.assertEquals(load_tests_args, [loader, suite, None]) load_tests_args = [] suite = loader.loadTestsFromModule(m, use_load_tests=False) self.assertEquals(load_tests_args, []) def test_loadTestsFromModule__faulty_load_tests(self): m = types.ModuleType('m') def load_tests(loader, tests, pattern): raise TypeError('some failure') m.load_tests = load_tests loader = unittest2.TestLoader() suite = loader.loadTestsFromModule(m) self.assertIsInstance(suite, unittest2.TestSuite) self.assertEqual(suite.countTestCases(), 1) test = list(suite)[0] self.assertRaisesRegexp(TypeError, "some failure", test.m) ################################################################ ### /Tests for TestLoader.loadTestsFromModule() ### Tests for TestLoader.loadTestsFromName() ################################################################ # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # Is ValueError raised in response to an empty name? def test_loadTestsFromName__empty_name(self): loader = unittest2.TestLoader() try: loader.loadTestsFromName('') except ValueError, e: self.assertEqual(str(e), "Empty module name") else: self.fail("TestLoader.loadTestsFromName failed to raise ValueError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # What happens when the name contains invalid characters? def test_loadTestsFromName__malformed_name(self): loader = unittest2.TestLoader() # XXX Should this raise ValueError or ImportError? try: loader.loadTestsFromName('abc () //') except ValueError: pass except ImportError: pass else: self.fail("TestLoader.loadTestsFromName failed to raise ValueError") # "The specifier name is a ``dotted name'' that may resolve ... to a # module" # # What happens when a module by that name can't be found? def test_loadTestsFromName__unknown_module_name(self): loader = unittest2.TestLoader() try: loader.loadTestsFromName('sdasfasfasdf') except ImportError, e: self.assertEqual(str(e), "No module named sdasfasfasdf") else: self.fail("TestLoader.loadTestsFromName failed to raise ImportError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # What happens when the module is found, but the attribute can't? def test_loadTestsFromName__unknown_attr_name(self): loader = unittest2.TestLoader() try: loader.loadTestsFromName('unittest2.sdasfasfasdf') except AttributeError, e: self.assertEqual(str(e), "'module' object has no attribute 'sdasfasfasdf'") else: self.fail("TestLoader.loadTestsFromName failed to raise AttributeError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # What happens when we provide the module, but the attribute can't be # found? def test_loadTestsFromName__relative_unknown_name(self): loader = unittest2.TestLoader() try: loader.loadTestsFromName('sdasfasfasdf', unittest2) except AttributeError, e: self.assertEqual(str(e), "'module' object has no attribute 'sdasfasfasdf'") else: self.fail("TestLoader.loadTestsFromName failed to raise AttributeError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # ... # "The method optionally resolves name relative to the given module" # # Does loadTestsFromName raise ValueError when passed an empty # name relative to a provided module? # # XXX Should probably raise a ValueError instead of an AttributeError def test_loadTestsFromName__relative_empty_name(self): loader = unittest2.TestLoader() try: loader.loadTestsFromName('', unittest2) except AttributeError: pass else: self.fail("Failed to raise AttributeError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # ... # "The method optionally resolves name relative to the given module" # # What happens when an impossible name is given, relative to the provided # `module`? def test_loadTestsFromName__relative_malformed_name(self): loader = unittest2.TestLoader() # XXX Should this raise AttributeError or ValueError? try: loader.loadTestsFromName('abc () //', unittest2) except ValueError: pass except AttributeError: pass else: self.fail("TestLoader.loadTestsFromName failed to raise ValueError") # "The method optionally resolves name relative to the given module" # # Does loadTestsFromName raise TypeError when the `module` argument # isn't a module object? # # XXX Accepts the not-a-module object, ignorning the object's type # This should raise an exception or the method name should be changed # # XXX Some people are relying on this, so keep it for now def test_loadTestsFromName__relative_not_a_module(self): class MyTestCase(unittest2.TestCase): def test(self): pass class NotAModule(object): test_2 = MyTestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromName('test_2', NotAModule) reference = [MyTestCase('test')] self.assertEqual(list(suite), reference) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # Does it raise an exception if the name resolves to an invalid # object? def test_loadTestsFromName__relative_bad_object(self): m = types.ModuleType('m') m.testcase_1 = object() loader = unittest2.TestLoader() try: loader.loadTestsFromName('testcase_1', m) except TypeError: pass else: self.fail("Should have raised TypeError") # "The specifier name is a ``dotted name'' that may # resolve either to ... a test case class" def test_loadTestsFromName__relative_TestCase_subclass(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testcase_1 = MyTestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromName('testcase_1', m) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [MyTestCase('test')]) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." def test_loadTestsFromName__relative_TestSuite(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testsuite = unittest2.TestSuite([MyTestCase('test')]) loader = unittest2.TestLoader() suite = loader.loadTestsFromName('testsuite', m) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [MyTestCase('test')]) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a test method within a test case class" def test_loadTestsFromName__relative_testmethod(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testcase_1 = MyTestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromName('testcase_1.test', m) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [MyTestCase('test')]) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # Does loadTestsFromName() raise the proper exception when trying to # resolve "a test method within a test case class" that doesn't exist # for the given name (relative to a provided module)? def test_loadTestsFromName__relative_invalid_testmethod(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testcase_1 = MyTestCase loader = unittest2.TestLoader() try: loader.loadTestsFromName('testcase_1.testfoo', m) except AttributeError, e: self.assertEqual(str(e), "type object 'MyTestCase' has no attribute 'testfoo'") else: self.fail("Failed to raise AttributeError") # "The specifier name is a ``dotted name'' that may resolve ... to # ... a callable object which returns a ... TestSuite instance" def test_loadTestsFromName__callable__TestSuite(self): m = types.ModuleType('m') testcase_1 = unittest2.FunctionTestCase(lambda: None) testcase_2 = unittest2.FunctionTestCase(lambda: None) def return_TestSuite(): return unittest2.TestSuite([testcase_1, testcase_2]) m.return_TestSuite = return_TestSuite loader = unittest2.TestLoader() suite = loader.loadTestsFromName('return_TestSuite', m) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [testcase_1, testcase_2]) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a callable object which returns a TestCase ... instance" def test_loadTestsFromName__callable__TestCase_instance(self): m = types.ModuleType('m') testcase_1 = unittest2.FunctionTestCase(lambda: None) def return_TestCase(): return testcase_1 m.return_TestCase = return_TestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromName('return_TestCase', m) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [testcase_1]) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a callable object which returns a TestCase ... instance" #***************************************************************** #Override the suiteClass attribute to ensure that the suiteClass #attribute is used def test_loadTestsFromName__callable__TestCase_instance_ProperSuiteClass(self): class SubTestSuite(unittest2.TestSuite): pass m = types.ModuleType('m') testcase_1 = unittest2.FunctionTestCase(lambda: None) def return_TestCase(): return testcase_1 m.return_TestCase = return_TestCase loader = unittest2.TestLoader() loader.suiteClass = SubTestSuite suite = loader.loadTestsFromName('return_TestCase', m) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [testcase_1]) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a test method within a test case class" #***************************************************************** #Override the suiteClass attribute to ensure that the suiteClass #attribute is used def test_loadTestsFromName__relative_testmethod_ProperSuiteClass(self): class SubTestSuite(unittest2.TestSuite): pass m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testcase_1 = MyTestCase loader = unittest2.TestLoader() loader.suiteClass=SubTestSuite suite = loader.loadTestsFromName('testcase_1.test', m) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [MyTestCase('test')]) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a callable object which returns a TestCase or TestSuite instance" # # What happens if the callable returns something else? def test_loadTestsFromName__callable__wrong_type(self): m = types.ModuleType('m') def return_wrong(): return 6 m.return_wrong = return_wrong loader = unittest2.TestLoader() try: loader.loadTestsFromName('return_wrong', m) except TypeError: pass else: self.fail("TestLoader.loadTestsFromName failed to raise TypeError") # "The specifier can refer to modules and packages which have not been # imported; they will be imported as a side-effect" def test_loadTestsFromName__module_not_loaded(self): # We're going to try to load this module as a side-effect, so it # better not be loaded before we try. # module_name = 'unittest2.test.dummy' sys.modules.pop(module_name, None) loader = unittest2.TestLoader() try: suite = loader.loadTestsFromName(module_name) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), []) # module should now be loaded, thanks to loadTestsFromName() self.assertIn(module_name, sys.modules) finally: if module_name in sys.modules: del sys.modules[module_name] ################################################################ ### Tests for TestLoader.loadTestsFromName() ### Tests for TestLoader.loadTestsFromNames() ################################################################ # "Similar to loadTestsFromName(), but takes a sequence of names rather # than a single name." # # What happens if that sequence of names is empty? def test_loadTestsFromNames__empty_name_list(self): loader = unittest2.TestLoader() suite = loader.loadTestsFromNames([]) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), []) # "Similar to loadTestsFromName(), but takes a sequence of names rather # than a single name." # ... # "The method optionally resolves name relative to the given module" # # What happens if that sequence of names is empty? # # XXX Should this raise a ValueError or just return an empty TestSuite? def test_loadTestsFromNames__relative_empty_name_list(self): loader = unittest2.TestLoader() suite = loader.loadTestsFromNames([], unittest2) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), []) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # Is ValueError raised in response to an empty name? def test_loadTestsFromNames__empty_name(self): loader = unittest2.TestLoader() try: loader.loadTestsFromNames(['']) except ValueError, e: self.assertEqual(str(e), "Empty module name") else: self.fail("TestLoader.loadTestsFromNames failed to raise ValueError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # What happens when presented with an impossible module name? def test_loadTestsFromNames__malformed_name(self): loader = unittest2.TestLoader() # XXX Should this raise ValueError or ImportError? try: loader.loadTestsFromNames(['abc () //']) except ValueError: pass except ImportError: pass else: self.fail("TestLoader.loadTestsFromNames failed to raise ValueError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # What happens when no module can be found for the given name? def test_loadTestsFromNames__unknown_module_name(self): loader = unittest2.TestLoader() try: loader.loadTestsFromNames(['sdasfasfasdf']) except ImportError, e: self.assertEqual(str(e), "No module named sdasfasfasdf") else: self.fail("TestLoader.loadTestsFromNames failed to raise ImportError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # What happens when the module can be found, but not the attribute? def test_loadTestsFromNames__unknown_attr_name(self): loader = unittest2.TestLoader() try: loader.loadTestsFromNames(['unittest2.sdasfasfasdf', 'unittest2']) except AttributeError, e: self.assertEqual(str(e), "'module' object has no attribute 'sdasfasfasdf'") else: self.fail("TestLoader.loadTestsFromNames failed to raise AttributeError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # ... # "The method optionally resolves name relative to the given module" # # What happens when given an unknown attribute on a specified `module` # argument? def test_loadTestsFromNames__unknown_name_relative_1(self): loader = unittest2.TestLoader() try: loader.loadTestsFromNames(['sdasfasfasdf'], unittest2) except AttributeError, e: self.assertEqual(str(e), "'module' object has no attribute 'sdasfasfasdf'") else: self.fail("TestLoader.loadTestsFromName failed to raise AttributeError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # ... # "The method optionally resolves name relative to the given module" # # Do unknown attributes (relative to a provided module) still raise an # exception even in the presence of valid attribute names? def test_loadTestsFromNames__unknown_name_relative_2(self): loader = unittest2.TestLoader() try: loader.loadTestsFromNames(['TestCase', 'sdasfasfasdf'], unittest2) except AttributeError, e: self.assertEqual(str(e), "'module' object has no attribute 'sdasfasfasdf'") else: self.fail("TestLoader.loadTestsFromName failed to raise AttributeError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # ... # "The method optionally resolves name relative to the given module" # # What happens when faced with the empty string? # # XXX This currently raises AttributeError, though ValueError is probably # more appropriate def test_loadTestsFromNames__relative_empty_name(self): loader = unittest2.TestLoader() try: loader.loadTestsFromNames([''], unittest2) except AttributeError: pass else: self.fail("Failed to raise ValueError") # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # ... # "The method optionally resolves name relative to the given module" # # What happens when presented with an impossible attribute name? def test_loadTestsFromNames__relative_malformed_name(self): loader = unittest2.TestLoader() # XXX Should this raise AttributeError or ValueError? try: loader.loadTestsFromNames(['abc () //'], unittest2) except AttributeError: pass except ValueError: pass else: self.fail("TestLoader.loadTestsFromNames failed to raise ValueError") # "The method optionally resolves name relative to the given module" # # Does loadTestsFromNames() make sure the provided `module` is in fact # a module? # # XXX This validation is currently not done. This flexibility should # either be documented or a TypeError should be raised. def test_loadTestsFromNames__relative_not_a_module(self): class MyTestCase(unittest2.TestCase): def test(self): pass class NotAModule(object): test_2 = MyTestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromNames(['test_2'], NotAModule) reference = [unittest2.TestSuite([MyTestCase('test')])] self.assertEqual(list(suite), reference) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # # Does it raise an exception if the name resolves to an invalid # object? def test_loadTestsFromNames__relative_bad_object(self): m = types.ModuleType('m') m.testcase_1 = object() loader = unittest2.TestLoader() try: loader.loadTestsFromNames(['testcase_1'], m) except TypeError: pass else: self.fail("Should have raised TypeError") # "The specifier name is a ``dotted name'' that may resolve ... to # ... a test case class" def test_loadTestsFromNames__relative_TestCase_subclass(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testcase_1 = MyTestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromNames(['testcase_1'], m) self.assertIsInstance(suite, loader.suiteClass) expected = loader.suiteClass([MyTestCase('test')]) self.assertEqual(list(suite), [expected]) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a TestSuite instance" def test_loadTestsFromNames__relative_TestSuite(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testsuite = unittest2.TestSuite([MyTestCase('test')]) loader = unittest2.TestLoader() suite = loader.loadTestsFromNames(['testsuite'], m) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [m.testsuite]) # "The specifier name is a ``dotted name'' that may resolve ... to ... a # test method within a test case class" def test_loadTestsFromNames__relative_testmethod(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testcase_1 = MyTestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromNames(['testcase_1.test'], m) self.assertIsInstance(suite, loader.suiteClass) ref_suite = unittest2.TestSuite([MyTestCase('test')]) self.assertEqual(list(suite), [ref_suite]) # "The specifier name is a ``dotted name'' that may resolve ... to ... a # test method within a test case class" # # Does the method gracefully handle names that initially look like they # resolve to "a test method within a test case class" but don't? def test_loadTestsFromNames__relative_invalid_testmethod(self): m = types.ModuleType('m') class MyTestCase(unittest2.TestCase): def test(self): pass m.testcase_1 = MyTestCase loader = unittest2.TestLoader() try: loader.loadTestsFromNames(['testcase_1.testfoo'], m) except AttributeError, e: self.assertEqual(str(e), "type object 'MyTestCase' has no attribute 'testfoo'") else: self.fail("Failed to raise AttributeError") # "The specifier name is a ``dotted name'' that may resolve ... to # ... a callable object which returns a ... TestSuite instance" def test_loadTestsFromNames__callable__TestSuite(self): m = types.ModuleType('m') testcase_1 = unittest2.FunctionTestCase(lambda: None) testcase_2 = unittest2.FunctionTestCase(lambda: None) def return_TestSuite(): return unittest2.TestSuite([testcase_1, testcase_2]) m.return_TestSuite = return_TestSuite loader = unittest2.TestLoader() suite = loader.loadTestsFromNames(['return_TestSuite'], m) self.assertIsInstance(suite, loader.suiteClass) expected = unittest2.TestSuite([testcase_1, testcase_2]) self.assertEqual(list(suite), [expected]) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a callable object which returns a TestCase ... instance" def test_loadTestsFromNames__callable__TestCase_instance(self): m = types.ModuleType('m') testcase_1 = unittest2.FunctionTestCase(lambda: None) def return_TestCase(): return testcase_1 m.return_TestCase = return_TestCase loader = unittest2.TestLoader() suite = loader.loadTestsFromNames(['return_TestCase'], m) self.assertIsInstance(suite, loader.suiteClass) ref_suite = unittest2.TestSuite([testcase_1]) self.assertEqual(list(suite), [ref_suite]) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a callable object which returns a TestCase or TestSuite instance" # # Are staticmethods handled correctly? def test_loadTestsFromNames__callable__call_staticmethod(self): m = types.ModuleType('m') class Test1(unittest2.TestCase): def test(self): pass testcase_1 = Test1('test') class Foo(unittest2.TestCase): @staticmethod def foo(): return testcase_1 m.Foo = Foo loader = unittest2.TestLoader() suite = loader.loadTestsFromNames(['Foo.foo'], m) self.assertIsInstance(suite, loader.suiteClass) ref_suite = unittest2.TestSuite([testcase_1]) self.assertEqual(list(suite), [ref_suite]) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a callable object which returns a TestCase or TestSuite instance" # # What happens when the callable returns something else? def test_loadTestsFromNames__callable__wrong_type(self): m = types.ModuleType('m') def return_wrong(): return 6 m.return_wrong = return_wrong loader = unittest2.TestLoader() try: loader.loadTestsFromNames(['return_wrong'], m) except TypeError: pass else: self.fail("TestLoader.loadTestsFromNames failed to raise TypeError") # "The specifier can refer to modules and packages which have not been # imported; they will be imported as a side-effect" def test_loadTestsFromNames__module_not_loaded(self): # We're going to try to load this module as a side-effect, so it # better not be loaded before we try. # module_name = 'unittest2.test.dummy' sys.modules.pop(module_name, None) loader = unittest2.TestLoader() try: suite = loader.loadTestsFromNames([module_name]) self.assertIsInstance(suite, loader.suiteClass) self.assertEqual(list(suite), [unittest2.TestSuite()]) # module should now be loaded, thanks to loadTestsFromName() self.assertIn(module_name, sys.modules) finally: if module_name in sys.modules: del sys.modules[module_name] ################################################################ ### /Tests for TestLoader.loadTestsFromNames() ### Tests for TestLoader.getTestCaseNames() ################################################################ # "Return a sorted sequence of method names found within testCaseClass" # # Test.foobar is defined to make sure getTestCaseNames() respects # loader.testMethodPrefix def test_getTestCaseNames(self): class Test(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foobar(self): pass loader = unittest2.TestLoader() self.assertEqual(loader.getTestCaseNames(Test), ['test_1', 'test_2']) # "Return a sorted sequence of method names found within testCaseClass" # # Does getTestCaseNames() behave appropriately if no tests are found? def test_getTestCaseNames__no_tests(self): class Test(unittest2.TestCase): def foobar(self): pass loader = unittest2.TestLoader() self.assertEqual(loader.getTestCaseNames(Test), []) # "Return a sorted sequence of method names found within testCaseClass" # # Are not-TestCases handled gracefully? # # XXX This should raise a TypeError, not return a list # # XXX It's too late in the 2.5 release cycle to fix this, but it should # probably be revisited for 2.6 def test_getTestCaseNames__not_a_TestCase(self): class BadCase(int): def test_foo(self): pass loader = unittest2.TestLoader() names = loader.getTestCaseNames(BadCase) self.assertEqual(names, ['test_foo']) # "Return a sorted sequence of method names found within testCaseClass" # # Make sure inherited names are handled. # # TestP.foobar is defined to make sure getTestCaseNames() respects # loader.testMethodPrefix def test_getTestCaseNames__inheritance(self): class TestP(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foobar(self): pass class TestC(TestP): def test_1(self): pass def test_3(self): pass loader = unittest2.TestLoader() names = ['test_1', 'test_2', 'test_3'] self.assertEqual(loader.getTestCaseNames(TestC), names) ################################################################ ### /Tests for TestLoader.getTestCaseNames() ### Tests for TestLoader.testMethodPrefix ################################################################ # "String giving the prefix of method names which will be interpreted as # test methods" # # Implicit in the documentation is that testMethodPrefix is respected by # all loadTestsFrom* methods. def test_testMethodPrefix__loadTestsFromTestCase(self): class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foo_bar(self): pass tests_1 = unittest2.TestSuite([Foo('foo_bar')]) tests_2 = unittest2.TestSuite([Foo('test_1'), Foo('test_2')]) loader = unittest2.TestLoader() loader.testMethodPrefix = 'foo' self.assertEqual(loader.loadTestsFromTestCase(Foo), tests_1) loader.testMethodPrefix = 'test' self.assertEqual(loader.loadTestsFromTestCase(Foo), tests_2) # "String giving the prefix of method names which will be interpreted as # test methods" # # Implicit in the documentation is that testMethodPrefix is respected by # all loadTestsFrom* methods. def test_testMethodPrefix__loadTestsFromModule(self): m = types.ModuleType('m') class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foo_bar(self): pass m.Foo = Foo tests_1 = [unittest2.TestSuite([Foo('foo_bar')])] tests_2 = [unittest2.TestSuite([Foo('test_1'), Foo('test_2')])] loader = unittest2.TestLoader() loader.testMethodPrefix = 'foo' self.assertEqual(list(loader.loadTestsFromModule(m)), tests_1) loader.testMethodPrefix = 'test' self.assertEqual(list(loader.loadTestsFromModule(m)), tests_2) # "String giving the prefix of method names which will be interpreted as # test methods" # # Implicit in the documentation is that testMethodPrefix is respected by # all loadTestsFrom* methods. def test_testMethodPrefix__loadTestsFromName(self): m = types.ModuleType('m') class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foo_bar(self): pass m.Foo = Foo tests_1 = unittest2.TestSuite([Foo('foo_bar')]) tests_2 = unittest2.TestSuite([Foo('test_1'), Foo('test_2')]) loader = unittest2.TestLoader() loader.testMethodPrefix = 'foo' self.assertEqual(loader.loadTestsFromName('Foo', m), tests_1) loader.testMethodPrefix = 'test' self.assertEqual(loader.loadTestsFromName('Foo', m), tests_2) # "String giving the prefix of method names which will be interpreted as # test methods" # # Implicit in the documentation is that testMethodPrefix is respected by # all loadTestsFrom* methods. def test_testMethodPrefix__loadTestsFromNames(self): m = types.ModuleType('m') class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foo_bar(self): pass m.Foo = Foo tests_1 = unittest2.TestSuite([unittest2.TestSuite([Foo('foo_bar')])]) tests_2 = unittest2.TestSuite([Foo('test_1'), Foo('test_2')]) tests_2 = unittest2.TestSuite([tests_2]) loader = unittest2.TestLoader() loader.testMethodPrefix = 'foo' self.assertEqual(loader.loadTestsFromNames(['Foo'], m), tests_1) loader.testMethodPrefix = 'test' self.assertEqual(loader.loadTestsFromNames(['Foo'], m), tests_2) # "The default value is 'test'" def test_testMethodPrefix__default_value(self): loader = unittest2.TestLoader() self.assertTrue(loader.testMethodPrefix == 'test') ################################################################ ### /Tests for TestLoader.testMethodPrefix ### Tests for TestLoader.sortTestMethodsUsing ################################################################ # "Function to be used to compare method names when sorting them in # getTestCaseNames() and all the loadTestsFromX() methods" def test_sortTestMethodsUsing__loadTestsFromTestCase(self): def reversed_cmp(x, y): return -cmp(x, y) class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass loader = unittest2.TestLoader() loader.sortTestMethodsUsing = reversed_cmp tests = loader.suiteClass([Foo('test_2'), Foo('test_1')]) self.assertEqual(loader.loadTestsFromTestCase(Foo), tests) # "Function to be used to compare method names when sorting them in # getTestCaseNames() and all the loadTestsFromX() methods" def test_sortTestMethodsUsing__loadTestsFromModule(self): def reversed_cmp(x, y): return -cmp(x, y) m = types.ModuleType('m') class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass m.Foo = Foo loader = unittest2.TestLoader() loader.sortTestMethodsUsing = reversed_cmp tests = [loader.suiteClass([Foo('test_2'), Foo('test_1')])] self.assertEqual(list(loader.loadTestsFromModule(m)), tests) # "Function to be used to compare method names when sorting them in # getTestCaseNames() and all the loadTestsFromX() methods" def test_sortTestMethodsUsing__loadTestsFromName(self): def reversed_cmp(x, y): return -cmp(x, y) m = types.ModuleType('m') class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass m.Foo = Foo loader = unittest2.TestLoader() loader.sortTestMethodsUsing = reversed_cmp tests = loader.suiteClass([Foo('test_2'), Foo('test_1')]) self.assertEqual(loader.loadTestsFromName('Foo', m), tests) # "Function to be used to compare method names when sorting them in # getTestCaseNames() and all the loadTestsFromX() methods" def test_sortTestMethodsUsing__loadTestsFromNames(self): def reversed_cmp(x, y): return -cmp(x, y) m = types.ModuleType('m') class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass m.Foo = Foo loader = unittest2.TestLoader() loader.sortTestMethodsUsing = reversed_cmp tests = [loader.suiteClass([Foo('test_2'), Foo('test_1')])] self.assertEqual(list(loader.loadTestsFromNames(['Foo'], m)), tests) # "Function to be used to compare method names when sorting them in # getTestCaseNames()" # # Does it actually affect getTestCaseNames()? def test_sortTestMethodsUsing__getTestCaseNames(self): def reversed_cmp(x, y): return -cmp(x, y) class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass loader = unittest2.TestLoader() loader.sortTestMethodsUsing = reversed_cmp test_names = ['test_2', 'test_1'] self.assertEqual(loader.getTestCaseNames(Foo), test_names) # "The default value is the built-in cmp() function" def test_sortTestMethodsUsing__default_value(self): loader = unittest2.TestLoader() self.assertTrue(loader.sortTestMethodsUsing is cmp) # "it can be set to None to disable the sort." # # XXX How is this different from reassigning cmp? Are the tests returned # in a random order or something? This behaviour should die def test_sortTestMethodsUsing__None(self): class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass loader = unittest2.TestLoader() loader.sortTestMethodsUsing = None test_names = ['test_2', 'test_1'] self.assertEqual(set(loader.getTestCaseNames(Foo)), set(test_names)) ################################################################ ### /Tests for TestLoader.sortTestMethodsUsing ### Tests for TestLoader.suiteClass ################################################################ # "Callable object that constructs a test suite from a list of tests." def test_suiteClass__loadTestsFromTestCase(self): class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foo_bar(self): pass tests = [Foo('test_1'), Foo('test_2')] loader = unittest2.TestLoader() loader.suiteClass = list self.assertEqual(loader.loadTestsFromTestCase(Foo), tests) # It is implicit in the documentation for TestLoader.suiteClass that # all TestLoader.loadTestsFrom* methods respect it. Let's make sure def test_suiteClass__loadTestsFromModule(self): m = types.ModuleType('m') class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foo_bar(self): pass m.Foo = Foo tests = [[Foo('test_1'), Foo('test_2')]] loader = unittest2.TestLoader() loader.suiteClass = list self.assertEqual(loader.loadTestsFromModule(m), tests) # It is implicit in the documentation for TestLoader.suiteClass that # all TestLoader.loadTestsFrom* methods respect it. Let's make sure def test_suiteClass__loadTestsFromName(self): m = types.ModuleType('m') class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foo_bar(self): pass m.Foo = Foo tests = [Foo('test_1'), Foo('test_2')] loader = unittest2.TestLoader() loader.suiteClass = list self.assertEqual(loader.loadTestsFromName('Foo', m), tests) # It is implicit in the documentation for TestLoader.suiteClass that # all TestLoader.loadTestsFrom* methods respect it. Let's make sure def test_suiteClass__loadTestsFromNames(self): m = types.ModuleType('m') class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def foo_bar(self): pass m.Foo = Foo tests = [[Foo('test_1'), Foo('test_2')]] loader = unittest2.TestLoader() loader.suiteClass = list self.assertEqual(loader.loadTestsFromNames(['Foo'], m), tests) # "The default value is the TestSuite class" def test_suiteClass__default_value(self): loader = unittest2.TestLoader() self.assertTrue(loader.suiteClass is unittest2.TestSuite) if __name__ == '__main__': unittest2.main() distlib-0.2.2/tests/unittest2/test/test_program.py0000664000000000000000000001612412030667514021017 0ustar rootrootfrom cStringIO import StringIO import sys import unittest2 hasInstallHandler = hasattr(unittest2, 'installHandler') class Test_TestProgram(unittest2.TestCase): # Horrible white box test def testNoExit(self): result = object() test = object() class FakeRunner(object): def run(self, test): self.test = test return result runner = FakeRunner() oldParseArgs = unittest2.TestProgram.parseArgs def restoreParseArgs(): unittest2.TestProgram.parseArgs = oldParseArgs unittest2.TestProgram.parseArgs = lambda *args: None self.addCleanup(restoreParseArgs) def removeTest(): del unittest2.TestProgram.test unittest2.TestProgram.test = test self.addCleanup(removeTest) program = unittest2.TestProgram(testRunner=runner, exit=False, verbosity=2) self.assertEqual(program.result, result) self.assertEqual(runner.test, test) self.assertEqual(program.verbosity, 2) class FooBar(unittest2.TestCase): def testPass(self): assert True def testFail(self): assert False class FooBarLoader(unittest2.TestLoader): """Test loader that returns a suite containing FooBar.""" def loadTestsFromModule(self, module): return self.suiteClass( [self.loadTestsFromTestCase(Test_TestProgram.FooBar)]) def test_NonExit(self): program = unittest2.main(exit=False, argv=["foobar"], testRunner=unittest2.TextTestRunner(stream=StringIO()), testLoader=self.FooBarLoader()) self.assertTrue(hasattr(program, 'result')) def test_Exit(self): self.assertRaises( SystemExit, unittest2.main, argv=["foobar"], testRunner=unittest2.TextTestRunner(stream=StringIO()), exit=True, testLoader=self.FooBarLoader()) def test_ExitAsDefault(self): self.assertRaises( SystemExit, unittest2.main, argv=["foobar"], testRunner=unittest2.TextTestRunner(stream=StringIO()), testLoader=self.FooBarLoader()) class InitialisableProgram(unittest2.TestProgram): exit = False result = None verbosity = 1 defaultTest = None testRunner = None testLoader = unittest2.defaultTestLoader progName = 'test' test = 'test' def __init__(self, *args): pass RESULT = object() class FakeRunner(object): initArgs = None test = None raiseError = False def __init__(self, **kwargs): FakeRunner.initArgs = kwargs if FakeRunner.raiseError: FakeRunner.raiseError = False raise TypeError def run(self, test): FakeRunner.test = test return RESULT class TestCommandLineArgs(unittest2.TestCase): def setUp(self): self.program = InitialisableProgram() self.program.createTests = lambda: None FakeRunner.initArgs = None FakeRunner.test = None FakeRunner.raiseError = False def testHelpAndUnknown(self): program = self.program def usageExit(msg=None): program.msg = msg program.exit = True program.usageExit = usageExit for opt in '-h', '-H', '--help': program.exit = False program.parseArgs([None, opt]) self.assertTrue(program.exit) self.assertIsNone(program.msg) program.parseArgs([None, '-$']) self.assertTrue(program.exit) self.assertIsNotNone(program.msg) def testVerbosity(self): program = self.program for opt in '-q', '--quiet': program.verbosity = 1 program.parseArgs([None, opt]) self.assertEqual(program.verbosity, 0) for opt in '-v', '--verbose': program.verbosity = 1 program.parseArgs([None, opt]) self.assertEqual(program.verbosity, 2) def testBufferCatchFailfast(self): program = self.program for arg, attr in (('buffer', 'buffer'), ('failfast', 'failfast'), ('catch', 'catchbreak')): if attr == 'catch' and not hasInstallHandler: continue short_opt = '-%s' % arg[0] long_opt = '--%s' % arg for opt in short_opt, long_opt: setattr(program, attr, None) program.parseArgs([None, opt]) self.assertTrue(getattr(program, attr)) for opt in short_opt, long_opt: not_none = object() setattr(program, attr, not_none) program.parseArgs([None, opt]) self.assertEqual(getattr(program, attr), not_none) def testRunTestsRunnerClass(self): program = self.program program.testRunner = FakeRunner program.verbosity = 'verbosity' program.failfast = 'failfast' program.buffer = 'buffer' program.runTests() self.assertEqual(FakeRunner.initArgs, {'verbosity': 'verbosity', 'failfast': 'failfast', 'buffer': 'buffer'}) self.assertEqual(FakeRunner.test, 'test') self.assertIs(program.result, RESULT) def testRunTestsRunnerInstance(self): program = self.program program.testRunner = FakeRunner() FakeRunner.initArgs = None program.runTests() # A new FakeRunner should not have been instantiated self.assertIsNone(FakeRunner.initArgs) self.assertEqual(FakeRunner.test, 'test') self.assertIs(program.result, RESULT) def testRunTestsOldRunnerClass(self): program = self.program FakeRunner.raiseError = True program.testRunner = FakeRunner program.verbosity = 'verbosity' program.failfast = 'failfast' program.buffer = 'buffer' program.test = 'test' program.runTests() # If initialising raises a type error it should be retried # without the new keyword arguments self.assertEqual(FakeRunner.initArgs, {}) self.assertEqual(FakeRunner.test, 'test') self.assertIs(program.result, RESULT) def testCatchBreakInstallsHandler(self): module = sys.modules['unittest2.main'] original = module.installHandler def restore(): module.installHandler = original self.addCleanup(restore) self.installed = False def fakeInstallHandler(): self.installed = True module.installHandler = fakeInstallHandler program = self.program program.catchbreak = True program.testRunner = FakeRunner program.runTests() self.assertTrue(self.installed) if __name__ == '__main__': unittest2.main() distlib-0.2.2/tests/unittest2/test/test_case.py0000664000000000000000000011647112030667514020271 0ustar rootrootimport difflib import pprint import re from copy import deepcopy import unittest2 from unittest2.test.support import ( OldTestResult, EqualityMixin, HashingMixin, LoggingResult ) class MyException(Exception): pass class Test(object): "Keep these TestCase classes out of the main namespace" class Foo(unittest2.TestCase): def runTest(self): pass def test1(self): pass class Bar(Foo): def test2(self): pass class LoggingTestCase(unittest2.TestCase): """A test case which logs its calls.""" def __init__(self, events): super(Test.LoggingTestCase, self).__init__('test') self.events = events def setUp(self): self.events.append('setUp') def test(self): self.events.append('test') def tearDown(self): self.events.append('tearDown') class TestCleanUp(unittest2.TestCase): def testCleanUp(self): class TestableTest(unittest2.TestCase): def testNothing(self): pass test = TestableTest('testNothing') self.assertEqual(test._cleanups, []) cleanups = [] def cleanup1(*args, **kwargs): cleanups.append((1, args, kwargs)) def cleanup2(*args, **kwargs): cleanups.append((2, args, kwargs)) test.addCleanup(cleanup1, 1, 2, 3, four='hello', five='goodbye') test.addCleanup(cleanup2) self.assertEqual(test._cleanups, [(cleanup1, (1, 2, 3), dict(four='hello', five='goodbye')), (cleanup2, (), {})]) result = test.doCleanups() self.assertTrue(result) self.assertEqual(cleanups, [(2, (), {}), (1, (1, 2, 3), dict(four='hello', five='goodbye'))]) def testCleanUpWithErrors(self): class TestableTest(unittest2.TestCase): def testNothing(self): pass class MockResult(object): errors = [] def addError(self, test, exc_info): self.errors.append((test, exc_info)) result = MockResult() test = TestableTest('testNothing') test._resultForDoCleanups = result exc1 = Exception('foo') exc2 = Exception('bar') def cleanup1(): raise exc1 def cleanup2(): raise exc2 test.addCleanup(cleanup1) test.addCleanup(cleanup2) self.assertFalse(test.doCleanups()) (test1, (Type1, instance1, _)), (test2, (Type2, instance2, _)) = reversed(MockResult.errors) self.assertEqual((test1, Type1, instance1), (test, Exception, exc1)) self.assertEqual((test2, Type2, instance2), (test, Exception, exc2)) def testCleanupInRun(self): blowUp = False ordering = [] class TestableTest(unittest2.TestCase): def setUp(self): ordering.append('setUp') if blowUp: raise Exception('foo') def testNothing(self): ordering.append('test') def tearDown(self): ordering.append('tearDown') test = TestableTest('testNothing') def cleanup1(): ordering.append('cleanup1') def cleanup2(): ordering.append('cleanup2') test.addCleanup(cleanup1) test.addCleanup(cleanup2) def success(some_test): self.assertEqual(some_test, test) ordering.append('success') result = unittest2.TestResult() result.addSuccess = success test.run(result) self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup2', 'cleanup1', 'success']) blowUp = True ordering = [] test = TestableTest('testNothing') test.addCleanup(cleanup1) test.run(result) self.assertEqual(ordering, ['setUp', 'cleanup1']) def testTestCaseDebugExecutesCleanups(self): ordering = [] class TestableTest(unittest2.TestCase): def setUp(self): ordering.append('setUp') self.addCleanup(cleanup1) def testNothing(self): ordering.append('test') def tearDown(self): ordering.append('tearDown') test = TestableTest('testNothing') def cleanup1(): ordering.append('cleanup1') test.addCleanup(cleanup2) def cleanup2(): ordering.append('cleanup2') test.debug() self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2']) class Test_TestCase(unittest2.TestCase, EqualityMixin, HashingMixin): ### Set up attributes used by inherited tests ################################################################ # Used by HashingMixin.test_hash and EqualityMixin.test_eq eq_pairs = [(Test.Foo('test1'), Test.Foo('test1'))] # Used by EqualityMixin.test_ne ne_pairs = [(Test.Foo('test1'), Test.Foo('runTest')), (Test.Foo('test1'), Test.Bar('test1')), (Test.Foo('test1'), Test.Bar('test2'))] ################################################################ ### /Set up attributes used by inherited tests # "class TestCase([methodName])" # ... # "Each instance of TestCase will run a single test method: the # method named methodName." # ... # "methodName defaults to "runTest"." # # Make sure it really is optional, and that it defaults to the proper # thing. def test_init__no_test_name(self): class Test(unittest2.TestCase): def runTest(self): raise MyException() def test(self): pass self.assertEqual(Test().id()[-13:], '.Test.runTest') # "class TestCase([methodName])" # ... # "Each instance of TestCase will run a single test method: the # method named methodName." def test_init__test_name__valid(self): class Test(unittest2.TestCase): def runTest(self): raise MyException() def test(self): pass self.assertEqual(Test('test').id()[-10:], '.Test.test') # "class unittest2.TestCase([methodName])" # ... # "Each instance of TestCase will run a single test method: the # method named methodName." def test_init__test_name__invalid(self): class Test(unittest2.TestCase): def runTest(self): raise MyException() def test(self): pass try: Test('testfoo') except ValueError: pass else: self.fail("Failed to raise ValueError") # "Return the number of tests represented by the this test object. For # TestCase instances, this will always be 1" def test_countTestCases(self): class Foo(unittest2.TestCase): def test(self): pass self.assertEqual(Foo('test').countTestCases(), 1) # "Return the default type of test result object to be used to run this # test. For TestCase instances, this will always be # unittest2.TestResult; subclasses of TestCase should # override this as necessary." def test_defaultTestResult(self): class Foo(unittest2.TestCase): def runTest(self): pass result = Foo().defaultTestResult() self.assertEqual(type(result), unittest2.TestResult) # "When a setUp() method is defined, the test runner will run that method # prior to each test. Likewise, if a tearDown() method is defined, the # test runner will invoke that method after each test. In the example, # setUp() was used to create a fresh sequence for each test." # # Make sure the proper call order is maintained, even if setUp() raises # an exception. def test_run_call_order__error_in_setUp(self): events = [] result = LoggingResult(events) class Foo(Test.LoggingTestCase): def setUp(self): super(Foo, self).setUp() raise RuntimeError('raised by Foo.setUp') Foo(events).run(result) expected = ['startTest', 'setUp', 'addError', 'stopTest'] self.assertEqual(events, expected) # "With a temporary result stopTestRun is called when setUp errors. def test_run_call_order__error_in_setUp_default_result(self): events = [] class Foo(Test.LoggingTestCase): def defaultTestResult(self): return LoggingResult(self.events) def setUp(self): super(Foo, self).setUp() raise RuntimeError('raised by Foo.setUp') Foo(events).run() expected = ['startTestRun', 'startTest', 'setUp', 'addError', 'stopTest', 'stopTestRun'] self.assertEqual(events, expected) # "When a setUp() method is defined, the test runner will run that method # prior to each test. Likewise, if a tearDown() method is defined, the # test runner will invoke that method after each test. In the example, # setUp() was used to create a fresh sequence for each test." # # Make sure the proper call order is maintained, even if the test raises # an error (as opposed to a failure). def test_run_call_order__error_in_test(self): events = [] result = LoggingResult(events) class Foo(Test.LoggingTestCase): def test(self): super(Foo, self).test() raise RuntimeError('raised by Foo.test') expected = ['startTest', 'setUp', 'test', 'addError', 'tearDown', 'stopTest'] Foo(events).run(result) self.assertEqual(events, expected) # "With a default result, an error in the test still results in stopTestRun # being called." def test_run_call_order__error_in_test_default_result(self): events = [] class Foo(Test.LoggingTestCase): def defaultTestResult(self): return LoggingResult(self.events) def test(self): super(Foo, self).test() raise RuntimeError('raised by Foo.test') expected = ['startTestRun', 'startTest', 'setUp', 'test', 'addError', 'tearDown', 'stopTest', 'stopTestRun'] Foo(events).run() self.assertEqual(events, expected) # "When a setUp() method is defined, the test runner will run that method # prior to each test. Likewise, if a tearDown() method is defined, the # test runner will invoke that method after each test. In the example, # setUp() was used to create a fresh sequence for each test." # # Make sure the proper call order is maintained, even if the test signals # a failure (as opposed to an error). def test_run_call_order__failure_in_test(self): events = [] result = LoggingResult(events) class Foo(Test.LoggingTestCase): def test(self): super(Foo, self).test() self.fail('raised by Foo.test') expected = ['startTest', 'setUp', 'test', 'addFailure', 'tearDown', 'stopTest'] Foo(events).run(result) self.assertEqual(events, expected) # "When a test fails with a default result stopTestRun is still called." def test_run_call_order__failure_in_test_default_result(self): class Foo(Test.LoggingTestCase): def defaultTestResult(self): return LoggingResult(self.events) def test(self): super(Foo, self).test() self.fail('raised by Foo.test') expected = ['startTestRun', 'startTest', 'setUp', 'test', 'addFailure', 'tearDown', 'stopTest', 'stopTestRun'] events = [] Foo(events).run() self.assertEqual(events, expected) # "When a setUp() method is defined, the test runner will run that method # prior to each test. Likewise, if a tearDown() method is defined, the # test runner will invoke that method after each test. In the example, # setUp() was used to create a fresh sequence for each test." # # Make sure the proper call order is maintained, even if tearDown() raises # an exception. def test_run_call_order__error_in_tearDown(self): events = [] result = LoggingResult(events) class Foo(Test.LoggingTestCase): def tearDown(self): super(Foo, self).tearDown() raise RuntimeError('raised by Foo.tearDown') Foo(events).run(result) expected = ['startTest', 'setUp', 'test', 'tearDown', 'addError', 'stopTest'] self.assertEqual(events, expected) # "When tearDown errors with a default result stopTestRun is still called." def test_run_call_order__error_in_tearDown_default_result(self): class Foo(Test.LoggingTestCase): def defaultTestResult(self): return LoggingResult(self.events) def tearDown(self): super(Foo, self).tearDown() raise RuntimeError('raised by Foo.tearDown') events = [] Foo(events).run() expected = ['startTestRun', 'startTest', 'setUp', 'test', 'tearDown', 'addError', 'stopTest', 'stopTestRun'] self.assertEqual(events, expected) # "TestCase.run() still works when the defaultTestResult is a TestResult # that does not support startTestRun and stopTestRun. def test_run_call_order_default_result(self): class Foo(unittest2.TestCase): def defaultTestResult(self): return OldTestResult() def test(self): pass Foo('test').run() # "This class attribute gives the exception raised by the test() method. # If a test framework needs to use a specialized exception, possibly to # carry additional information, it must subclass this exception in # order to ``play fair'' with the framework. The initial value of this # attribute is AssertionError" def test_failureException__default(self): class Foo(unittest2.TestCase): def test(self): pass self.assertTrue(Foo('test').failureException is AssertionError) # "This class attribute gives the exception raised by the test() method. # If a test framework needs to use a specialized exception, possibly to # carry additional information, it must subclass this exception in # order to ``play fair'' with the framework." # # Make sure TestCase.run() respects the designated failureException def test_failureException__subclassing__explicit_raise(self): events = [] result = LoggingResult(events) class Foo(unittest2.TestCase): def test(self): raise RuntimeError() failureException = RuntimeError self.assertTrue(Foo('test').failureException is RuntimeError) Foo('test').run(result) expected = ['startTest', 'addFailure', 'stopTest'] self.assertEqual(events, expected) # "This class attribute gives the exception raised by the test() method. # If a test framework needs to use a specialized exception, possibly to # carry additional information, it must subclass this exception in # order to ``play fair'' with the framework." # # Make sure TestCase.run() respects the designated failureException def test_failureException__subclassing__implicit_raise(self): events = [] result = LoggingResult(events) class Foo(unittest2.TestCase): def test(self): self.fail("foo") failureException = RuntimeError self.assertTrue(Foo('test').failureException is RuntimeError) Foo('test').run(result) expected = ['startTest', 'addFailure', 'stopTest'] self.assertEqual(events, expected) # "The default implementation does nothing." def test_setUp(self): class Foo(unittest2.TestCase): def runTest(self): pass # ... and nothing should happen Foo().setUp() # "The default implementation does nothing." def test_tearDown(self): class Foo(unittest2.TestCase): def runTest(self): pass # ... and nothing should happen Foo().tearDown() # "Return a string identifying the specific test case." # # Because of the vague nature of the docs, I'm not going to lock this # test down too much. Really all that can be asserted is that the id() # will be a string (either 8-byte or unicode -- again, because the docs # just say "string") def test_id(self): class Foo(unittest2.TestCase): def runTest(self): pass self.assertIsInstance(Foo().id(), basestring) # "If result is omitted or None, a temporary result object is created # and used, but is not made available to the caller. As TestCase owns the # temporary result startTestRun and stopTestRun are called. def test_run__uses_defaultTestResult(self): events = [] class Foo(unittest2.TestCase): def test(self): events.append('test') def defaultTestResult(self): return LoggingResult(events) # Make run() find a result object on its own Foo('test').run() expected = ['startTestRun', 'startTest', 'test', 'addSuccess', 'stopTest', 'stopTestRun'] self.assertEqual(events, expected) def testShortDescriptionWithoutDocstring(self): self.assertIsNone(self.shortDescription()) def testShortDescriptionWithOneLineDocstring(self): """Tests shortDescription() for a method with a docstring.""" self.assertEqual( self.shortDescription(), 'Tests shortDescription() for a method with a docstring.') def testShortDescriptionWithMultiLineDocstring(self): """Tests shortDescription() for a method with a longer docstring. This method ensures that only the first line of a docstring is returned used in the short description, no matter how long the whole thing is. """ self.assertEqual( self.shortDescription(), 'Tests shortDescription() for a method with a longer ' 'docstring.') def testAddTypeEqualityFunc(self): class SadSnake(object): """Dummy class for test_addTypeEqualityFunc.""" s1, s2 = SadSnake(), SadSnake() self.assertNotEqual(s1, s2) def AllSnakesCreatedEqual(a, b, msg=None): return type(a) is type(b) is SadSnake self.addTypeEqualityFunc(SadSnake, AllSnakesCreatedEqual) self.assertEqual(s1, s2) # No this doesn't clean up and remove the SadSnake equality func # from this TestCase instance but since its a local nothing else # will ever notice that. def testAssertIs(self): thing = object() self.assertIs(thing, thing) self.assertRaises(self.failureException, self.assertIs, thing, object()) def testAssertIsNot(self): thing = object() self.assertIsNot(thing, object()) self.assertRaises(self.failureException, self.assertIsNot, thing, thing) def testAssertIsInstance(self): thing = [] self.assertIsInstance(thing, list) self.assertRaises(self.failureException, self.assertIsInstance, thing, dict) def testAssertNotIsInstance(self): thing = [] self.assertNotIsInstance(thing, dict) self.assertRaises(self.failureException, self.assertNotIsInstance, thing, list) def testAssertIn(self): animals = {'monkey': 'banana', 'cow': 'grass', 'seal': 'fish'} self.assertIn('a', 'abc') self.assertIn(2, [1, 2, 3]) self.assertIn('monkey', animals) self.assertNotIn('d', 'abc') self.assertNotIn(0, [1, 2, 3]) self.assertNotIn('otter', animals) self.assertRaises(self.failureException, self.assertIn, 'x', 'abc') self.assertRaises(self.failureException, self.assertIn, 4, [1, 2, 3]) self.assertRaises(self.failureException, self.assertIn, 'elephant', animals) self.assertRaises(self.failureException, self.assertNotIn, 'c', 'abc') self.assertRaises(self.failureException, self.assertNotIn, 1, [1, 2, 3]) self.assertRaises(self.failureException, self.assertNotIn, 'cow', animals) def testAssertDictContainsSubset(self): self.assertDictContainsSubset({}, {}) self.assertDictContainsSubset({}, {'a': 1}) self.assertDictContainsSubset({'a': 1}, {'a': 1}) self.assertDictContainsSubset({'a': 1}, {'a': 1, 'b': 2}) self.assertDictContainsSubset({'a': 1, 'b': 2}, {'a': 1, 'b': 2}) self.assertRaises(unittest2.TestCase.failureException, self.assertDictContainsSubset, {'a': 2}, {'a': 1}, '.*Mismatched values:.*') self.assertRaises(unittest2.TestCase.failureException, self.assertDictContainsSubset, {'c': 1}, {'a': 1}, '.*Missing:.*') self.assertRaises(unittest2.TestCase.failureException, self.assertDictContainsSubset, {'a': 1, 'c': 1}, {'a': 1}, '.*Missing:.*') self.assertRaises(unittest2.TestCase.failureException, self.assertDictContainsSubset, {'a': 1, 'c': 1}, {'a': 1}, '.*Missing:.*Mismatched values:.*') self.assertRaises(self.failureException, self.assertDictContainsSubset, {1: "one"}, {}) def testAssertEqual(self): equal_pairs = [ ((), ()), ({}, {}), ([], []), (set(), set()), (frozenset(), frozenset())] for a, b in equal_pairs: # This mess of try excepts is to test the assertEqual behavior # itself. try: self.assertEqual(a, b) except self.failureException: self.fail('assertEqual(%r, %r) failed' % (a, b)) try: self.assertEqual(a, b, msg='foo') except self.failureException: self.fail('assertEqual(%r, %r) with msg= failed' % (a, b)) try: self.assertEqual(a, b, 'foo') except self.failureException: self.fail('assertEqual(%r, %r) with third parameter failed' % (a, b)) unequal_pairs = [ ((), []), ({}, set()), (set([4,1]), frozenset([4,2])), (frozenset([4,5]), set([2,3])), (set([3,4]), set([5,4]))] for a, b in unequal_pairs: self.assertRaises(self.failureException, self.assertEqual, a, b) self.assertRaises(self.failureException, self.assertEqual, a, b, 'foo') self.assertRaises(self.failureException, self.assertEqual, a, b, msg='foo') def testEquality(self): self.assertListEqual([], []) self.assertTupleEqual((), ()) self.assertSequenceEqual([], ()) a = [0, 'a', []] b = [] self.assertRaises(unittest2.TestCase.failureException, self.assertListEqual, a, b) self.assertRaises(unittest2.TestCase.failureException, self.assertListEqual, tuple(a), tuple(b)) self.assertRaises(unittest2.TestCase.failureException, self.assertSequenceEqual, a, tuple(b)) b.extend(a) self.assertListEqual(a, b) self.assertTupleEqual(tuple(a), tuple(b)) self.assertSequenceEqual(a, tuple(b)) self.assertSequenceEqual(tuple(a), b) self.assertRaises(self.failureException, self.assertListEqual, a, tuple(b)) self.assertRaises(self.failureException, self.assertTupleEqual, tuple(a), b) self.assertRaises(self.failureException, self.assertListEqual, None, b) self.assertRaises(self.failureException, self.assertTupleEqual, None, tuple(b)) self.assertRaises(self.failureException, self.assertSequenceEqual, None, tuple(b)) self.assertRaises(self.failureException, self.assertListEqual, 1, 1) self.assertRaises(self.failureException, self.assertTupleEqual, 1, 1) self.assertRaises(self.failureException, self.assertSequenceEqual, 1, 1) self.assertDictEqual({}, {}) c = { 'x': 1 } d = {} self.assertRaises(unittest2.TestCase.failureException, self.assertDictEqual, c, d) d.update(c) self.assertDictEqual(c, d) d['x'] = 0 self.assertRaises(unittest2.TestCase.failureException, self.assertDictEqual, c, d, 'These are unequal') self.assertRaises(self.failureException, self.assertDictEqual, None, d) self.assertRaises(self.failureException, self.assertDictEqual, [], d) self.assertRaises(self.failureException, self.assertDictEqual, 1, 1) def testAssertItemsEqual(self): self.assertItemsEqual([1, 2, 3], [3, 2, 1]) self.assertItemsEqual(['foo', 'bar', 'baz'], ['bar', 'baz', 'foo']) self.assertRaises(self.failureException, self.assertItemsEqual, [10], [10, 11]) self.assertRaises(self.failureException, self.assertItemsEqual, [10, 11], [10]) self.assertRaises(self.failureException, self.assertItemsEqual, [10, 11, 10], [10, 11]) # Test that sequences of unhashable objects can be tested for sameness: self.assertItemsEqual([[1, 2], [3, 4]], [[3, 4], [1, 2]]) self.assertItemsEqual([{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 1}]) self.assertRaises(self.failureException, self.assertItemsEqual, [[1]], [[2]]) # Test unsortable objects self.assertItemsEqual([2j, None], [None, 2j]) self.assertRaises(self.failureException, self.assertItemsEqual, [2j, None], [None, 3j]) def testAssertSetEqual(self): set1 = set() set2 = set() self.assertSetEqual(set1, set2) self.assertRaises(self.failureException, self.assertSetEqual, None, set2) self.assertRaises(self.failureException, self.assertSetEqual, [], set2) self.assertRaises(self.failureException, self.assertSetEqual, set1, None) self.assertRaises(self.failureException, self.assertSetEqual, set1, []) set1 = set(['a']) set2 = set() self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) set1 = set(['a']) set2 = set(['a']) self.assertSetEqual(set1, set2) set1 = set(['a']) set2 = set(['a', 'b']) self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) set1 = set(['a']) set2 = frozenset(['a', 'b']) self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) set1 = set(['a', 'b']) set2 = frozenset(['a', 'b']) self.assertSetEqual(set1, set2) set1 = set() set2 = "foo" self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) self.assertRaises(self.failureException, self.assertSetEqual, set2, set1) # make sure any string formatting is tuple-safe set1 = set([(0, 1), (2, 3)]) set2 = set([(4, 5)]) self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) def testInequality(self): # Try ints self.assertGreater(2, 1) self.assertGreaterEqual(2, 1) self.assertGreaterEqual(1, 1) self.assertLess(1, 2) self.assertLessEqual(1, 2) self.assertLessEqual(1, 1) self.assertRaises(self.failureException, self.assertGreater, 1, 2) self.assertRaises(self.failureException, self.assertGreater, 1, 1) self.assertRaises(self.failureException, self.assertGreaterEqual, 1, 2) self.assertRaises(self.failureException, self.assertLess, 2, 1) self.assertRaises(self.failureException, self.assertLess, 1, 1) self.assertRaises(self.failureException, self.assertLessEqual, 2, 1) # Try Floats self.assertGreater(1.1, 1.0) self.assertGreaterEqual(1.1, 1.0) self.assertGreaterEqual(1.0, 1.0) self.assertLess(1.0, 1.1) self.assertLessEqual(1.0, 1.1) self.assertLessEqual(1.0, 1.0) self.assertRaises(self.failureException, self.assertGreater, 1.0, 1.1) self.assertRaises(self.failureException, self.assertGreater, 1.0, 1.0) self.assertRaises(self.failureException, self.assertGreaterEqual, 1.0, 1.1) self.assertRaises(self.failureException, self.assertLess, 1.1, 1.0) self.assertRaises(self.failureException, self.assertLess, 1.0, 1.0) self.assertRaises(self.failureException, self.assertLessEqual, 1.1, 1.0) # Try Strings self.assertGreater('bug', 'ant') self.assertGreaterEqual('bug', 'ant') self.assertGreaterEqual('ant', 'ant') self.assertLess('ant', 'bug') self.assertLessEqual('ant', 'bug') self.assertLessEqual('ant', 'ant') self.assertRaises(self.failureException, self.assertGreater, 'ant', 'bug') self.assertRaises(self.failureException, self.assertGreater, 'ant', 'ant') self.assertRaises(self.failureException, self.assertGreaterEqual, 'ant', 'bug') self.assertRaises(self.failureException, self.assertLess, 'bug', 'ant') self.assertRaises(self.failureException, self.assertLess, 'ant', 'ant') self.assertRaises(self.failureException, self.assertLessEqual, 'bug', 'ant') # Try Unicode self.assertGreater(u'bug', u'ant') self.assertGreaterEqual(u'bug', u'ant') self.assertGreaterEqual(u'ant', u'ant') self.assertLess(u'ant', u'bug') self.assertLessEqual(u'ant', u'bug') self.assertLessEqual(u'ant', u'ant') self.assertRaises(self.failureException, self.assertGreater, u'ant', u'bug') self.assertRaises(self.failureException, self.assertGreater, u'ant', u'ant') self.assertRaises(self.failureException, self.assertGreaterEqual, u'ant', u'bug') self.assertRaises(self.failureException, self.assertLess, u'bug', u'ant') self.assertRaises(self.failureException, self.assertLess, u'ant', u'ant') self.assertRaises(self.failureException, self.assertLessEqual, u'bug', u'ant') # Try Mixed String/Unicode self.assertGreater('bug', u'ant') self.assertGreater(u'bug', 'ant') self.assertGreaterEqual('bug', u'ant') self.assertGreaterEqual(u'bug', 'ant') self.assertGreaterEqual('ant', u'ant') self.assertGreaterEqual(u'ant', 'ant') self.assertLess('ant', u'bug') self.assertLess(u'ant', 'bug') self.assertLessEqual('ant', u'bug') self.assertLessEqual(u'ant', 'bug') self.assertLessEqual('ant', u'ant') self.assertLessEqual(u'ant', 'ant') self.assertRaises(self.failureException, self.assertGreater, 'ant', u'bug') self.assertRaises(self.failureException, self.assertGreater, u'ant', 'bug') self.assertRaises(self.failureException, self.assertGreater, 'ant', u'ant') self.assertRaises(self.failureException, self.assertGreater, u'ant', 'ant') self.assertRaises(self.failureException, self.assertGreaterEqual, 'ant', u'bug') self.assertRaises(self.failureException, self.assertGreaterEqual, u'ant', 'bug') self.assertRaises(self.failureException, self.assertLess, 'bug', u'ant') self.assertRaises(self.failureException, self.assertLess, u'bug', 'ant') self.assertRaises(self.failureException, self.assertLess, 'ant', u'ant') self.assertRaises(self.failureException, self.assertLess, u'ant', 'ant') self.assertRaises(self.failureException, self.assertLessEqual, 'bug', u'ant') self.assertRaises(self.failureException, self.assertLessEqual, u'bug', 'ant') def testAssertMultiLineEqual(self): sample_text = """\ http://www.python.org/doc/2.3/lib/module-unittest.html test case A test case is the smallest unit of testing. [...] """ revised_sample_text = """\ http://www.python.org/doc/2.4.1/lib/module-unittest.html test case A test case is the smallest unit of testing. [...] You may provide your own implementation that does not subclass from TestCase, of course. """ sample_text_error = """\ - http://www.python.org/doc/2.3/lib/module-unittest.html ? ^ + http://www.python.org/doc/2.4.1/lib/module-unittest.html ? ^^^ test case - A test case is the smallest unit of testing. [...] + A test case is the smallest unit of testing. [...] You may provide your ? +++++++++++++++++++++ + own implementation that does not subclass from TestCase, of course. """ self.maxDiff = None for type_changer in (lambda x: x, lambda x: x.decode('utf8')): try: self.assertMultiLineEqual(type_changer(sample_text), type_changer(revised_sample_text)) except self.failureException, e: # need to remove the first line of the error message error = str(e).encode('utf8').split('\n', 1)[1] # assertMultiLineEqual is hooked up as the default for # unicode strings - so we can't use it for this check self.assertTrue(sample_text_error == error) def testAssertSequenceEqualMaxDiff(self): self.assertEqual(self.maxDiff, 80*8) seq1 = 'a' + 'x' * 80**2 seq2 = 'b' + 'x' * 80**2 diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) # the +1 is the leading \n added by assertSequenceEqual omitted = unittest2.case.DIFF_OMITTED % (len(diff) + 1,) self.maxDiff = len(diff)//2 try: self.assertSequenceEqual(seq1, seq2) except self.failureException, e: msg = e.args[0] else: self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) < len(diff)) self.assertIn(omitted, msg) self.maxDiff = len(diff) * 2 try: self.assertSequenceEqual(seq1, seq2) except self.failureException, e: msg = e.args[0] else: self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) > len(diff)) self.assertNotIn(omitted, msg) self.maxDiff = None try: self.assertSequenceEqual(seq1, seq2) except self.failureException, e: msg = e.args[0] else: self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) > len(diff)) self.assertNotIn(omitted, msg) def testTruncateMessage(self): self.maxDiff = 1 message = self._truncateMessage('foo', 'bar') omitted = unittest2.case.DIFF_OMITTED % len('bar') self.assertEqual(message, 'foo' + omitted) self.maxDiff = None message = self._truncateMessage('foo', 'bar') self.assertEqual(message, 'foobar') self.maxDiff = 4 message = self._truncateMessage('foo', 'bar') self.assertEqual(message, 'foobar') def testAssertDictEqualTruncates(self): test = unittest2.TestCase('assertEqual') def truncate(msg, diff): return 'foo' test._truncateMessage = truncate try: test.assertDictEqual({}, {1: 0}) except self.failureException, e: self.assertEqual(str(e), 'foo') else: self.fail('assertDictEqual did not fail') def testAssertMultiLineEqualTruncates(self): test = unittest2.TestCase('assertEqual') def truncate(msg, diff): return 'foo' test._truncateMessage = truncate try: test.assertMultiLineEqual('foo', 'bar') except self.failureException, e: self.assertEqual(str(e), 'foo') else: self.fail('assertMultiLineEqual did not fail') def testAssertIsNone(self): self.assertIsNone(None) self.assertRaises(self.failureException, self.assertIsNone, False) self.assertIsNotNone('DjZoPloGears on Rails') self.assertRaises(self.failureException, self.assertIsNotNone, None) def testAssertRegexpMatches(self): self.assertRegexpMatches('asdfabasdf', r'ab+') self.assertRaises(self.failureException, self.assertRegexpMatches, 'saaas', r'aaaa') def testAssertRaisesRegexp(self): class ExceptionMock(Exception): pass def Stub(): raise ExceptionMock('We expect') self.assertRaisesRegexp(ExceptionMock, re.compile('expect$'), Stub) self.assertRaisesRegexp(ExceptionMock, 'expect$', Stub) self.assertRaisesRegexp(ExceptionMock, u'expect$', Stub) def testAssertNotRaisesRegexp(self): self.assertRaisesRegexp( self.failureException, '^Exception not raised$', self.assertRaisesRegexp, Exception, re.compile('x'), lambda: None) self.assertRaisesRegexp( self.failureException, '^Exception not raised$', self.assertRaisesRegexp, Exception, 'x', lambda: None) self.assertRaisesRegexp( self.failureException, '^Exception not raised$', self.assertRaisesRegexp, Exception, u'x', lambda: None) def testAssertRaisesRegexpMismatch(self): def Stub(): raise Exception('Unexpected') self.assertRaisesRegexp( self.failureException, r'"\^Expected\$" does not match "Unexpected"', self.assertRaisesRegexp, Exception, '^Expected$', Stub) self.assertRaisesRegexp( self.failureException, r'"\^Expected\$" does not match "Unexpected"', self.assertRaisesRegexp, Exception, u'^Expected$', Stub) self.assertRaisesRegexp( self.failureException, r'"\^Expected\$" does not match "Unexpected"', self.assertRaisesRegexp, Exception, re.compile('^Expected$'), Stub) def testSynonymAssertMethodNames(self): """Test undocumented method name synonyms. Please do not use these methods names in your own code. This test confirms their continued existence and functionality in order to avoid breaking existing code. """ self.assertNotEquals(3, 5) self.assertEquals(3, 3) self.assertAlmostEquals(2.0, 2.0) self.assertNotAlmostEquals(3.0, 5.0) self.assert_(True) def testDeepcopy(self): # Issue: 5660 class TestableTest(unittest2.TestCase): def testNothing(self): pass test = TestableTest('testNothing') # This shouldn't blow up deepcopy(test) if __name__ == "__main__": unittest2.main() distlib-0.2.2/tests/unittest2/test/test_runner.py0000664000000000000000000001104412030667514020655 0ustar rootrootimport pickle from cStringIO import StringIO from unittest2.test.support import LoggingResult, OldTestResult import unittest2 class Test_TextTestRunner(unittest2.TestCase): """Tests for TextTestRunner.""" def test_init(self): runner = unittest2.TextTestRunner() self.assertFalse(runner.failfast) self.assertFalse(runner.buffer) self.assertEqual(runner.verbosity, 1) self.assertTrue(runner.descriptions) self.assertEqual(runner.resultclass, unittest2.TextTestResult) def testBufferAndFailfast(self): class Test(unittest2.TestCase): def testFoo(self): pass result = unittest2.TestResult() runner = unittest2.TextTestRunner(stream=StringIO(), failfast=True, buffer=True) # Use our result object runner._makeResult = lambda: result runner.run(Test('testFoo')) self.assertTrue(result.failfast) self.assertTrue(result.buffer) def testRunnerRegistersResult(self): class Test(unittest2.TestCase): def testFoo(self): pass originalRegisterResult = unittest2.runner.registerResult def cleanup(): unittest2.runner.registerResult = originalRegisterResult self.addCleanup(cleanup) result = unittest2.TestResult() runner = unittest2.TextTestRunner(stream=StringIO()) # Use our result object runner._makeResult = lambda: result self.wasRegistered = 0 def fakeRegisterResult(thisResult): self.wasRegistered += 1 self.assertEqual(thisResult, result) unittest2.runner.registerResult = fakeRegisterResult runner.run(unittest2.TestSuite()) self.assertEqual(self.wasRegistered, 1) def test_works_with_result_without_startTestRun_stopTestRun(self): class OldTextResult(OldTestResult): def __init__(self, *_): super(OldTextResult, self).__init__() separator2 = '' def printErrors(self): pass runner = unittest2.TextTestRunner(stream=StringIO(), resultclass=OldTextResult) runner.run(unittest2.TestSuite()) def test_startTestRun_stopTestRun_called(self): class LoggingTextResult(LoggingResult): separator2 = '' def printErrors(self): pass class LoggingRunner(unittest2.TextTestRunner): def __init__(self, events): super(LoggingRunner, self).__init__(StringIO()) self._events = events def _makeResult(self): return LoggingTextResult(self._events) events = [] runner = LoggingRunner(events) runner.run(unittest2.TestSuite()) expected = ['startTestRun', 'stopTestRun'] self.assertEqual(events, expected) def test_pickle_unpickle(self): # Issue #7197: a TextTestRunner should be (un)pickleable. This is # required by test_multiprocessing under Windows (in verbose mode). import StringIO # cStringIO objects are not pickleable, but StringIO objects are. stream = StringIO.StringIO("foo") runner = unittest2.TextTestRunner(stream) for protocol in range(pickle.HIGHEST_PROTOCOL + 1): s = pickle.dumps(runner, protocol=protocol) obj = pickle.loads(s) # StringIO objects never compare equal, a cheap test instead. self.assertEqual(obj.stream.getvalue(), stream.getvalue()) def test_resultclass(self): def MockResultClass(*args): return args STREAM = object() DESCRIPTIONS = object() VERBOSITY = object() runner = unittest2.TextTestRunner(STREAM, DESCRIPTIONS, VERBOSITY, resultclass=MockResultClass) self.assertEqual(runner.resultclass, MockResultClass) expectedresult = (runner.stream, DESCRIPTIONS, VERBOSITY) self.assertEqual(runner._makeResult(), expectedresult) def test_oldresult(self): class Test(unittest2.TestCase): def testFoo(self): pass runner = unittest2.TextTestRunner(resultclass=OldTestResult, stream=StringIO()) # This will raise an exception if TextTestRunner can't handle old # test result objects runner.run(Test('testFoo')) if __name__ == '__main__': unittest2.main()distlib-0.2.2/tests/unittest2/test/test_functiontestcase.py0000664000000000000000000001270212030667514022727 0ustar rootrootimport unittest2 from unittest2.test.support import LoggingResult class Test_FunctionTestCase(unittest2.TestCase): # "Return the number of tests represented by the this test object. For # unittest2.TestCase instances, this will always be 1" def test_countTestCases(self): test = unittest2.FunctionTestCase(lambda: None) self.assertEqual(test.countTestCases(), 1) # "When a setUp() method is defined, the test runner will run that method # prior to each test. Likewise, if a tearDown() method is defined, the # test runner will invoke that method after each test. In the example, # setUp() was used to create a fresh sequence for each test." # # Make sure the proper call order is maintained, even if setUp() raises # an exception. def test_run_call_order__error_in_setUp(self): events = [] result = LoggingResult(events) def setUp(): events.append('setUp') raise RuntimeError('raised by setUp') def test(): events.append('test') def tearDown(): events.append('tearDown') expected = ['startTest', 'setUp', 'addError', 'stopTest'] unittest2.FunctionTestCase(test, setUp, tearDown).run(result) self.assertEqual(events, expected) # "When a setUp() method is defined, the test runner will run that method # prior to each test. Likewise, if a tearDown() method is defined, the # test runner will invoke that method after each test. In the example, # setUp() was used to create a fresh sequence for each test." # # Make sure the proper call order is maintained, even if the test raises # an error (as opposed to a failure). def test_run_call_order__error_in_test(self): events = [] result = LoggingResult(events) def setUp(): events.append('setUp') def test(): events.append('test') raise RuntimeError('raised by test') def tearDown(): events.append('tearDown') expected = ['startTest', 'setUp', 'test', 'addError', 'tearDown', 'stopTest'] unittest2.FunctionTestCase(test, setUp, tearDown).run(result) self.assertEqual(events, expected) # "When a setUp() method is defined, the test runner will run that method # prior to each test. Likewise, if a tearDown() method is defined, the # test runner will invoke that method after each test. In the example, # setUp() was used to create a fresh sequence for each test." # # Make sure the proper call order is maintained, even if the test signals # a failure (as opposed to an error). def test_run_call_order__failure_in_test(self): events = [] result = LoggingResult(events) def setUp(): events.append('setUp') def test(): events.append('test') self.fail('raised by test') def tearDown(): events.append('tearDown') expected = ['startTest', 'setUp', 'test', 'addFailure', 'tearDown', 'stopTest'] unittest2.FunctionTestCase(test, setUp, tearDown).run(result) self.assertEqual(events, expected) # "When a setUp() method is defined, the test runner will run that method # prior to each test. Likewise, if a tearDown() method is defined, the # test runner will invoke that method after each test. In the example, # setUp() was used to create a fresh sequence for each test." # # Make sure the proper call order is maintained, even if tearDown() raises # an exception. def test_run_call_order__error_in_tearDown(self): events = [] result = LoggingResult(events) def setUp(): events.append('setUp') def test(): events.append('test') def tearDown(): events.append('tearDown') raise RuntimeError('raised by tearDown') expected = ['startTest', 'setUp', 'test', 'tearDown', 'addError', 'stopTest'] unittest2.FunctionTestCase(test, setUp, tearDown).run(result) self.assertEqual(events, expected) # "Return a string identifying the specific test case." # # Because of the vague nature of the docs, I'm not going to lock this # test down too much. Really all that can be asserted is that the id() # will be a string (either 8-byte or unicode -- again, because the docs # just say "string") def test_id(self): test = unittest2.FunctionTestCase(lambda: None) self.assertIsInstance(test.id(), basestring) # "Returns a one-line description of the test, or None if no description # has been provided. The default implementation of this method returns # the first line of the test method's docstring, if available, or None." def test_shortDescription__no_docstring(self): test = unittest2.FunctionTestCase(lambda: None) self.assertEqual(test.shortDescription(), None) # "Returns a one-line description of the test, or None if no description # has been provided. The default implementation of this method returns # the first line of the test method's docstring, if available, or None." def test_shortDescription__singleline_docstring(self): desc = "this tests foo" test = unittest2.FunctionTestCase(lambda: None, description=desc) self.assertEqual(test.shortDescription(), "this tests foo") if __name__ == '__main__': unittest2.main() distlib-0.2.2/tests/unittest2/test/test_suite.py0000664000000000000000000002624512030667514020506 0ustar rootrootfrom unittest2.test.support import EqualityMixin, LoggingResult import sys import unittest2 class Test(object): class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass def test_3(self): pass def runTest(self): pass def _mk_TestSuite(*names): return unittest2.TestSuite(Test.Foo(n) for n in names) class Test_TestSuite(unittest2.TestCase, EqualityMixin): ### Set up attributes needed by inherited tests ################################################################ # Used by EqualityMixin.test_eq eq_pairs = [(unittest2.TestSuite(), unittest2.TestSuite()), (unittest2.TestSuite(), unittest2.TestSuite([])), (_mk_TestSuite('test_1'), _mk_TestSuite('test_1'))] # Used by EqualityMixin.test_ne ne_pairs = [(unittest2.TestSuite(), _mk_TestSuite('test_1')), (unittest2.TestSuite([]), _mk_TestSuite('test_1')), (_mk_TestSuite('test_1', 'test_2'), _mk_TestSuite('test_1', 'test_3')), (_mk_TestSuite('test_1'), _mk_TestSuite('test_2'))] ################################################################ ### /Set up attributes needed by inherited tests ### Tests for TestSuite.__init__ ################################################################ # "class TestSuite([tests])" # # The tests iterable should be optional def test_init__tests_optional(self): suite = unittest2.TestSuite() self.assertEqual(suite.countTestCases(), 0) # "class TestSuite([tests])" # ... # "If tests is given, it must be an iterable of individual test cases # or other test suites that will be used to build the suite initially" # # TestSuite should deal with empty tests iterables by allowing the # creation of an empty suite def test_init__empty_tests(self): suite = unittest2.TestSuite([]) self.assertEqual(suite.countTestCases(), 0) # "class TestSuite([tests])" # ... # "If tests is given, it must be an iterable of individual test cases # or other test suites that will be used to build the suite initially" # # TestSuite should allow any iterable to provide tests def test_init__tests_from_any_iterable(self): def tests(): yield unittest2.FunctionTestCase(lambda: None) yield unittest2.FunctionTestCase(lambda: None) suite_1 = unittest2.TestSuite(tests()) self.assertEqual(suite_1.countTestCases(), 2) suite_2 = unittest2.TestSuite(suite_1) self.assertEqual(suite_2.countTestCases(), 2) suite_3 = unittest2.TestSuite(set(suite_1)) self.assertEqual(suite_3.countTestCases(), 2) # "class TestSuite([tests])" # ... # "If tests is given, it must be an iterable of individual test cases # or other test suites that will be used to build the suite initially" # # Does TestSuite() also allow other TestSuite() instances to be present # in the tests iterable? def test_init__TestSuite_instances_in_tests(self): def tests(): ftc = unittest2.FunctionTestCase(lambda: None) yield unittest2.TestSuite([ftc]) yield unittest2.FunctionTestCase(lambda: None) suite = unittest2.TestSuite(tests()) self.assertEqual(suite.countTestCases(), 2) ################################################################ ### /Tests for TestSuite.__init__ # Container types should support the iter protocol def test_iter(self): test1 = unittest2.FunctionTestCase(lambda: None) test2 = unittest2.FunctionTestCase(lambda: None) suite = unittest2.TestSuite((test1, test2)) self.assertEqual(list(suite), [test1, test2]) # "Return the number of tests represented by the this test object. # ...this method is also implemented by the TestSuite class, which can # return larger [greater than 1] values" # # Presumably an empty TestSuite returns 0? def test_countTestCases_zero_simple(self): suite = unittest2.TestSuite() self.assertEqual(suite.countTestCases(), 0) # "Return the number of tests represented by the this test object. # ...this method is also implemented by the TestSuite class, which can # return larger [greater than 1] values" # # Presumably an empty TestSuite (even if it contains other empty # TestSuite instances) returns 0? def test_countTestCases_zero_nested(self): class Test1(unittest2.TestCase): def test(self): pass suite = unittest2.TestSuite([unittest2.TestSuite()]) self.assertEqual(suite.countTestCases(), 0) # "Return the number of tests represented by the this test object. # ...this method is also implemented by the TestSuite class, which can # return larger [greater than 1] values" def test_countTestCases_simple(self): test1 = unittest2.FunctionTestCase(lambda: None) test2 = unittest2.FunctionTestCase(lambda: None) suite = unittest2.TestSuite((test1, test2)) self.assertEqual(suite.countTestCases(), 2) # "Return the number of tests represented by the this test object. # ...this method is also implemented by the TestSuite class, which can # return larger [greater than 1] values" # # Make sure this holds for nested TestSuite instances, too def test_countTestCases_nested(self): class Test1(unittest2.TestCase): def test1(self): pass def test2(self): pass test2 = unittest2.FunctionTestCase(lambda: None) test3 = unittest2.FunctionTestCase(lambda: None) child = unittest2.TestSuite((Test1('test2'), test2)) parent = unittest2.TestSuite((test3, child, Test1('test1'))) self.assertEqual(parent.countTestCases(), 4) # "Run the tests associated with this suite, collecting the result into # the test result object passed as result." # # And if there are no tests? What then? def test_run__empty_suite(self): events = [] result = LoggingResult(events) suite = unittest2.TestSuite() suite.run(result) self.assertEqual(events, []) # "Note that unlike TestCase.run(), TestSuite.run() requires the # "result object to be passed in." def test_run__requires_result(self): suite = unittest2.TestSuite() try: suite.run() except TypeError: pass else: self.fail("Failed to raise TypeError") # "Run the tests associated with this suite, collecting the result into # the test result object passed as result." def test_run(self): events = [] result = LoggingResult(events) class LoggingCase(unittest2.TestCase): def run(self, result): events.append('run %s' % self._testMethodName) def test1(self): pass def test2(self): pass tests = [LoggingCase('test1'), LoggingCase('test2')] unittest2.TestSuite(tests).run(result) self.assertEqual(events, ['run test1', 'run test2']) # "Add a TestCase ... to the suite" def test_addTest__TestCase(self): class Foo(unittest2.TestCase): def test(self): pass test = Foo('test') suite = unittest2.TestSuite() suite.addTest(test) self.assertEqual(suite.countTestCases(), 1) self.assertEqual(list(suite), [test]) # "Add a ... TestSuite to the suite" def test_addTest__TestSuite(self): class Foo(unittest2.TestCase): def test(self): pass suite_2 = unittest2.TestSuite([Foo('test')]) suite = unittest2.TestSuite() suite.addTest(suite_2) self.assertEqual(suite.countTestCases(), 1) self.assertEqual(list(suite), [suite_2]) # "Add all the tests from an iterable of TestCase and TestSuite # instances to this test suite." # # "This is equivalent to iterating over tests, calling addTest() for # each element" def test_addTests(self): class Foo(unittest2.TestCase): def test_1(self): pass def test_2(self): pass test_1 = Foo('test_1') test_2 = Foo('test_2') inner_suite = unittest2.TestSuite([test_2]) def gen(): yield test_1 yield test_2 yield inner_suite suite_1 = unittest2.TestSuite() suite_1.addTests(gen()) self.assertEqual(list(suite_1), list(gen())) # "This is equivalent to iterating over tests, calling addTest() for # each element" suite_2 = unittest2.TestSuite() for t in gen(): suite_2.addTest(t) self.assertEqual(suite_1, suite_2) # "Add all the tests from an iterable of TestCase and TestSuite # instances to this test suite." # # What happens if it doesn't get an iterable? def test_addTest__noniterable(self): suite = unittest2.TestSuite() try: suite.addTests(5) except TypeError: pass else: self.fail("Failed to raise TypeError") def test_addTest__noncallable(self): suite = unittest2.TestSuite() self.assertRaises(TypeError, suite.addTest, 5) def test_addTest__casesuiteclass(self): suite = unittest2.TestSuite() self.assertRaises(TypeError, suite.addTest, Test_TestSuite) self.assertRaises(TypeError, suite.addTest, unittest2.TestSuite) def test_addTests__string(self): suite = unittest2.TestSuite() self.assertRaises(TypeError, suite.addTests, "foo") def test_function_in_suite(self): def f(_): pass suite = unittest2.TestSuite() suite.addTest(f) # when the bug is fixed this line will not crash suite.run(unittest2.TestResult()) def test_basetestsuite(self): class Test(unittest2.TestCase): wasSetUp = False wasTornDown = False @classmethod def setUpClass(cls): cls.wasSetUp = True @classmethod def tearDownClass(cls): cls.wasTornDown = True def testPass(self): pass def testFail(self): fail class Module(object): wasSetUp = False wasTornDown = False @staticmethod def setUpModule(): Module.wasSetUp = True @staticmethod def tearDownModule(): Module.wasTornDown = True Test.__module__ = 'Module' sys.modules['Module'] = Module self.addCleanup(sys.modules.pop, 'Module') suite = unittest2.BaseTestSuite() suite.addTests([Test('testPass'), Test('testFail')]) self.assertEqual(suite.countTestCases(), 2) result = unittest2.TestResult() suite.run(result) self.assertFalse(Module.wasSetUp) self.assertFalse(Module.wasTornDown) self.assertFalse(Test.wasSetUp) self.assertFalse(Test.wasTornDown) self.assertEqual(len(result.errors), 1) self.assertEqual(len(result.failures), 0) self.assertEqual(result.testsRun, 2) if __name__ == '__main__': unittest2.main() distlib-0.2.2/tests/unittest2/test/test_discovery.py0000664000000000000000000003207412030667514021361 0ustar rootrootimport os import re import sys import unittest2 class TestDiscovery(unittest2.TestCase): # Heavily mocked tests so I can avoid hitting the filesystem def test_get_name_from_path(self): loader = unittest2.TestLoader() loader._top_level_dir = '/foo' name = loader._get_name_from_path('/foo/bar/baz.py') self.assertEqual(name, 'bar.baz') if not __debug__: # asserts are off return self.assertRaises(AssertionError, loader._get_name_from_path, '/bar/baz.py') def test_find_tests(self): loader = unittest2.TestLoader() original_listdir = os.listdir def restore_listdir(): os.listdir = original_listdir original_isfile = os.path.isfile def restore_isfile(): os.path.isfile = original_isfile original_isdir = os.path.isdir def restore_isdir(): os.path.isdir = original_isdir path_lists = [['test1.py', 'test2.py', 'not_a_test.py', 'test_dir', 'test.foo', 'test-not-a-module.py', 'another_dir'], ['test3.py', 'test4.py', ]] os.listdir = lambda path: path_lists.pop(0) self.addCleanup(restore_listdir) def isdir(path): return path.endswith('dir') os.path.isdir = isdir self.addCleanup(restore_isdir) def isfile(path): # another_dir is not a package and so shouldn't be recursed into return not path.endswith('dir') and not 'another_dir' in path os.path.isfile = isfile self.addCleanup(restore_isfile) loader._get_module_from_name = lambda path: path + ' module' loader.loadTestsFromModule = lambda module: module + ' tests' top_level = os.path.abspath('/foo') loader._top_level_dir = top_level suite = list(loader._find_tests(top_level, 'test*.py')) expected = [name + ' module tests' for name in ('test1', 'test2')] expected.extend([('test_dir.%s' % name) + ' module tests' for name in ('test3', 'test4')]) self.assertEqual(suite, expected) def test_find_tests_with_package(self): loader = unittest2.TestLoader() original_listdir = os.listdir def restore_listdir(): os.listdir = original_listdir original_isfile = os.path.isfile def restore_isfile(): os.path.isfile = original_isfile original_isdir = os.path.isdir def restore_isdir(): os.path.isdir = original_isdir directories = ['a_directory', 'test_directory', 'test_directory2'] path_lists = [directories, [], [], []] os.listdir = lambda path: path_lists.pop(0) self.addCleanup(restore_listdir) os.path.isdir = lambda path: True self.addCleanup(restore_isdir) os.path.isfile = lambda path: os.path.basename(path) not in directories self.addCleanup(restore_isfile) class Module(object): paths = [] load_tests_args = [] def __init__(self, path): self.path = path self.paths.append(path) if os.path.basename(path) == 'test_directory': def load_tests(loader, tests, pattern): self.load_tests_args.append((loader, tests, pattern)) return 'load_tests' self.load_tests = load_tests def __eq__(self, other): return self.path == other.path # Silence py3k warning __hash__ = None loader._get_module_from_name = lambda name: Module(name) def loadTestsFromModule(module, use_load_tests): if use_load_tests: raise self.failureException('use_load_tests should be False for packages') return module.path + ' module tests' loader.loadTestsFromModule = loadTestsFromModule loader._top_level_dir = '/foo' # this time no '.py' on the pattern so that it can match # a test package suite = list(loader._find_tests('/foo', 'test*')) # We should have loaded tests from the test_directory package by calling load_tests # and directly from the test_directory2 package self.assertEqual(suite, ['load_tests', 'test_directory2' + ' module tests']) self.assertEqual(Module.paths, ['test_directory', 'test_directory2']) # load_tests should have been called once with loader, tests and pattern self.assertEqual(Module.load_tests_args, [(loader, 'test_directory' + ' module tests', 'test*')]) def test_discover(self): loader = unittest2.TestLoader() original_isfile = os.path.isfile original_isdir = os.path.isdir def restore_isfile(): os.path.isfile = original_isfile os.path.isfile = lambda path: False self.addCleanup(restore_isfile) orig_sys_path = sys.path[:] def restore_path(): sys.path[:] = orig_sys_path self.addCleanup(restore_path) full_path = os.path.abspath(os.path.normpath('/foo')) self.assertRaises(ImportError, loader.discover, '/foo/bar', top_level_dir='/foo') self.assertEqual(loader._top_level_dir, full_path) self.assertIn(full_path, sys.path) os.path.isfile = lambda path: True os.path.isdir = lambda path: True def restore_isdir(): os.path.isdir = original_isdir self.addCleanup(restore_isdir) _find_tests_args = [] def _find_tests(start_dir, pattern): _find_tests_args.append((start_dir, pattern)) return ['tests'] loader._find_tests = _find_tests loader.suiteClass = str suite = loader.discover('/foo/bar/baz', 'pattern', '/foo/bar') top_level_dir = os.path.abspath(os.path.normpath('/foo/bar')) start_dir = os.path.abspath(os.path.normpath('/foo/bar/baz')) self.assertEqual(suite, "['tests']") self.assertEqual(loader._top_level_dir, top_level_dir) self.assertEqual(_find_tests_args, [(start_dir, 'pattern')]) self.assertIn(top_level_dir, sys.path) def test_discover_with_modules_that_fail_to_import(self): loader = unittest2.TestLoader() listdir = os.listdir os.listdir = lambda _: ['test_this_does_not_exist.py'] isfile = os.path.isfile os.path.isfile = lambda _: True orig_sys_path = sys.path[:] def restore(): os.path.isfile = isfile os.listdir = listdir sys.path[:] = orig_sys_path self.addCleanup(restore) suite = loader.discover('.') self.assertIn(os.getcwd(), sys.path) self.assertEqual(suite.countTestCases(), 1) test = list(list(suite)[0])[0] # extract test from suite self.assertRaises(ImportError, lambda: test.test_this_does_not_exist()) def test_command_line_handling_parseArgs(self): # Haha - take that uninstantiable class program = object.__new__(unittest2.TestProgram) args = [] def do_discovery(argv): args.extend(argv) program._do_discovery = do_discovery program.parseArgs(['something', 'discover']) self.assertEqual(args, []) program.parseArgs(['something', 'discover', 'foo', 'bar']) self.assertEqual(args, ['foo', 'bar']) def test_command_line_handling_do_discovery_too_many_arguments(self): class Stop(Exception): pass def usageExit(): raise Stop program = object.__new__(unittest2.TestProgram) program.usageExit = usageExit self.assertRaises(Stop, # too many args lambda: program._do_discovery(['one', 'two', 'three', 'four'])) def test_command_line_handling_do_discovery_calls_loader(self): program = object.__new__(unittest2.TestProgram) class Loader(object): args = [] def discover(self, start_dir, pattern, top_level_dir): self.args.append((start_dir, pattern, top_level_dir)) return 'tests' program._do_discovery(['-v'], Loader=Loader) self.assertEqual(program.verbosity, 2) self.assertEqual(program.test, 'tests') self.assertEqual(Loader.args, [('.', 'test*.py', None)]) Loader.args = [] program = object.__new__(unittest2.TestProgram) program._do_discovery(['--verbose'], Loader=Loader) self.assertEqual(program.test, 'tests') self.assertEqual(Loader.args, [('.', 'test*.py', None)]) Loader.args = [] program = object.__new__(unittest2.TestProgram) program._do_discovery([], Loader=Loader) self.assertEqual(program.test, 'tests') self.assertEqual(Loader.args, [('.', 'test*.py', None)]) Loader.args = [] program = object.__new__(unittest2.TestProgram) program._do_discovery(['fish'], Loader=Loader) self.assertEqual(program.test, 'tests') self.assertEqual(Loader.args, [('fish', 'test*.py', None)]) Loader.args = [] program = object.__new__(unittest2.TestProgram) program._do_discovery(['fish', 'eggs'], Loader=Loader) self.assertEqual(program.test, 'tests') self.assertEqual(Loader.args, [('fish', 'eggs', None)]) Loader.args = [] program = object.__new__(unittest2.TestProgram) program._do_discovery(['fish', 'eggs', 'ham'], Loader=Loader) self.assertEqual(program.test, 'tests') self.assertEqual(Loader.args, [('fish', 'eggs', 'ham')]) Loader.args = [] program = object.__new__(unittest2.TestProgram) program._do_discovery(['-s', 'fish'], Loader=Loader) self.assertEqual(program.test, 'tests') self.assertEqual(Loader.args, [('fish', 'test*.py', None)]) Loader.args = [] program = object.__new__(unittest2.TestProgram) program._do_discovery(['-t', 'fish'], Loader=Loader) self.assertEqual(program.test, 'tests') self.assertEqual(Loader.args, [('.', 'test*.py', 'fish')]) Loader.args = [] program = object.__new__(unittest2.TestProgram) program._do_discovery(['-p', 'fish'], Loader=Loader) self.assertEqual(program.test, 'tests') self.assertEqual(Loader.args, [('.', 'fish', None)]) self.assertFalse(program.failfast) self.assertFalse(program.catchbreak) args = ['-p', 'eggs', '-s', 'fish', '-v', '-f'] try: import signal except ImportError: signal = None else: args.append('-c') Loader.args = [] program = object.__new__(unittest2.TestProgram) program._do_discovery(args, Loader=Loader) self.assertEqual(program.test, 'tests') self.assertEqual(Loader.args, [('fish', 'eggs', None)]) self.assertEqual(program.verbosity, 2) self.assertTrue(program.failfast) if signal is not None: self.assertTrue(program.catchbreak) def test_detect_module_clash(self): class Module(object): __file__ = 'bar/foo.py' sys.modules['foo'] = Module full_path = os.path.abspath('foo') original_listdir = os.listdir original_isfile = os.path.isfile original_isdir = os.path.isdir def cleanup(): os.listdir = original_listdir os.path.isfile = original_isfile os.path.isdir = original_isdir del sys.modules['foo'] if full_path in sys.path: sys.path.remove(full_path) self.addCleanup(cleanup) def listdir(_): return ['foo.py'] def isfile(_): return True def isdir(_): return True os.listdir = listdir os.path.isfile = isfile os.path.isdir = isdir loader = unittest2.TestLoader() mod_dir = os.path.abspath('bar') expected_dir = os.path.abspath('foo') msg = re.escape(r"'foo' module incorrectly imported from %r. Expected %r. " "Is this module globally installed?" % (mod_dir, expected_dir)) self.assertRaisesRegexp( ImportError, '^%s$' % msg, loader.discover, start_dir='foo', pattern='foo.py' ) self.assertEqual(sys.path[0], full_path) def test_discovery_from_dotted_path(self): loader = unittest2.TestLoader() tests = [self] expectedPath = os.path.abspath(os.path.dirname(unittest2.test.__file__)) self.wasRun = False def _find_tests(start_dir, pattern): self.wasRun = True self.assertEqual(start_dir, expectedPath) return tests loader._find_tests = _find_tests suite = loader.discover('unittest2.test') self.assertTrue(self.wasRun) self.assertEqual(suite._tests, tests) if __name__ == '__main__': unittest2.main() distlib-0.2.2/tests/unittest2/test/dummy.py0000664000000000000000000000000012030667514017426 0ustar rootrootdistlib-0.2.2/tests/unittest2/test/test_setups.py0000664000000000000000000004071512030667514020676 0ustar rootrootimport sys from cStringIO import StringIO import unittest2 from unittest2.test.support import resultFactory class TestSetups(unittest2.TestCase): def getRunner(self): return unittest2.TextTestRunner(resultclass=resultFactory, stream=StringIO()) def runTests(self, *cases): suite = unittest2.TestSuite() for case in cases: tests = unittest2.defaultTestLoader.loadTestsFromTestCase(case) suite.addTests(tests) runner = self.getRunner() # creating a nested suite exposes some potential bugs realSuite = unittest2.TestSuite() realSuite.addTest(suite) # adding empty suites to the end exposes potential bugs suite.addTest(unittest2.TestSuite()) realSuite.addTest(unittest2.TestSuite()) return runner.run(realSuite) def test_setup_class(self): class Test(unittest2.TestCase): setUpCalled = 0 @classmethod def setUpClass(cls): Test.setUpCalled += 1 unittest2.TestCase.setUpClass() def test_one(self): pass def test_two(self): pass result = self.runTests(Test) self.assertEqual(Test.setUpCalled, 1) self.assertEqual(result.testsRun, 2) self.assertEqual(len(result.errors), 0) def test_teardown_class(self): class Test(unittest2.TestCase): tearDownCalled = 0 @classmethod def tearDownClass(cls): Test.tearDownCalled += 1 unittest2.TestCase.tearDownClass() def test_one(self): pass def test_two(self): pass result = self.runTests(Test) self.assertEqual(Test.tearDownCalled, 1) self.assertEqual(result.testsRun, 2) self.assertEqual(len(result.errors), 0) def test_teardown_class_two_classes(self): class Test(unittest2.TestCase): tearDownCalled = 0 @classmethod def tearDownClass(cls): Test.tearDownCalled += 1 unittest2.TestCase.tearDownClass() def test_one(self): pass def test_two(self): pass class Test2(unittest2.TestCase): tearDownCalled = 0 @classmethod def tearDownClass(cls): Test2.tearDownCalled += 1 unittest2.TestCase.tearDownClass() def test_one(self): pass def test_two(self): pass result = self.runTests(Test, Test2) self.assertEqual(Test.tearDownCalled, 1) self.assertEqual(Test2.tearDownCalled, 1) self.assertEqual(result.testsRun, 4) self.assertEqual(len(result.errors), 0) def test_error_in_setupclass(self): class BrokenTest(unittest2.TestCase): @classmethod def setUpClass(cls): raise TypeError('foo') def test_one(self): pass def test_two(self): pass result = self.runTests(BrokenTest) self.assertEqual(result.testsRun, 0) self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), 'setUpClass (%s.BrokenTest)' % __name__) def test_error_in_teardown_class(self): class Test(unittest2.TestCase): tornDown = 0 @classmethod def tearDownClass(cls): Test.tornDown += 1 raise TypeError('foo') def test_one(self): pass def test_two(self): pass class Test2(unittest2.TestCase): tornDown = 0 @classmethod def tearDownClass(cls): Test2.tornDown += 1 raise TypeError('foo') def test_one(self): pass def test_two(self): pass result = self.runTests(Test, Test2) self.assertEqual(result.testsRun, 4) self.assertEqual(len(result.errors), 2) self.assertEqual(Test.tornDown, 1) self.assertEqual(Test2.tornDown, 1) error, _ = result.errors[0] self.assertEqual(str(error), 'tearDownClass (%s.Test)' % __name__) def test_class_not_torndown_when_setup_fails(self): class Test(unittest2.TestCase): tornDown = False @classmethod def setUpClass(cls): raise TypeError @classmethod def tearDownClass(cls): Test.tornDown = True raise TypeError('foo') def test_one(self): pass self.runTests(Test) self.assertFalse(Test.tornDown) def test_class_not_setup_or_torndown_when_skipped(self): class Test(unittest2.TestCase): classSetUp = False tornDown = False @classmethod def setUpClass(cls): Test.classSetUp = True @classmethod def tearDownClass(cls): Test.tornDown = True def test_one(self): pass Test = unittest2.skip("hop")(Test) self.runTests(Test) self.assertFalse(Test.classSetUp) self.assertFalse(Test.tornDown) def test_setup_teardown_order_with_pathological_suite(self): results = [] class Module1(object): @staticmethod def setUpModule(): results.append('Module1.setUpModule') @staticmethod def tearDownModule(): results.append('Module1.tearDownModule') class Module2(object): @staticmethod def setUpModule(): results.append('Module2.setUpModule') @staticmethod def tearDownModule(): results.append('Module2.tearDownModule') class Test1(unittest2.TestCase): @classmethod def setUpClass(cls): results.append('setup 1') @classmethod def tearDownClass(cls): results.append('teardown 1') def testOne(self): results.append('Test1.testOne') def testTwo(self): results.append('Test1.testTwo') class Test2(unittest2.TestCase): @classmethod def setUpClass(cls): results.append('setup 2') @classmethod def tearDownClass(cls): results.append('teardown 2') def testOne(self): results.append('Test2.testOne') def testTwo(self): results.append('Test2.testTwo') class Test3(unittest2.TestCase): @classmethod def setUpClass(cls): results.append('setup 3') @classmethod def tearDownClass(cls): results.append('teardown 3') def testOne(self): results.append('Test3.testOne') def testTwo(self): results.append('Test3.testTwo') Test1.__module__ = Test2.__module__ = 'Module' Test3.__module__ = 'Module2' sys.modules['Module'] = Module1 sys.modules['Module2'] = Module2 first = unittest2.TestSuite((Test1('testOne'),)) second = unittest2.TestSuite((Test1('testTwo'),)) third = unittest2.TestSuite((Test2('testOne'),)) fourth = unittest2.TestSuite((Test2('testTwo'),)) fifth = unittest2.TestSuite((Test3('testOne'),)) sixth = unittest2.TestSuite((Test3('testTwo'),)) suite = unittest2.TestSuite((first, second, third, fourth, fifth, sixth)) runner = self.getRunner() result = runner.run(suite) self.assertEqual(result.testsRun, 6) self.assertEqual(len(result.errors), 0) self.assertEqual(results, ['Module1.setUpModule', 'setup 1', 'Test1.testOne', 'Test1.testTwo', 'teardown 1', 'setup 2', 'Test2.testOne', 'Test2.testTwo', 'teardown 2', 'Module1.tearDownModule', 'Module2.setUpModule', 'setup 3', 'Test3.testOne', 'Test3.testTwo', 'teardown 3', 'Module2.tearDownModule']) def test_setup_module(self): class Module(object): moduleSetup = 0 @staticmethod def setUpModule(): Module.moduleSetup += 1 class Test(unittest2.TestCase): def test_one(self): pass def test_two(self): pass Test.__module__ = 'Module' sys.modules['Module'] = Module result = self.runTests(Test) self.assertEqual(Module.moduleSetup, 1) self.assertEqual(result.testsRun, 2) self.assertEqual(len(result.errors), 0) def test_error_in_setup_module(self): class Module(object): moduleSetup = 0 moduleTornDown = 0 @staticmethod def setUpModule(): Module.moduleSetup += 1 raise TypeError('foo') @staticmethod def tearDownModule(): Module.moduleTornDown += 1 class Test(unittest2.TestCase): classSetUp = False classTornDown = False @classmethod def setUpClass(cls): Test.classSetUp = True @classmethod def tearDownClass(cls): Test.classTornDown = True def test_one(self): pass def test_two(self): pass class Test2(unittest2.TestCase): def test_one(self): pass def test_two(self): pass Test.__module__ = 'Module' Test2.__module__ = 'Module' sys.modules['Module'] = Module result = self.runTests(Test, Test2) self.assertEqual(Module.moduleSetup, 1) self.assertEqual(Module.moduleTornDown, 0) self.assertEqual(result.testsRun, 0) self.assertFalse(Test.classSetUp) self.assertFalse(Test.classTornDown) self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), 'setUpModule (Module)') def test_testcase_with_missing_module(self): class Test(unittest2.TestCase): def test_one(self): pass def test_two(self): pass Test.__module__ = 'Module' sys.modules.pop('Module', None) result = self.runTests(Test) self.assertEqual(result.testsRun, 2) def test_teardown_module(self): class Module(object): moduleTornDown = 0 @staticmethod def tearDownModule(): Module.moduleTornDown += 1 class Test(unittest2.TestCase): def test_one(self): pass def test_two(self): pass Test.__module__ = 'Module' sys.modules['Module'] = Module result = self.runTests(Test) self.assertEqual(Module.moduleTornDown, 1) self.assertEqual(result.testsRun, 2) self.assertEqual(len(result.errors), 0) def test_error_in_teardown_module(self): class Module(object): moduleTornDown = 0 @staticmethod def tearDownModule(): Module.moduleTornDown += 1 raise TypeError('foo') class Test(unittest2.TestCase): classSetUp = False classTornDown = False @classmethod def setUpClass(cls): Test.classSetUp = True @classmethod def tearDownClass(cls): Test.classTornDown = True def test_one(self): pass def test_two(self): pass class Test2(unittest2.TestCase): def test_one(self): pass def test_two(self): pass Test.__module__ = 'Module' Test2.__module__ = 'Module' sys.modules['Module'] = Module result = self.runTests(Test, Test2) self.assertEqual(Module.moduleTornDown, 1) self.assertEqual(result.testsRun, 4) self.assertTrue(Test.classSetUp) self.assertTrue(Test.classTornDown) self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), 'tearDownModule (Module)') def test_skiptest_in_setupclass(self): class Test(unittest2.TestCase): @classmethod def setUpClass(cls): raise unittest2.SkipTest('foo') def test_one(self): pass def test_two(self): pass result = self.runTests(Test) self.assertEqual(result.testsRun, 0) self.assertEqual(len(result.errors), 0) self.assertEqual(len(result.skipped), 1) skipped = result.skipped[0][0] self.assertEqual(str(skipped), 'setUpClass (%s.Test)' % __name__) def test_skiptest_in_setupmodule(self): class Test(unittest2.TestCase): def test_one(self): pass def test_two(self): pass class Module(object): @staticmethod def setUpModule(): raise unittest2.SkipTest('foo') Test.__module__ = 'Module' sys.modules['Module'] = Module result = self.runTests(Test) self.assertEqual(result.testsRun, 0) self.assertEqual(len(result.errors), 0) self.assertEqual(len(result.skipped), 1) skipped = result.skipped[0][0] self.assertEqual(str(skipped), 'setUpModule (Module)') def test_suite_debug_executes_setups_and_teardowns(self): ordering = [] class Module(object): @staticmethod def setUpModule(): ordering.append('setUpModule') @staticmethod def tearDownModule(): ordering.append('tearDownModule') class Test(unittest2.TestCase): @classmethod def setUpClass(cls): ordering.append('setUpClass') @classmethod def tearDownClass(cls): ordering.append('tearDownClass') def test_something(self): ordering.append('test_something') Test.__module__ = 'Module' sys.modules['Module'] = Module suite = unittest2.defaultTestLoader.loadTestsFromTestCase(Test) suite.debug() expectedOrder = ['setUpModule', 'setUpClass', 'test_something', 'tearDownClass', 'tearDownModule'] self.assertEqual(ordering, expectedOrder) def test_suite_debug_propagates_exceptions(self): class Module(object): @staticmethod def setUpModule(): if phase == 0: raise Exception('setUpModule') @staticmethod def tearDownModule(): if phase == 1: raise Exception('tearDownModule') class Test(unittest2.TestCase): @classmethod def setUpClass(cls): if phase == 2: raise Exception('setUpClass') @classmethod def tearDownClass(cls): if phase == 3: raise Exception('tearDownClass') def test_something(self): if phase == 4: raise Exception('test_something') Test.__module__ = 'Module' sys.modules['Module'] = Module _suite = unittest2.defaultTestLoader.loadTestsFromTestCase(Test) suite = unittest2.TestSuite() # nesting a suite again exposes a bug in the initial implementation suite.addTest(_suite) messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something') for phase, msg in enumerate(messages): self.assertRaisesRegexp(Exception, msg, suite.debug) distlib-0.2.2/tests/unittest2/test/support.py0000664000000000000000000001255712030667514020033 0ustar rootrootimport sys import warnings import unittest2 def resultFactory(*_): return unittest2.TestResult() class OldTestResult(object): """An object honouring TestResult before startTestRun/stopTestRun.""" def __init__(self, *_): self.failures = [] self.errors = [] self.testsRun = 0 self.shouldStop = False def startTest(self, test): pass def stopTest(self, test): pass def addError(self, test, err): self.errors.append((test, err)) def addFailure(self, test, err): self.failures.append((test, err)) def addSuccess(self, test): pass def wasSuccessful(self): return True def printErrors(self): pass class LoggingResult(unittest2.TestResult): def __init__(self, log): self._events = log super(LoggingResult, self).__init__() def startTest(self, test): self._events.append('startTest') super(LoggingResult, self).startTest(test) def startTestRun(self): self._events.append('startTestRun') super(LoggingResult, self).startTestRun() def stopTest(self, test): self._events.append('stopTest') super(LoggingResult, self).stopTest(test) def stopTestRun(self): self._events.append('stopTestRun') super(LoggingResult, self).stopTestRun() def addFailure(self, *args): self._events.append('addFailure') super(LoggingResult, self).addFailure(*args) def addSuccess(self, *args): self._events.append('addSuccess') super(LoggingResult, self).addSuccess(*args) def addError(self, *args): self._events.append('addError') super(LoggingResult, self).addError(*args) def addSkip(self, *args): self._events.append('addSkip') super(LoggingResult, self).addSkip(*args) def addExpectedFailure(self, *args): self._events.append('addExpectedFailure') super(LoggingResult, self).addExpectedFailure(*args) def addUnexpectedSuccess(self, *args): self._events.append('addUnexpectedSuccess') super(LoggingResult, self).addUnexpectedSuccess(*args) class EqualityMixin(object): """Used as a mixin for TestCase""" # Check for a valid __eq__ implementation def test_eq(self): for obj_1, obj_2 in self.eq_pairs: self.assertEqual(obj_1, obj_2) self.assertEqual(obj_2, obj_1) # Check for a valid __ne__ implementation def test_ne(self): for obj_1, obj_2 in self.ne_pairs: self.assertNotEqual(obj_1, obj_2) self.assertNotEqual(obj_2, obj_1) class HashingMixin(object): """Used as a mixin for TestCase""" # Check for a valid __hash__ implementation def test_hash(self): for obj_1, obj_2 in self.eq_pairs: try: if not hash(obj_1) == hash(obj_2): self.fail("%r and %r do not hash equal" % (obj_1, obj_2)) except KeyboardInterrupt: raise except Exception, e: self.fail("Problem hashing %r and %r: %s" % (obj_1, obj_2, e)) for obj_1, obj_2 in self.ne_pairs: try: if hash(obj_1) == hash(obj_2): self.fail("%s and %s hash equal, but shouldn't" % (obj_1, obj_2)) except KeyboardInterrupt: raise except Exception, e: self.fail("Problem hashing %s and %s: %s" % (obj_1, obj_2, e)) # copied from Python 2.6 try: from warnings import catch_warnings except ImportError: class catch_warnings(object): def __init__(self, record=False, module=None): self._record = record self._module = sys.modules['warnings'] self._entered = False def __repr__(self): args = [] if self._record: args.append("record=True") name = type(self).__name__ return "%s(%s)" % (name, ", ".join(args)) def __enter__(self): if self._entered: raise RuntimeError("Cannot enter %r twice" % self) self._entered = True self._filters = self._module.filters self._module.filters = self._filters[:] self._showwarning = self._module.showwarning if self._record: log = [] def showwarning(*args, **kwargs): log.append(WarningMessage(*args, **kwargs)) self._module.showwarning = showwarning return log else: return None def __exit__(self, *exc_info): if not self._entered: raise RuntimeError("Cannot exit %r without entering first" % self) self._module.filters = self._filters self._module.showwarning = self._showwarning class WarningMessage(object): _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file", "line") def __init__(self, message, category, filename, lineno, file=None, line=None): local_values = locals() for attr in self._WARNING_DETAILS: setattr(self, attr, local_values[attr]) self._category_name = None if category.__name__: self._category_name = category.__name__ distlib-0.2.2/tests/unittest2/test/test_new_tests.py0000664000000000000000000000323712030667514021364 0ustar rootrootfrom cStringIO import StringIO import unittest import unittest2 from unittest2.test.support import resultFactory class TestUnittest(unittest2.TestCase): def assertIsSubclass(self, actual, klass): self.assertTrue(issubclass(actual, klass), "Not a subclass.") def testInheritance(self): self.assertIsSubclass(unittest2.TestCase, unittest.TestCase) self.assertIsSubclass(unittest2.TestResult, unittest.TestResult) self.assertIsSubclass(unittest2.TestSuite, unittest.TestSuite) self.assertIsSubclass(unittest2.TextTestRunner, unittest.TextTestRunner) self.assertIsSubclass(unittest2.TestLoader, unittest.TestLoader) self.assertIsSubclass(unittest2.TextTestResult, unittest.TestResult) def test_new_runner_old_case(self): runner = unittest2.TextTestRunner(resultclass=resultFactory, stream=StringIO()) class Test(unittest.TestCase): def testOne(self): pass suite = unittest2.TestSuite((Test('testOne'),)) result = runner.run(suite) self.assertEqual(result.testsRun, 1) self.assertEqual(len(result.errors), 0) def test_old_runner_new_case(self): runner = unittest.TextTestRunner(stream=StringIO()) class Test(unittest2.TestCase): def testOne(self): self.assertDictEqual({}, {}) suite = unittest.TestSuite((Test('testOne'),)) result = runner.run(suite) self.assertEqual(result.testsRun, 1) self.assertEqual(len(result.errors), 0) if __name__ == '__main__': unittest2.main()distlib-0.2.2/tests/unittest2/test/__init__.py0000664000000000000000000000000112030667514020033 0ustar rootroot#distlib-0.2.2/tests/unittest2/signals.py0000664000000000000000000000322412030667514016767 0ustar rootrootimport signal import weakref from unittest2.compatibility import wraps __unittest = True class _InterruptHandler(object): def __init__(self, default_handler): self.called = False self.default_handler = default_handler def __call__(self, signum, frame): installed_handler = signal.getsignal(signal.SIGINT) if installed_handler is not self: # if we aren't the installed handler, then delegate immediately # to the default handler self.default_handler(signum, frame) if self.called: self.default_handler(signum, frame) self.called = True for result in _results.keys(): result.stop() _results = weakref.WeakKeyDictionary() def registerResult(result): _results[result] = 1 def removeResult(result): return bool(_results.pop(result, None)) _interrupt_handler = None def installHandler(): global _interrupt_handler if _interrupt_handler is None: default_handler = signal.getsignal(signal.SIGINT) _interrupt_handler = _InterruptHandler(default_handler) signal.signal(signal.SIGINT, _interrupt_handler) def removeHandler(method=None): if method is not None: @wraps(method) def inner(*args, **kwargs): initial = signal.getsignal(signal.SIGINT) removeHandler() try: return method(*args, **kwargs) finally: signal.signal(signal.SIGINT, initial) return inner global _interrupt_handler if _interrupt_handler is not None: signal.signal(signal.SIGINT, _interrupt_handler.default_handler) distlib-0.2.2/tests/unittest2/case.py0000664000000000000000000012343412030667514016250 0ustar rootroot"""Test case implementation""" import sys import difflib import pprint import re import unittest import warnings from unittest2 import result from unittest2.util import ( safe_repr, safe_str, strclass, unorderable_list_difference ) from unittest2.compatibility import wraps __unittest = True DIFF_OMITTED = ('\nDiff is %s characters long. ' 'Set self.maxDiff to None to see it.') class SkipTest(Exception): """ Raise this exception in a test to skip it. Usually you can use TestResult.skip() or one of the skipping decorators instead of raising this directly. """ class _ExpectedFailure(Exception): """ Raise this when a test is expected to fail. This is an implementation detail. """ def __init__(self, exc_info): # can't use super because Python 2.4 exceptions are old style Exception.__init__(self) self.exc_info = exc_info class _UnexpectedSuccess(Exception): """ The test was supposed to fail, but it didn't! """ def _id(obj): return obj def skip(reason): """ Unconditionally skip a test. """ def decorator(test_item): if not (isinstance(test_item, type) and issubclass(test_item, TestCase)): @wraps(test_item) def skip_wrapper(*args, **kwargs): raise SkipTest(reason) test_item = skip_wrapper test_item.__unittest_skip__ = True test_item.__unittest_skip_why__ = reason return test_item return decorator def skipIf(condition, reason): """ Skip a test if the condition is true. """ if condition: return skip(reason) return _id def skipUnless(condition, reason): """ Skip a test unless the condition is true. """ if not condition: return skip(reason) return _id def expectedFailure(func): @wraps(func) def wrapper(*args, **kwargs): try: func(*args, **kwargs) except Exception: raise _ExpectedFailure(sys.exc_info()) raise _UnexpectedSuccess return wrapper class _AssertRaisesContext(object): """A context manager used to implement TestCase.assertRaises* methods.""" def __init__(self, expected, test_case, expected_regexp=None): self.expected = expected self.failureException = test_case.failureException self.expected_regexp = expected_regexp def __enter__(self): return self def __exit__(self, exc_type, exc_value, tb): if exc_type is None: try: exc_name = self.expected.__name__ except AttributeError: exc_name = str(self.expected) raise self.failureException( "%s not raised" % (exc_name,)) if not issubclass(exc_type, self.expected): # let unexpected exceptions pass through return False self.exception = exc_value # store for later retrieval if self.expected_regexp is None: return True expected_regexp = self.expected_regexp if isinstance(expected_regexp, basestring): expected_regexp = re.compile(expected_regexp) if not expected_regexp.search(str(exc_value)): raise self.failureException('"%s" does not match "%s"' % (expected_regexp.pattern, str(exc_value))) return True class _TypeEqualityDict(object): def __init__(self, testcase): self.testcase = testcase self._store = {} def __setitem__(self, key, value): self._store[key] = value def __getitem__(self, key): value = self._store[key] if isinstance(value, basestring): return getattr(self.testcase, value) return value def get(self, key, default=None): if key in self._store: return self[key] return default class TestCase(unittest.TestCase): """A class whose instances are single test cases. By default, the test code itself should be placed in a method named 'runTest'. If the fixture may be used for many test cases, create as many test methods as are needed. When instantiating such a TestCase subclass, specify in the constructor arguments the name of the test method that the instance is to execute. Test authors should subclass TestCase for their own tests. Construction and deconstruction of the test's environment ('fixture') can be implemented by overriding the 'setUp' and 'tearDown' methods respectively. If it is necessary to override the __init__ method, the base class __init__ method must always be called. It is important that subclasses should not change the signature of their __init__ method, since instances of the classes are instantiated automatically by parts of the framework in order to be run. """ # This attribute determines which exception will be raised when # the instance's assertion methods fail; test methods raising this # exception will be deemed to have 'failed' rather than 'errored' failureException = AssertionError # This attribute sets the maximum length of a diff in failure messages # by assert methods using difflib. It is looked up as an instance attribute # so can be configured by individual tests if required. maxDiff = 80*8 # This attribute determines whether long messages (including repr of # objects used in assert methods) will be printed on failure in *addition* # to any explicit message passed. longMessage = True # Attribute used by TestSuite for classSetUp _classSetupFailed = False def __init__(self, methodName='runTest'): """Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name. """ self._testMethodName = methodName self._resultForDoCleanups = None try: testMethod = getattr(self, methodName) except AttributeError: raise ValueError("no such test method in %s: %s" % \ (self.__class__, methodName)) self._testMethodDoc = testMethod.__doc__ self._cleanups = [] # Map types to custom assertEqual functions that will compare # instances of said type in more detail to generate a more useful # error message. self._type_equality_funcs = _TypeEqualityDict(self) self.addTypeEqualityFunc(dict, 'assertDictEqual') self.addTypeEqualityFunc(list, 'assertListEqual') self.addTypeEqualityFunc(tuple, 'assertTupleEqual') self.addTypeEqualityFunc(set, 'assertSetEqual') self.addTypeEqualityFunc(frozenset, 'assertSetEqual') self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual') def addTypeEqualityFunc(self, typeobj, function): """Add a type specific assertEqual style function to compare a type. This method is for use by TestCase subclasses that need to register their own type equality functions to provide nicer error messages. Args: typeobj: The data type to call this function on when both values are of the same type in assertEqual(). function: The callable taking two arguments and an optional msg= argument that raises self.failureException with a useful error message when the two arguments are not equal. """ self._type_equality_funcs[typeobj] = function def addCleanup(self, function, *args, **kwargs): """Add a function, with arguments, to be called when the test is completed. Functions added are called on a LIFO basis and are called after tearDown on test failure or success. Cleanup items are called even if setUp fails (unlike tearDown).""" self._cleanups.append((function, args, kwargs)) def setUp(self): "Hook method for setting up the test fixture before exercising it." @classmethod def setUpClass(cls): "Hook method for setting up class fixture before running tests in the class." @classmethod def tearDownClass(cls): "Hook method for deconstructing the class fixture after running all tests in the class." def tearDown(self): "Hook method for deconstructing the test fixture after testing it." def countTestCases(self): return 1 def defaultTestResult(self): return result.TestResult() def shortDescription(self): """Returns a one-line description of the test, or None if no description has been provided. The default implementation of this method returns the first line of the specified test method's docstring. """ doc = self._testMethodDoc return doc and doc.split("\n")[0].strip() or None def id(self): return "%s.%s" % (strclass(self.__class__), self._testMethodName) def __eq__(self, other): if type(self) is not type(other): return NotImplemented return self._testMethodName == other._testMethodName def __ne__(self, other): return not self == other def __hash__(self): return hash((type(self), self._testMethodName)) def __str__(self): return "%s (%s)" % (self._testMethodName, strclass(self.__class__)) def __repr__(self): return "<%s testMethod=%s>" % \ (strclass(self.__class__), self._testMethodName) def _addSkip(self, result, reason): addSkip = getattr(result, 'addSkip', None) if addSkip is not None: addSkip(self, reason) else: warnings.warn("Use of a TestResult without an addSkip method is deprecated", DeprecationWarning, 2) result.addSuccess(self) def run(self, result=None): orig_result = result if result is None: result = self.defaultTestResult() startTestRun = getattr(result, 'startTestRun', None) if startTestRun is not None: startTestRun() self._resultForDoCleanups = result result.startTest(self) testMethod = getattr(self, self._testMethodName) if (getattr(self.__class__, "__unittest_skip__", False) or getattr(testMethod, "__unittest_skip__", False)): # If the class or method was skipped. try: skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') or getattr(testMethod, '__unittest_skip_why__', '')) self._addSkip(result, skip_why) finally: result.stopTest(self) return try: success = False try: self.setUp() except SkipTest, e: self._addSkip(result, str(e)) except Exception: result.addError(self, sys.exc_info()) else: try: testMethod() except self.failureException: result.addFailure(self, sys.exc_info()) except _ExpectedFailure, e: addExpectedFailure = getattr(result, 'addExpectedFailure', None) if addExpectedFailure is not None: addExpectedFailure(self, e.exc_info) else: warnings.warn("Use of a TestResult without an addExpectedFailure method is deprecated", DeprecationWarning) result.addSuccess(self) except _UnexpectedSuccess: addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None) if addUnexpectedSuccess is not None: addUnexpectedSuccess(self) else: warnings.warn("Use of a TestResult without an addUnexpectedSuccess method is deprecated", DeprecationWarning) result.addFailure(self, sys.exc_info()) except SkipTest, e: self._addSkip(result, str(e)) except Exception: result.addError(self, sys.exc_info()) else: success = True try: self.tearDown() except Exception: result.addError(self, sys.exc_info()) success = False cleanUpSuccess = self.doCleanups() success = success and cleanUpSuccess if success: result.addSuccess(self) finally: result.stopTest(self) if orig_result is None: stopTestRun = getattr(result, 'stopTestRun', None) if stopTestRun is not None: stopTestRun() def doCleanups(self): """Execute all cleanup functions. Normally called for you after tearDown.""" result = self._resultForDoCleanups ok = True while self._cleanups: function, args, kwargs = self._cleanups.pop(-1) try: function(*args, **kwargs) except Exception: ok = False result.addError(self, sys.exc_info()) return ok def __call__(self, *args, **kwds): return self.run(*args, **kwds) def debug(self): """Run the test without collecting errors in a TestResult""" self.setUp() getattr(self, self._testMethodName)() self.tearDown() while self._cleanups: function, args, kwargs = self._cleanups.pop(-1) function(*args, **kwargs) def skipTest(self, reason): """Skip this test.""" raise SkipTest(reason) def fail(self, msg=None): """Fail immediately, with the given message.""" raise self.failureException(msg) def assertFalse(self, expr, msg=None): "Fail the test if the expression is true." if expr: msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr)) raise self.failureException(msg) def assertTrue(self, expr, msg=None): """Fail the test unless the expression is true.""" if not expr: msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr)) raise self.failureException(msg) def _formatMessage(self, msg, standardMsg): """Honour the longMessage attribute when generating failure messages. If longMessage is False this means: * Use only an explicit message if it is provided * Otherwise use the standard message for the assert If longMessage is True: * Use the standard message * If an explicit message is provided, plus ' : ' and the explicit message """ if not self.longMessage: return msg or standardMsg if msg is None: return standardMsg try: return '%s : %s' % (standardMsg, msg) except UnicodeDecodeError: return '%s : %s' % (safe_str(standardMsg), safe_str(msg)) def assertRaises(self, excClass, callableObj=None, *args, **kwargs): """Fail unless an exception of class excClass is thrown by callableObj when invoked with arguments args and keyword arguments kwargs. If a different type of exception is thrown, it will not be caught, and the test case will be deemed to have suffered an error, exactly as for an unexpected exception. If called with callableObj omitted or None, will return a context object used like this:: with self.assertRaises(SomeException): do_something() The context manager keeps a reference to the exception as the 'exception' attribute. This allows you to inspect the exception after the assertion:: with self.assertRaises(SomeException) as cm: do_something() the_exception = cm.exception self.assertEqual(the_exception.error_code, 3) """ if callableObj is None: return _AssertRaisesContext(excClass, self) try: callableObj(*args, **kwargs) except excClass: return if hasattr(excClass,'__name__'): excName = excClass.__name__ else: excName = str(excClass) raise self.failureException, "%s not raised" % excName def _getAssertEqualityFunc(self, first, second): """Get a detailed comparison function for the types of the two args. Returns: A callable accepting (first, second, msg=None) that will raise a failure exception if first != second with a useful human readable error message for those types. """ # # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) # and vice versa. I opted for the conservative approach in case # subclasses are not intended to be compared in detail to their super # class instances using a type equality func. This means testing # subtypes won't automagically use the detailed comparison. Callers # should use their type specific assertSpamEqual method to compare # subclasses if the detailed comparison is desired and appropriate. # See the discussion in http://bugs.python.org/issue2578. # if type(first) is type(second): asserter = self._type_equality_funcs.get(type(first)) if asserter is not None: return asserter return self._baseAssertEqual def _baseAssertEqual(self, first, second, msg=None): """The default assertEqual implementation, not type specific.""" if not first == second: standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second)) msg = self._formatMessage(msg, standardMsg) raise self.failureException(msg) def assertEqual(self, first, second, msg=None): """Fail if the two objects are unequal as determined by the '==' operator. """ assertion_func = self._getAssertEqualityFunc(first, second) assertion_func(first, second, msg=msg) def assertNotEqual(self, first, second, msg=None): """Fail if the two objects are equal as determined by the '==' operator. """ if not first != second: msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first), safe_repr(second))) raise self.failureException(msg) def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None): """Fail if the two objects are unequal as determined by their difference rounded to the given number of decimal places (default 7) and comparing to zero, or by comparing that the between the two objects is more than the given delta. Note that decimal places (from zero) are usually not the same as significant digits (measured from the most signficant digit). If the two objects compare equal then they will automatically compare almost equal. """ if first == second: # shortcut return if delta is not None and places is not None: raise TypeError("specify delta or places not both") if delta is not None: if abs(first - second) <= delta: return standardMsg = '%s != %s within %s delta' % (safe_repr(first), safe_repr(second), safe_repr(delta)) else: if places is None: places = 7 if round(abs(second-first), places) == 0: return standardMsg = '%s != %s within %r places' % (safe_repr(first), safe_repr(second), places) msg = self._formatMessage(msg, standardMsg) raise self.failureException(msg) def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None): """Fail if the two objects are equal as determined by their difference rounded to the given number of decimal places (default 7) and comparing to zero, or by comparing that the between the two objects is less than the given delta. Note that decimal places (from zero) are usually not the same as significant digits (measured from the most signficant digit). Objects that are equal automatically fail. """ if delta is not None and places is not None: raise TypeError("specify delta or places not both") if delta is not None: if not (first == second) and abs(first - second) > delta: return standardMsg = '%s == %s within %s delta' % (safe_repr(first), safe_repr(second), safe_repr(delta)) else: if places is None: places = 7 if not (first == second) and round(abs(second-first), places) != 0: return standardMsg = '%s == %s within %r places' % (safe_repr(first), safe_repr(second), places) msg = self._formatMessage(msg, standardMsg) raise self.failureException(msg) # Synonyms for assertion methods # The plurals are undocumented. Keep them that way to discourage use. # Do not add more. Do not remove. # Going through a deprecation cycle on these would annoy many people. assertEquals = assertEqual assertNotEquals = assertNotEqual assertAlmostEquals = assertAlmostEqual assertNotAlmostEquals = assertNotAlmostEqual assert_ = assertTrue # These fail* assertion method names are pending deprecation and will # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578 def _deprecate(original_func): def deprecated_func(*args, **kwargs): warnings.warn( ('Please use %s instead.' % original_func.__name__), PendingDeprecationWarning, 2) return original_func(*args, **kwargs) return deprecated_func failUnlessEqual = _deprecate(assertEqual) failIfEqual = _deprecate(assertNotEqual) failUnlessAlmostEqual = _deprecate(assertAlmostEqual) failIfAlmostEqual = _deprecate(assertNotAlmostEqual) failUnless = _deprecate(assertTrue) failUnlessRaises = _deprecate(assertRaises) failIf = _deprecate(assertFalse) def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None, max_diff=80*8): """An equality assertion for ordered sequences (like lists and tuples). For the purposes of this function, a valid ordered sequence type is one which can be indexed, has a length, and has an equality operator. Args: seq1: The first sequence to compare. seq2: The second sequence to compare. seq_type: The expected datatype of the sequences, or None if no datatype should be enforced. msg: Optional message to use on failure instead of a list of differences. max_diff: Maximum size off the diff, larger diffs are not shown """ if seq_type is not None: seq_type_name = seq_type.__name__ if not isinstance(seq1, seq_type): raise self.failureException('First sequence is not a %s: %s' % (seq_type_name, safe_repr(seq1))) if not isinstance(seq2, seq_type): raise self.failureException('Second sequence is not a %s: %s' % (seq_type_name, safe_repr(seq2))) else: seq_type_name = "sequence" differing = None try: len1 = len(seq1) except (TypeError, NotImplementedError): differing = 'First %s has no length. Non-sequence?' % ( seq_type_name) if differing is None: try: len2 = len(seq2) except (TypeError, NotImplementedError): differing = 'Second %s has no length. Non-sequence?' % ( seq_type_name) if differing is None: if seq1 == seq2: return seq1_repr = repr(seq1) seq2_repr = repr(seq2) if len(seq1_repr) > 30: seq1_repr = seq1_repr[:30] + '...' if len(seq2_repr) > 30: seq2_repr = seq2_repr[:30] + '...' elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr) differing = '%ss differ: %s != %s\n' % elements for i in xrange(min(len1, len2)): try: item1 = seq1[i] except (TypeError, IndexError, NotImplementedError): differing += ('\nUnable to index element %d of first %s\n' % (i, seq_type_name)) break try: item2 = seq2[i] except (TypeError, IndexError, NotImplementedError): differing += ('\nUnable to index element %d of second %s\n' % (i, seq_type_name)) break if item1 != item2: differing += ('\nFirst differing element %d:\n%s\n%s\n' % (i, item1, item2)) break else: if (len1 == len2 and seq_type is None and type(seq1) != type(seq2)): # The sequences are the same, but have differing types. return if len1 > len2: differing += ('\nFirst %s contains %d additional ' 'elements.\n' % (seq_type_name, len1 - len2)) try: differing += ('First extra element %d:\n%s\n' % (len2, seq1[len2])) except (TypeError, IndexError, NotImplementedError): differing += ('Unable to index element %d ' 'of first %s\n' % (len2, seq_type_name)) elif len1 < len2: differing += ('\nSecond %s contains %d additional ' 'elements.\n' % (seq_type_name, len2 - len1)) try: differing += ('First extra element %d:\n%s\n' % (len1, seq2[len1])) except (TypeError, IndexError, NotImplementedError): differing += ('Unable to index element %d ' 'of second %s\n' % (len1, seq_type_name)) standardMsg = differing diffMsg = '\n' + '\n'.join( difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) standardMsg = self._truncateMessage(standardMsg, diffMsg) msg = self._formatMessage(msg, standardMsg) self.fail(msg) def _truncateMessage(self, message, diff): max_diff = self.maxDiff if max_diff is None or len(diff) <= max_diff: return message + diff return message + (DIFF_OMITTED % len(diff)) def assertListEqual(self, list1, list2, msg=None): """A list-specific equality assertion. Args: list1: The first list to compare. list2: The second list to compare. msg: Optional message to use on failure instead of a list of differences. """ self.assertSequenceEqual(list1, list2, msg, seq_type=list) def assertTupleEqual(self, tuple1, tuple2, msg=None): """A tuple-specific equality assertion. Args: tuple1: The first tuple to compare. tuple2: The second tuple to compare. msg: Optional message to use on failure instead of a list of differences. """ self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple) def assertSetEqual(self, set1, set2, msg=None): """A set-specific equality assertion. Args: set1: The first set to compare. set2: The second set to compare. msg: Optional message to use on failure instead of a list of differences. assertSetEqual uses ducktyping to support different types of sets, and is optimized for sets specifically (parameters must support a difference method). """ try: difference1 = set1.difference(set2) except TypeError, e: self.fail('invalid type when attempting set difference: %s' % e) except AttributeError, e: self.fail('first argument does not support set difference: %s' % e) try: difference2 = set2.difference(set1) except TypeError, e: self.fail('invalid type when attempting set difference: %s' % e) except AttributeError, e: self.fail('second argument does not support set difference: %s' % e) if not (difference1 or difference2): return lines = [] if difference1: lines.append('Items in the first set but not the second:') for item in difference1: lines.append(repr(item)) if difference2: lines.append('Items in the second set but not the first:') for item in difference2: lines.append(repr(item)) standardMsg = '\n'.join(lines) self.fail(self._formatMessage(msg, standardMsg)) def assertIn(self, member, container, msg=None): """Just like self.assertTrue(a in b), but with a nicer default message.""" if member not in container: standardMsg = '%s not found in %s' % (safe_repr(member), safe_repr(container)) self.fail(self._formatMessage(msg, standardMsg)) def assertNotIn(self, member, container, msg=None): """Just like self.assertTrue(a not in b), but with a nicer default message.""" if member in container: standardMsg = '%s unexpectedly found in %s' % (safe_repr(member), safe_repr(container)) self.fail(self._formatMessage(msg, standardMsg)) def assertIs(self, expr1, expr2, msg=None): """Just like self.assertTrue(a is b), but with a nicer default message.""" if expr1 is not expr2: standardMsg = '%s is not %s' % (safe_repr(expr1), safe_repr(expr2)) self.fail(self._formatMessage(msg, standardMsg)) def assertIsNot(self, expr1, expr2, msg=None): """Just like self.assertTrue(a is not b), but with a nicer default message.""" if expr1 is expr2: standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),) self.fail(self._formatMessage(msg, standardMsg)) def assertDictEqual(self, d1, d2, msg=None): self.assert_(isinstance(d1, dict), 'First argument is not a dictionary') self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') if d1 != d2: standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) diff = ('\n' + '\n'.join(difflib.ndiff( pprint.pformat(d1).splitlines(), pprint.pformat(d2).splitlines()))) standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) def assertDictContainsSubset(self, expected, actual, msg=None): """Checks whether actual is a superset of expected.""" missing = [] mismatched = [] for key, value in expected.iteritems(): if key not in actual: missing.append(key) elif value != actual[key]: mismatched.append('%s, expected: %s, actual: %s' % (safe_repr(key), safe_repr(value), safe_repr(actual[key]))) if not (missing or mismatched): return standardMsg = '' if missing: standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in missing) if mismatched: if standardMsg: standardMsg += '; ' standardMsg += 'Mismatched values: %s' % ','.join(mismatched) self.fail(self._formatMessage(msg, standardMsg)) def assertItemsEqual(self, expected_seq, actual_seq, msg=None): """An unordered sequence specific comparison. It asserts that expected_seq and actual_seq contain the same elements. It is the equivalent of:: self.assertEqual(sorted(expected_seq), sorted(actual_seq)) Raises with an error message listing which elements of expected_seq are missing from actual_seq and vice versa if any. Asserts that each element has the same count in both sequences. Example: - [0, 1, 1] and [1, 0, 1] compare equal. - [0, 0, 1] and [0, 1] compare unequal. """ try: expected = sorted(expected_seq) actual = sorted(actual_seq) except TypeError: # Unsortable items (example: set(), complex(), ...) expected = list(expected_seq) actual = list(actual_seq) missing, unexpected = unorderable_list_difference( expected, actual, ignore_duplicate=False ) else: return self.assertSequenceEqual(expected, actual, msg=msg) errors = [] if missing: errors.append('Expected, but missing:\n %s' % safe_repr(missing)) if unexpected: errors.append('Unexpected, but present:\n %s' % safe_repr(unexpected)) if errors: standardMsg = '\n'.join(errors) self.fail(self._formatMessage(msg, standardMsg)) def assertMultiLineEqual(self, first, second, msg=None): """Assert that two multi-line strings are equal.""" self.assert_(isinstance(first, basestring), ( 'First argument is not a string')) self.assert_(isinstance(second, basestring), ( 'Second argument is not a string')) if first != second: standardMsg = '%s != %s' % (safe_repr(first, True), safe_repr(second, True)) diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) def assertLess(self, a, b, msg=None): """Just like self.assertTrue(a < b), but with a nicer default message.""" if not a < b: standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b)) self.fail(self._formatMessage(msg, standardMsg)) def assertLessEqual(self, a, b, msg=None): """Just like self.assertTrue(a <= b), but with a nicer default message.""" if not a <= b: standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b)) self.fail(self._formatMessage(msg, standardMsg)) def assertGreater(self, a, b, msg=None): """Just like self.assertTrue(a > b), but with a nicer default message.""" if not a > b: standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b)) self.fail(self._formatMessage(msg, standardMsg)) def assertGreaterEqual(self, a, b, msg=None): """Just like self.assertTrue(a >= b), but with a nicer default message.""" if not a >= b: standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b)) self.fail(self._formatMessage(msg, standardMsg)) def assertIsNone(self, obj, msg=None): """Same as self.assertTrue(obj is None), with a nicer default message.""" if obj is not None: standardMsg = '%s is not None' % (safe_repr(obj),) self.fail(self._formatMessage(msg, standardMsg)) def assertIsNotNone(self, obj, msg=None): """Included for symmetry with assertIsNone.""" if obj is None: standardMsg = 'unexpectedly None' self.fail(self._formatMessage(msg, standardMsg)) def assertIsInstance(self, obj, cls, msg=None): """Same as self.assertTrue(isinstance(obj, cls)), with a nicer default message.""" if not isinstance(obj, cls): standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls) self.fail(self._formatMessage(msg, standardMsg)) def assertNotIsInstance(self, obj, cls, msg=None): """Included for symmetry with assertIsInstance.""" if isinstance(obj, cls): standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls) self.fail(self._formatMessage(msg, standardMsg)) def assertRaisesRegexp(self, expected_exception, expected_regexp, callable_obj=None, *args, **kwargs): """Asserts that the message in a raised exception matches a regexp. Args: expected_exception: Exception class expected to be raised. expected_regexp: Regexp (re pattern object or string) expected to be found in error message. callable_obj: Function to be called. args: Extra args. kwargs: Extra kwargs. """ if callable_obj is None: return _AssertRaisesContext(expected_exception, self, expected_regexp) try: callable_obj(*args, **kwargs) except expected_exception, exc_value: if isinstance(expected_regexp, basestring): expected_regexp = re.compile(expected_regexp) if not expected_regexp.search(str(exc_value)): raise self.failureException('"%s" does not match "%s"' % (expected_regexp.pattern, str(exc_value))) else: if hasattr(expected_exception, '__name__'): excName = expected_exception.__name__ else: excName = str(expected_exception) raise self.failureException, "%s not raised" % excName def assertRegexpMatches(self, text, expected_regexp, msg=None): """Fail the test unless the text matches the regular expression.""" if isinstance(expected_regexp, basestring): expected_regexp = re.compile(expected_regexp) if not expected_regexp.search(text): msg = msg or "Regexp didn't match" msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text) raise self.failureException(msg) def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None): """Fail the test if the text matches the regular expression.""" if isinstance(unexpected_regexp, basestring): unexpected_regexp = re.compile(unexpected_regexp) match = unexpected_regexp.search(text) if match: msg = msg or "Regexp matched" msg = '%s: %r matches %r in %r' % (msg, text[match.start():match.end()], unexpected_regexp.pattern, text) raise self.failureException(msg) class FunctionTestCase(TestCase): """A test case that wraps a test function. This is useful for slipping pre-existing test functions into the unittest framework. Optionally, set-up and tidy-up functions can be supplied. As with TestCase, the tidy-up ('tearDown') function will always be called if the set-up ('setUp') function ran successfully. """ def __init__(self, testFunc, setUp=None, tearDown=None, description=None): super(FunctionTestCase, self).__init__() self._setUpFunc = setUp self._tearDownFunc = tearDown self._testFunc = testFunc self._description = description def setUp(self): if self._setUpFunc is not None: self._setUpFunc() def tearDown(self): if self._tearDownFunc is not None: self._tearDownFunc() def runTest(self): self._testFunc() def id(self): return self._testFunc.__name__ def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented return self._setUpFunc == other._setUpFunc and \ self._tearDownFunc == other._tearDownFunc and \ self._testFunc == other._testFunc and \ self._description == other._description def __ne__(self, other): return not self == other def __hash__(self): return hash((type(self), self._setUpFunc, self._tearDownFunc, self._testFunc, self._description)) def __str__(self): return "%s (%s)" % (strclass(self.__class__), self._testFunc.__name__) def __repr__(self): return "<%s testFunc=%s>" % (strclass(self.__class__), self._testFunc) def shortDescription(self): if self._description is not None: return self._description doc = self._testFunc.__doc__ return doc and doc.split("\n")[0].strip() or None distlib-0.2.2/tests/unittest2/suite.py0000664000000000000000000002230612030667514016462 0ustar rootroot"""TestSuite""" import sys import unittest from unittest2 import case, util __unittest = True class BaseTestSuite(unittest.TestSuite): """A simple test suite that doesn't provide class or module shared fixtures. """ def __init__(self, tests=()): self._tests = [] self.addTests(tests) def __repr__(self): return "<%s tests=%s>" % (util.strclass(self.__class__), list(self)) def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented return list(self) == list(other) def __ne__(self, other): return not self == other # Can't guarantee hash invariant, so flag as unhashable __hash__ = None def __iter__(self): return iter(self._tests) def countTestCases(self): cases = 0 for test in self: cases += test.countTestCases() return cases def addTest(self, test): # sanity checks if not hasattr(test, '__call__'): raise TypeError("%r is not callable" % (repr(test),)) if isinstance(test, type) and issubclass(test, (case.TestCase, TestSuite)): raise TypeError("TestCases and TestSuites must be instantiated " "before passing them to addTest()") self._tests.append(test) def addTests(self, tests): if isinstance(tests, basestring): raise TypeError("tests must be an iterable of tests, not a string") for test in tests: self.addTest(test) def run(self, result): for test in self: if result.shouldStop: break test(result) return result def __call__(self, *args, **kwds): return self.run(*args, **kwds) def debug(self): """Run the tests without collecting errors in a TestResult""" for test in self: test.debug() class TestSuite(BaseTestSuite): """A test suite is a composite test consisting of a number of TestCases. For use, create an instance of TestSuite, then add test case instances. When all tests have been added, the suite can be passed to a test runner, such as TextTestRunner. It will run the individual test cases in the order in which they were added, aggregating the results. When subclassing, do not forget to call the base class constructor. """ def run(self, result): self._wrapped_run(result) self._tearDownPreviousClass(None, result) self._handleModuleTearDown(result) return result def debug(self): """Run the tests without collecting errors in a TestResult""" debug = _DebugResult() self._wrapped_run(debug, True) self._tearDownPreviousClass(None, debug) self._handleModuleTearDown(debug) ################################ # private methods def _wrapped_run(self, result, debug=False): for test in self: if result.shouldStop: break if _isnotsuite(test): self._tearDownPreviousClass(test, result) self._handleModuleFixture(test, result) self._handleClassSetUp(test, result) result._previousTestClass = test.__class__ if (getattr(test.__class__, '_classSetupFailed', False) or getattr(result, '_moduleSetUpFailed', False)): continue if hasattr(test, '_wrapped_run'): test._wrapped_run(result, debug) elif not debug: test(result) else: test.debug() def _handleClassSetUp(self, test, result): previousClass = getattr(result, '_previousTestClass', None) currentClass = test.__class__ if currentClass == previousClass: return if result._moduleSetUpFailed: return if getattr(currentClass, "__unittest_skip__", False): return try: currentClass._classSetupFailed = False except TypeError: # test may actually be a function # so its class will be a builtin-type pass setUpClass = getattr(currentClass, 'setUpClass', None) if setUpClass is not None: try: setUpClass() except Exception, e: if isinstance(result, _DebugResult): raise currentClass._classSetupFailed = True className = util.strclass(currentClass) errorName = 'setUpClass (%s)' % className self._addClassOrModuleLevelException(result, e, errorName) def _get_previous_module(self, result): previousModule = None previousClass = getattr(result, '_previousTestClass', None) if previousClass is not None: previousModule = previousClass.__module__ return previousModule def _handleModuleFixture(self, test, result): previousModule = self._get_previous_module(result) currentModule = test.__class__.__module__ if currentModule == previousModule: return self._handleModuleTearDown(result) result._moduleSetUpFailed = False try: module = sys.modules[currentModule] except KeyError: return setUpModule = getattr(module, 'setUpModule', None) if setUpModule is not None: try: setUpModule() except Exception, e: if isinstance(result, _DebugResult): raise result._moduleSetUpFailed = True errorName = 'setUpModule (%s)' % currentModule self._addClassOrModuleLevelException(result, e, errorName) def _addClassOrModuleLevelException(self, result, exception, errorName): error = _ErrorHolder(errorName) addSkip = getattr(result, 'addSkip', None) if addSkip is not None and isinstance(exception, case.SkipTest): addSkip(error, str(exception)) else: result.addError(error, sys.exc_info()) def _handleModuleTearDown(self, result): previousModule = self._get_previous_module(result) if previousModule is None: return if result._moduleSetUpFailed: return try: module = sys.modules[previousModule] except KeyError: return tearDownModule = getattr(module, 'tearDownModule', None) if tearDownModule is not None: try: tearDownModule() except Exception, e: if isinstance(result, _DebugResult): raise errorName = 'tearDownModule (%s)' % previousModule self._addClassOrModuleLevelException(result, e, errorName) def _tearDownPreviousClass(self, test, result): previousClass = getattr(result, '_previousTestClass', None) currentClass = test.__class__ if currentClass == previousClass: return if getattr(previousClass, '_classSetupFailed', False): return if getattr(result, '_moduleSetUpFailed', False): return if getattr(previousClass, "__unittest_skip__", False): return tearDownClass = getattr(previousClass, 'tearDownClass', None) if tearDownClass is not None: try: tearDownClass() except Exception, e: if isinstance(result, _DebugResult): raise className = util.strclass(previousClass) errorName = 'tearDownClass (%s)' % className self._addClassOrModuleLevelException(result, e, errorName) class _ErrorHolder(object): """ Placeholder for a TestCase inside a result. As far as a TestResult is concerned, this looks exactly like a unit test. Used to insert arbitrary errors into a test suite run. """ # Inspired by the ErrorHolder from Twisted: # http://twistedmatrix.com/trac/browser/trunk/twisted/trial/runner.py # attribute used by TestResult._exc_info_to_string failureException = None def __init__(self, description): self.description = description def id(self): return self.description def shortDescription(self): return None def __repr__(self): return "" % (self.description,) def __str__(self): return self.id() def run(self, result): # could call result.addError(...) - but this test-like object # shouldn't be run anyway pass def __call__(self, result): return self.run(result) def countTestCases(self): return 0 def _isnotsuite(test): "A crude way to tell apart testcases and suites with duck-typing" try: iter(test) except TypeError: return True return False class _DebugResult(object): "Used by the TestSuite to hold previous class when running in debug." _previousTestClass = None _moduleSetUpFailed = False shouldStop = False distlib-0.2.2/tests/unittest2/__init__.py0000664000000000000000000000454612030667514017076 0ustar rootroot""" unittest2 unittest2 is a backport of the new features added to the unittest testing framework in Python 2.7. It is tested to run on Python 2.4 - 2.6. To use unittest2 instead of unittest simply replace ``import unittest`` with ``import unittest2``. Copyright (c) 1999-2003 Steve Purcell Copyright (c) 2003-2010 Python Software Foundation This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ __all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', '__version__', 'collector'] __version__ = '0.5.1' # Expose obsolete functions for backwards compatibility __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) from unittest2.collector import collector from unittest2.result import TestResult from unittest2.case import ( TestCase, FunctionTestCase, SkipTest, skip, skipIf, skipUnless, expectedFailure ) from unittest2.suite import BaseTestSuite, TestSuite from unittest2.loader import ( TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, findTestCases ) from unittest2.main import TestProgram, main, main_ from unittest2.runner import TextTestRunner, TextTestResult try: from unittest2.signals import ( installHandler, registerResult, removeResult, removeHandler ) except ImportError: # Compatibility with platforms that don't have the signal module pass else: __all__.extend(['installHandler', 'registerResult', 'removeResult', 'removeHandler']) # deprecated _TextTestResult = TextTestResult __unittest = Truedistlib-0.2.2/tests/test_version.py0000664000000000000000000005446412445642546016136 0ustar rootroot# # Copyright (C) 2012-2013 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # """Tests for distlib.version.""" import doctest from compat import unittest from distlib.version import (NormalizedVersion as NV, NormalizedMatcher as NM, UnsupportedVersionError, _suggest_normalized_version, _suggest_semantic_version, LegacyVersion as LV, LegacyMatcher as LM, SemanticVersion as SV, SemanticMatcher as SM, is_semver, get_scheme, _normalized_key, _legacy_key, _semantic_key) class VersionTestCase(unittest.TestCase): versions = ((NV('1.0'), '1.0'), (NV('1.1'), '1.1'), (NV('1.2.3'), '1.2.3'), (NV('1.2'), '1.2'), (NV('1.2.3a4'), '1.2.3a4'), (NV('1.2c4'), '1.2c4'), (NV('4.17rc2'), '4.17rc2'), (NV('1.2.3.4'), '1.2.3.4'), #(NV('1.2.3.4.0b3', drop_trailing_zeros=True), '1.2.3.4b3'), #(NV('1.2.0.0.0', drop_trailing_zeros=True), '1.2'), (NV('1.0.dev345'), '1.0.dev345'), (NV('1.0.post456.dev623'), '1.0.post456.dev623'), (NV('1.2.3+1.2'), '1.2.3+1.2'), (NV('1.2.3+a1.b2'), '1.2.3+a1.b2'), ) def test_repr(self): self.assertEqual(repr(NV('1.0')), "NormalizedVersion('1.0')") def test_basic_versions(self): for v, s in self.versions: self.assertEqual(str(v), s) def test_hash(self): for v, s in self.versions: self.assertEqual(hash(v), hash(NV(s))) versions = set([v for v, s in self.versions]) for v, s in self.versions: self.assertIn(v, versions) self.assertEqual(set([NV('1.0')]), set([NV('1.0'), NV('1.0')])) def test_unsupported_versions(self): unsupported = ('1.2a', '1.2.3b', #'1.02', '1.2a03', '1.2a3.04', '1.2.dev.2', '1.2dev', '1.2.dev', '1.2-', '1.2-a', '1.2.dev2.post2', '1.2.post2.dev3.post4') for s in unsupported: self.assertRaises(UnsupportedVersionError, NV, s) def test_huge_version(self): self.assertEqual(str(NV('1980.0')), '1980.0') def test_comparison(self): comparison_doctest_string = r""" >>> NV('1.2.0') == '1.2' Traceback (most recent call last): ... TypeError: cannot compare NormalizedVersion and str >>> NV('1.2') < '1.3' Traceback (most recent call last): ... TypeError: cannot compare NormalizedVersion and str >>> NV('1.2.0') == NV('1.2') True >>> NV('1.2.0') == NV('1.2.3') False >>> NV('1.2.0') != NV('1.2.3') True >>> NV('1.2.0') < NV('1.2.3') True >>> NV('1.2.0') < NV('1.2.0') False >>> NV('1.2.0') <= NV('1.2.0') True >>> NV('1.2.0') <= NV('1.2.3') True >>> NV('1.2.3') <= NV('1.2.0') False >>> NV('1.2.0') >= NV('1.2.0') True >>> NV('1.2.3') >= NV('1.2.0') True >>> NV('1.2.0') >= NV('1.2.3') False >>> NV('1.2.0rc1') >= NV('1.2.0') False >>> NV('1.0') > NV('1.0b2') True >>> NV('1.0') > NV('1.0c2') True >>> NV('1.0') > NV('1.0rc2') True >>> NV('1.0rc2') > NV('1.0rc1') True >>> NV('1.0c4') > NV('1.0c1') True >>> (NV('1.0') > NV('1.0c2') > NV('1.0c1') > NV('1.0b2') > NV('1.0b1') ... > NV('1.0a2') > NV('1.0a1')) True >>> (NV('1.0.0') > NV('1.0.0c2') > NV('1.0.0c1') > NV('1.0.0b2') > NV('1.0.0b1') ... > NV('1.0.0a2') > NV('1.0.0a1')) True >>> NV('1.0') < NV('1.0.post456.dev623') True >>> NV('1.0.post456.dev623') < NV('1.0.post456') < NV('1.0.post1234') True >>> (NV('1.0a1') ... < NV('1.0a2.dev456') ... < NV('1.0a2') ... < NV('1.0a2.1.dev456') # e.g. need to do a quick post release on 1.0a2 ... < NV('1.0a2.1') ... < NV('1.0b1.dev456') ... < NV('1.0b2') ... < NV('1.0c1.dev456') ... < NV('1.0c1') ... < NV('1.0c1-1') ... < NV('1.0c1-1.1') ... < NV('1.0.dev7') ... < NV('1.0.dev18') ... < NV('1.0.dev456') ... < NV('1.0.dev1234') ... < NV('1.0rc1') ... < NV('1.0rc2') ... < NV('1.0') ... < NV('1.0-1') ... < NV('1.0-1.1') ... < NV('1.0.post456.dev623') # development version of a post release ... < NV('1.0.post456.dev623-1') ... < NV('1.0.post456.dev623-1.1') ... < NV('1.0.post456') < NV('1.0.post456-1') < NV('1.0.post456-1.1')) True """ doctest.script_from_examples(comparison_doctest_string) # the doctest above is never run, so temporarily add real unit # tests until the doctest is rewritten self.assertLessEqual(NV('1.2.0rc1'), NV('1.2.0')) self.assertGreater(NV('1.0'), NV('1.0c2')) self.assertGreater(NV('1.0'), NV('1.0rc2')) self.assertGreater(NV('1.0rc2'), NV('1.0rc1')) self.assertGreater(NV('1.0c4'), NV('1.0c1')) def test_suggest_normalized_version(self): suggest = _suggest_normalized_version self.assertEqual(suggest('1.0'), '1.0') self.assertEqual(suggest('1.0-alpha1'), '1.0a1') self.assertEqual(suggest('1.0c2'), '1.0c2') self.assertEqual(suggest('walla walla washington'), None) self.assertEqual(suggest('2.4c1'), '2.4c1') self.assertEqual(suggest('v1.0'), 'v1.0') # from setuptools self.assertEqual(suggest('0.4a1.r10'), '0.4a1.post10') self.assertEqual(suggest('0.7a1dev-r66608'), '0.7a1.dev66608') self.assertEqual(suggest('0.6a9.dev-r41475'), '0.6a9.dev41475') self.assertEqual(suggest('2.4preview1'), '2.4c1') self.assertEqual(suggest('2.4pre1'), '2.4c1') self.assertEqual(suggest('2.1-rc2'), '2.1c2') # from pypi self.assertEqual(suggest('0.1dev'), '0.1.dev0') self.assertEqual(suggest('0.1.dev'), '0.1.dev0') # we want to be able to parse Twisted # development versions are like post releases in Twisted #self.assertEqual(suggest('9.0.0+r2363'), '9.0.0.post2363') # pre-releases are using markers like "pre1" self.assertEqual(suggest('9.0.0pre1'), '9.0.0c1') # we want to be able to parse Tcl-TK # they us "p1" "p2" for post releases self.assertEqual(suggest('1.4p1'), '1.4.post1') def test_suggestions_other(self): suggest = _suggest_semantic_version self.assertEqual(suggest(''), '0.0.0') self.assertEqual(suggest('1'), '1.0.0') self.assertEqual(suggest('1.2'), '1.2.0') def test_matcher(self): # NormalizedMatcher knows how to parse stuff like: # # Project (>=version, ver2) constraints = ('zope.interface (>3.5.0)', 'AnotherProject (3.4)', 'OtherProject (<3.0)', 'NoVersion', 'Hey (>=2.5,<2.7)') for constraint in constraints: NM(constraint) self.assertTrue(NM('Hey (>=2.5,<2.7)').match('2.6')) self.assertTrue(NM('Ho').match('2.6')) self.assertFalse(NM('Hey (>=2.5,!=2.6,<2.7)').match('2.6')) self.assertTrue(NM('Ho (<3.0)').match('2.6')) self.assertTrue(NM('Ho (<3.0,!=2.5)').match('2.6.0')) self.assertFalse(NM('Ho (<3.0,!=2.6)').match('2.6.0')) self.assertTrue(NM('Ho (2.5)').match('2.5.4')) self.assertFalse(NM('Ho (==2.5)').match('2.50')) self.assertTrue(NM('Ho (!=2.5)').match('2.5.2')) self.assertFalse(NM('Hey (<=2.5)').match('2.5.9')) self.assertFalse(NM('Hey (<=2.5)').match('2.6.0')) self.assertTrue(NM('Hey (>=2.5)').match('2.5.1')) self.assertRaises(ValueError, NM, '') # We don't allow #self.assertTrue(NM('Hey 2.5').match('2.5.1')) #self.assertTrue(NM('vi5two 1.0').match('1.0')) #self.assertTrue(NM('5two 1.0').match('1.0')) self.assertTrue(NM('Ho (<3.0,!=2.6)').match('2.6.3')) # Make sure a constraint that ends with a number works self.assertTrue(NM('virtualenv5 (1.0)').match('1.0')) self.assertTrue(NM('virtualenv5').match('1.0')) self.assertTrue(NM('vi5two').match('1.0')) self.assertTrue(NM('5two').match('1.0')) # test repr for constraint in constraints: self.assertEqual(str(NM(constraint)), constraint) #Test exact_version cases = ( ('Dummy', False), ('Dummy (1.0)', False), ('Dummy (<1.0)', False), ('Dummy (<=1.0)', False), ('Dummy (>1.0)', False), ('Dummy (>=1.0)', False), ('Dummy (==1.0)', True), ('Dummy (===1.0)', True), ('Dummy (!=1.0)', False), ) for s, b in cases: m = NM(s) self.assertEqual(m.exact_version is not None, b) def test_matcher_name(self): # Test that names are parsed the right way self.assertEqual('Hey', NM('Hey (<1.1)').name) self.assertEqual('Foo-Bar', NM('Foo-Bar (1.1)').name) self.assertEqual('Foo Bar', NM('Foo Bar (1.1)').name) def test_matcher_local(self): self.assertTrue(NM('Foo (>=2.5+1.2)').match('2.6.0+1.3')) self.assertFalse(NM('Foo (>=2.6+1.4)').match('2.6.0+1.3')) self.assertTrue(NM('Foo (>=2.6)').match('2.6+1.3')) # numeric > lexicographic in local versions self.assertTrue(NM('Foo (>2.6+a1.4)').match('2.6+1.4')) def test_schemes(self): cases = ( ('normalized', (_normalized_key, NV, NM)), ('legacy', (_legacy_key, LV, LM)), ('semantic', (_semantic_key, SV, SM)), ) for name, values in cases: scheme = get_scheme(name) key, version, matcher = values self.assertIs(key, scheme.key) self.assertIs(matcher, scheme.matcher) self.assertIs(version, scheme.matcher.version_class) self.assertIs(get_scheme('default'), get_scheme('normalized')) self.assertRaises(ValueError, get_scheme, 'random') def test_prereleases(self): pre_releases = ( '1.0.dev456', '1.0a1', '1.0a2.dev456', '1.0a12.dev456', '1.0a12', '1.0b1.dev456', '1.0b2', '1.0b2.post345.dev456', '1.0b2.post345', '1.0c1.dev456', '1.0c1', '1.0rc1', '1.0.post345.dev456', '1.1.dev1', '1.1.dev1+1.2', ) final_releases = ( '1.0', '1.0.post345', '1.0.post345+2.3', ) for s in pre_releases: self.assertTrue(NV(s).is_prerelease) for s in final_releases: self.assertFalse(NV(s).is_prerelease) def test_comparison_pep426(self): versions = ( '1.0.dev456', '1.0a1', '1.0a2.dev456', '1.0a12.dev456', '1.0a12', '1.0b1.dev456', '1.0b2', '1.0b2.post345.dev456', '1.0b2.post345', '1.0c1.dev456', '1.0c1', '1.0rc1', '1.0', '1.0.post345.dev456', '1.0.post345', '1.1.dev1', ) n = len(versions) for i in range(n - 1): v1 = versions[i] v2 = versions[i + 1] self.assertLess(NV(v1), NV(v2)) def test_440(self): # compatible release matching for s in ('foo (1.2)', 'foo (~= 1.2)'): m = NM(s) for should_match in ('1.2', '1.3', '1.2.post0'): msg = 'Failed for %s' % should_match self.assertTrue(m.match(should_match), msg) for should_not_match in ('1.0', '1.1', '1.2.dev0', '2.0'): msg = 'Failed for %s' % should_not_match self.assertFalse(m.match(should_not_match), msg) for s in ('foo (1.4.5)', 'foo (~= 1.4.5)', 'foo (1.4.5a4)'): m = NM(s) for should_match in ('1.4.5', '1.4.6', '1.4.7.dev0'): msg = 'Failed for %s' % should_match self.assertTrue(m.match(should_match), msg) for should_not_match in ('1.5', '1.6', '1.4.5.dev0', '2.4.5'): msg = 'Failed for %s' % should_not_match self.assertFalse(m.match(should_not_match), msg) m = NM('foo (1.4.5.0)') for should_match in ('1.4.5.0', '1.4.5.1', '1.4.5.9.post1'): msg = 'Failed for %s' % should_match self.assertTrue(m.match(should_match), msg) for should_not_match in ('1.4.6', '1.5', '2.0'): msg = 'Failed for %s' % should_not_match self.assertFalse(m.match(should_not_match), msg) # prefix matching v = '1.1.post1' cases = (('(== 1.1)', False), ('(== 1.1.post1)', True), ('(== 1.1.*)', True), ('(!= 1.1)', True), ('(!= 1.1.post1)', False), ('(!= 1.1.*)', False)) for s, expected in cases: m = NM('foo %s' % s) actual = m.match(v) self.assertEqual(expected, actual, 'Failed for %s' % s) # inclusive ordered m = NM('foo (<= 1.5)') for should_match in ('0.1', '1.4', '1.4.9.post1', '1.5.dev0', '1.5', '1.5.0', '1.5.0.0'): msg = 'Failed for %s' % should_match self.assertTrue(m.match(should_match), msg) for should_not_match in ('1.5.post1', '1.5.post0.dev0', '1.6', '2.0'): msg = 'Failed for %s' % should_not_match self.assertFalse(m.match(should_not_match), msg) m = NM('foo (>= 1.5)') for should_match in ('1.5.post1', '1.5.post0.dev0', '1.6', '2.0', '1.5', '1.5.0', '1.5.0.0'): msg = 'Failed for %s' % should_match self.assertTrue(m.match(should_match), msg) for should_not_match in ('0.1', '1.4', '1.4.9.post1', '1.5.dev0'): msg = 'Failed for %s' % should_not_match self.assertFalse(m.match(should_not_match), msg) # exclusive ordered m = NM('foo (< 1.5)') for should_match in ('0.1', '1.4', '1.4.9.post1'): msg = 'Failed for %s' % should_match self.assertTrue(m.match(should_match), msg) for should_not_match in ('1.5.post1', '1.5.post0.dev0', '1.5.dev0', '1.5', '1.5.0', '1.5.0.1', '1.6', '2.0'): msg = 'Failed for %s' % should_not_match self.assertFalse(m.match(should_not_match), msg) m = NM('foo (> 1.5)') for should_match in ('1.6', '2.0'): msg = 'Failed for %s' % should_match self.assertTrue(m.match(should_match), msg) for should_not_match in ('0.1', '1.4', '1.4.9.post1', '1.5.dev0', '1.5', '1.5.0', '1.5.post0','1.5.post0.dev0', '1.5.0.1'): msg = 'Failed for %s' % should_not_match self.assertFalse(m.match(should_not_match), msg) #unusual prefix matching m = NM('foo (== 1.2.post0.*)') for should_match in ('1.2.post0', '1.2.post0.dev0'): msg = 'Failed for %s' % should_match self.assertTrue(m.match(should_match), msg) for should_not_match in ('1.2', '1.2.dev0'): msg = 'Failed for %s' % should_not_match self.assertFalse(m.match(should_not_match), msg) # invalid for op in ('<', '<=', '>', '>=', '~='): s = 'foo (%s 1.*)' % op self.assertRaises(ValueError, NM, s) for v in ('', '1.*.*'): s = 'foo (== %s)' % v self.assertRaises(ValueError, NM, s) class LegacyVersionTestCase(unittest.TestCase): # These tests are the same as distribute's def test_equality(self): def compare(a, b): ka, kb = _legacy_key(a), _legacy_key(b) self.assertEqual(ka, kb) compare('0.4', '0.4.0') compare('0.4.0.0', '0.4.0') compare('0.4.0-0', '0.4-0') compare('0pl1', '0.0pl1') compare('0pre1', '0.0c1') compare('0.0.0preview1', '0c1') compare('0.0c1', '0rc1') compare('1.2a1', '1.2.a.1') compare('1.2...a', '1.2a') def test_ordering(self): def compare(a, b): ka, kb = _legacy_key(a), _legacy_key(b) self.assertLess(ka, kb) compare('2.1','2.1.1') compare('2.1.0','2.10') compare('2a1','2b0') compare('2b1','2c0') compare('2a1','2.1') compare('2.3a1', '2.3') compare('2.1-1', '2.1-2') compare('2.1-1', '2.1.1') compare('2.1', '2.1.1-1') compare('2.1', '2.1pl4') compare('2.1a0-20040501', '2.1') compare('1.1', '02.1') compare('A56','B27') compare('3.2', '3.2.pl0') compare('3.2-1', '3.2pl1') compare('3.2pl1', '3.2pl1-1') compare('0.4', '4.0') compare('0.0.4', '0.4.0') compare('0pl1', '0.4pl1') compare('2.1dev','2.1a0') compare('2.1.0rc1','2.1.0') compare('2.1.0-rc0','2.1.0') compare('2.1.0-a','2.1.0') compare('2.1.0-alpha','2.1.0') compare('2.1.0','2.1.0-foo') compare('1.0','1.0-1') compare('1.0-1','1.0.1') compare('1.0a','1.0b') compare('1.0dev','1.0rc1') compare('1.0pre','1.0') compare('1.0pre','1.0') versions = """ 0.80.1-3 0.80.1-2 0.80.1-1 0.79.9999+0.80.0pre4-1 0.79.9999+0.80.0pre2-3 0.79.9999+0.80.0pre2-2 0.77.2-1 0.77.1-1 0.77.0-1 """.split() for i, v1 in enumerate(versions): for v2 in versions[i+1:]: compare(v2, v1) def test_absolute(self): cases = ( ('1.0-beta6', ('00000001', '*beta', '00000006', '*final')), ) for k, v in cases: self.assertEqual(_legacy_key(k), v) def test_prereleases(self): pre_releases = ( '2.1.0-alpha', '0.79.9999+0.80.0pre4-1', '1.0dev', '2.1a0', '1.0rc1', 'A56', '1.0b', '0.79.9999+0.80.0', '2013b', '2013f', ) final_releases = ( '0.80.1-3', '2.1.0', '3.2pl1-1', ) for s in pre_releases: self.assertTrue(LV(s).is_prerelease, s) for s in final_releases: self.assertFalse(LV(s).is_prerelease, s) class SemanticVersionTestCase(unittest.TestCase): def test_basic(self): bad = [ 'a', '1', '1.', '1.2' , '1.2.', '1.2.a', '1.2.3.a', ] good = [ '1.2.3', '1.2.3-pre.1.abc.2.def', '1.2.3+post.1.abc.2.def', '1.2.3-pre.1.abc.2.def+post.1.abc.2.def', ] for s in bad: self.assertFalse(is_semver(s)) self.assertRaises(UnsupportedVersionError, _semantic_key, s) for s in good: self.assertTrue(is_semver(s)) def test_ordering(self): def compare(a, b): ka, kb = _semantic_key(a), _semantic_key(b) self.assertLess(ka, kb) # From the semver.org home page versions = ( '1.0.0-alpha', '1.0.0-alpha.1', '1.0.0-beta.2', '1.0.0-beta.11', '1.0.0-rc.1', '1.0.0-rc.1+build.1', '1.0.0', '1.0.0+0.3.7', '1.3.7+build', '1.3.7+build.2.b8f12d7', '1.3.7+build.11.e0f985a', ) for i, v1 in enumerate(versions): for v2 in versions[i+1:]: compare(v1, v2) def test_prereleases(self): pre_releases = ( '1.0.0-alpha', '1.0.0-alpha.1', '1.0.0-beta.2', '1.0.0-beta.11', '1.0.0-rc.1', '1.0.0-rc.1+build.1', ) final_releases = ( '1.0.0', '1.0.0+0.3.7', '1.3.7+build', '1.3.7+build.2.b8f12d7', '1.3.7+build.11.e0f985a', ) for s in pre_releases: self.assertTrue(SV(s).is_prerelease) for s in final_releases: self.assertFalse(SV(s).is_prerelease) class CompatibilityTestCase(unittest.TestCase): def test_basic(self): def are_equal(v1, v2): return v1 == v2 def is_less(v1, v2): return v1 < v2 self.assertRaises(TypeError, are_equal, NV('3.3.0'), SV('3.3.0')) self.assertRaises(TypeError, are_equal, NV('3.3.0'), LV('3.3.0')) self.assertRaises(TypeError, are_equal, LV('3.3.0'), SV('3.3.0')) self.assertRaises(TypeError, are_equal, NM('foo'), LV('foo')) self.assertRaises(TypeError, are_equal, NM('foo'), NM('bar')) def test_suite(): #README = os.path.join(os.path.dirname(__file__), 'README.txt') #suite = [doctest.DocFileSuite(README), unittest.makeSuite(VersionTestCase)] suite = [unittest.makeSuite(VersionTestCase), unittest.makeSuite(CompatibilityTestCase), unittest.makeSuite(LegacyVersionTestCase), unittest.makeSuite(SemanticVersionTestCase)] return unittest.TestSuite(suite) if __name__ == "__main__": # pragma: no cover import logging import os import sys here = os.path.dirname(os.path.abspath(__file__)) rundir = os.path.join(here, 'run') if not os.path.exists(rundir): os.mkdir(rundir) elif not os.path.isdir(rundir): raise ValueError('Not a directory: %r' % rundir) fn = os.path.join(rundir, 'test_version_%d.%d.log' % sys.version_info[:2]) logging.basicConfig(level=logging.DEBUG, filename=fn, filemode='w', format='%(name)s %(funcName)s %(message)s') unittest.main(defaultTest="test_suite") distlib-0.2.2/tests/bad.zip0000664000000000000000000000170412056760160014266 0ustar rootrootPK iA file1.txtUT 5P}Pux PK tAsubdir/UT KPZPux PK zAsubdir/subsubdir/UT WPZPux PK zAsubdir/subsubdir/file3.txtUT WP}Pux PK pAsubdir/file2.txtUT DP}Pux PK UA ../file4.txtUT ҖPܖPux PK iA file1.txtUT5Pux PK tAACsubdir/UTKPux PK zAAsubdir/subsubdir/UTWPux PK zAsubdir/subsubdir/file3.txtUTWPux PK pA#subdir/file2.txtUTDPux PK UA m../file4.txtUTҖPux PKdistlib-0.2.2/tests/test_locators.py0000664000000000000000000005211112653165706016261 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # from __future__ import unicode_literals import os import sys from compat import unittest from distlib.compat import url2pathname, urlparse, urljoin from distlib.database import (Distribution, DistributionPath, make_graph, make_dist) from distlib.locators import (SimpleScrapingLocator, PyPIRPCLocator, PyPIJSONLocator, DirectoryLocator, DistPathLocator, AggregatingLocator, JSONLocator, DistPathLocator, DependencyFinder, locate, get_all_distribution_names, default_locator) HERE = os.path.abspath(os.path.dirname(__file__)) PYPI_RPC_HOST = 'http://python.org/pypi' PYPI_WEB_HOST = os.environ.get('PYPI_WEB_HOST', 'https://pypi.python.org/simple/') class LocatorTestCase(unittest.TestCase): @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_xmlrpc(self): locator = PyPIRPCLocator(PYPI_RPC_HOST) try: result = locator.get_project('sarge') except Exception: # pragma: no cover raise unittest.SkipTest('PyPI XML-RPC not available') self.assertIn('0.1', result) dist = result['0.1'] self.assertEqual(dist.name, 'sarge') self.assertEqual(dist.version, '0.1') possible = ('https://pypi.python.org/packages/source/s/sarge/' 'sarge-0.1.tar.gz', 'http://pypi.python.org/packages/source/s/sarge/' 'sarge-0.1.tar.gz') self.assertIn(dist.source_url, possible) self.assertEqual(dist.digest, ('md5', '961ddd9bc085fdd8b248c6dd96ceb1c8')) try: names = locator.get_distribution_names() except Exception: # pragma: no cover raise unittest.SkipTest('PyPI XML-RPC not available') self.assertGreater(len(names), 25000) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_json(self): locator = PyPIJSONLocator(PYPI_RPC_HOST) result = locator.get_project('sarge') LATEST_SARGE_VERSION = '0.1.4' LATEST_SARGE_MD5 = '285013875aa908ef1417055d3e74a00a' self.assertIn(LATEST_SARGE_VERSION, result) dist = result[LATEST_SARGE_VERSION] self.assertEqual(dist.name, 'sarge') self.assertEqual(dist.version, LATEST_SARGE_VERSION) url = ('https://pypi.python.org/packages/source/s/sarge/' 'sarge-%s.tar.gz' % LATEST_SARGE_VERSION) self.assertIn(url, dist.download_urls) self.assertEqual(dist.digests[url],('md5', LATEST_SARGE_MD5)) self.assertRaises(NotImplementedError, locator.get_distribution_names) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_scraper(self): locator = SimpleScrapingLocator('https://pypi.python.org/simple/') for name in ('sarge', 'Sarge'): result = locator.get_project(name) self.assertIn('0.1', result) dist = result['0.1'] self.assertEqual(dist.name, 'sarge') self.assertEqual(dist.version, '0.1') self.assertEqual(dist.source_url, 'https://pypi.python.org/packages/source/s/sarge/' 'sarge-0.1.tar.gz') self.assertEqual(dist.digest, ('md5', '961ddd9bc085fdd8b248c6dd96ceb1c8')) return # The following is too slow names = locator.get_distribution_names() self.assertGreater(len(names), 25000) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_unicode_project_name(self): # Just checking to see that no exceptions are raised. NAME = '\u2603' locator = SimpleScrapingLocator('https://pypi.python.org/simple/') result = locator.get_project(NAME) expected = {'urls': {}, 'digests': {}} self.assertEqual(result, expected) locator = PyPIJSONLocator('https://pypi.python.org/pypi/') result = locator.get_project(NAME) self.assertEqual(result, expected) def test_dir(self): d = os.path.join(HERE, 'fake_archives') locator = DirectoryLocator(d) expected = os.path.join(HERE, 'fake_archives', 'subdir', 'subsubdir', 'Flask-0.9.tar.gz') def get_path(url): t = urlparse(url) return url2pathname(t.path) for name in ('flask', 'Flask'): result = locator.get_project(name) self.assertIn('0.9', result) dist = result['0.9'] self.assertEqual(dist.name, 'Flask') self.assertEqual(dist.version, '0.9') self.assertEqual(os.path.normcase(get_path(dist.source_url)), os.path.normcase(expected)) names = locator.get_distribution_names() expected = set(['Flask', 'python-gnupg', 'coverage', 'Django']) if sys.version_info[:2] == (2, 7): expected.add('config') self.assertEqual(names, expected) def test_dir_nonrecursive(self): d = os.path.join(HERE, 'fake_archives') locator = DirectoryLocator(d, recursive=False) expected = os.path.join(HERE, 'fake_archives', 'subdir', 'subsubdir', 'Flask-0.9.tar.gz') def get_path(url): t = urlparse(url) return url2pathname(t.path) for name in ('flask', 'Flask'): result = locator.get_project(name) self.assertEqual(result, {'urls': {}, 'digests': {}}) names = locator.get_distribution_names() expected = set(['coverage']) self.assertEqual(names, expected) def test_path(self): fakes = os.path.join(HERE, 'fake_dists') sys.path.insert(0, fakes) try: edp = DistributionPath(include_egg=True) locator = DistPathLocator(edp) cases = ('babar', 'choxie', 'strawberry', 'towel-stuff', 'coconuts-aster', 'bacon', 'grammar', 'truffles', 'banana', 'cheese') for name in cases: d = locator.locate(name, True) self.assertIsNotNone(d) r = locator.get_project(name) expected = { d.version: d, 'urls': {d.version: set([d.source_url])}, 'digests': {d.version: set([None])} } self.assertEqual(r, expected) d = locator.locate('nonexistent') self.assertIsNone(d) r = locator.get_project('nonexistent') self.assertTrue(len(r) == 2) finally: sys.path.pop(0) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_aggregation(self): d = os.path.join(HERE, 'fake_archives') loc1 = DirectoryLocator(d) loc2 = SimpleScrapingLocator('https://pypi.python.org/simple/', timeout=5.0) locator = AggregatingLocator(loc1, loc2) exp1 = os.path.join(HERE, 'fake_archives', 'subdir', 'subsubdir', 'Flask-0.9.tar.gz') exp2 = 'https://pypi.python.org/packages/source/F/Flask/Flask-0.9.tar.gz' result = locator.get_project('flask') self.assertEqual(len(result), 3) self.assertIn('0.9', result) dist = result['0.9'] self.assertEqual(dist.name, 'Flask') self.assertEqual(dist.version, '0.9') scheme, _, path, _, _, _ = urlparse(dist.source_url) self.assertEqual(scheme, 'file') self.assertEqual(os.path.normcase(url2pathname(path)), os.path.normcase(exp1)) locator.merge = True locator._cache.clear() result = locator.get_project('flask') self.assertGreater(len(result), 3) self.assertIn('0.9', result) dist = result['0.9'] self.assertEqual(dist.name, 'Flask') self.assertEqual(dist.version, '0.9') self.assertEqual(dist.source_url, exp2) return # The following code is slow because it has # to get all the dist names by scraping :-( n1 = loc1.get_distribution_names() n2 = loc2.get_distribution_names() self.assertEqual(locator.get_distribution_names(), n1 | n2) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_dependency_finder(self): locator = AggregatingLocator( JSONLocator(), SimpleScrapingLocator('https://pypi.python.org/simple/', timeout=3.0), scheme='legacy') finder = DependencyFinder(locator) dists, problems = finder.find('irc (== 5.0.1)') self.assertFalse(problems) actual = sorted([d.name for d in dists]) self.assertEqual(actual, ['hgtools', 'irc', 'pytest-runner', 'setuptools_scm']) dists, problems = finder.find('irc (== 5.0.1)', meta_extras=[':test:']) self.assertFalse(problems) actual = sorted([d.name for d in dists]) self.assertEqual(actual, ['hgtools', 'irc', 'py', 'pytest', 'pytest-runner', 'setuptools_scm']) g = make_graph(dists) slist, cycle = g.topological_sort() self.assertFalse(cycle) names = [d.name for d in slist] expected = set([ ('setuptools_scm', 'hgtools', 'py', 'pytest-runner', 'pytest', 'irc'), ('setuptools_scm', 'hgtools', 'py', 'pytest', 'pytest-runner', 'irc'), ('setuptools_scm', 'py', 'hgtools', 'pytest-runner', 'pytest', 'irc'), ('hgtools', 'setuptools_scm', 'py', 'pytest', 'pytest-runner', 'irc'), ('py', 'hgtools', 'setuptools_scm', 'pytest', 'pytest-runner', 'irc'), ('hgtools', 'setuptools_scm', 'py', 'pytest-runner', 'pytest', 'irc'), ('py', 'hgtools', 'setuptools_scm', 'pytest-runner', 'pytest', 'irc'), ('py', 'setuptools_scm', 'hgtools', 'pytest', 'pytest-runner', 'irc'), ('pytest', 'setuptools_scm', 'hgtools', 'pytest-runner', 'irc'), ('hgtools', 'setuptools_scm', 'pytest', 'pytest-runner', 'irc'), ('py', 'setuptools_scm', 'hgtools', 'pytest-runner', 'pytest', 'irc'), ('py', 'setuptools_scm', 'pytest', 'pytest-runner', 'hgtools', 'irc'), ('py', 'setuptools_scm', 'pytest-runner', 'pytest', 'hgtools', 'irc'), ('py', 'setuptools_scm', 'pytest', 'hgtools', 'pytest-runner', 'irc'), ('setuptools_scm', 'py', 'pytest', 'hgtools', 'pytest-runner', 'irc'), ('setuptools_scm', 'py', 'pytest-runner', 'hgtools', 'pytest', 'irc'), ('py', 'setuptools_scm', 'pytest-runner', 'hgtools', 'pytest', 'irc'), ('setuptools_scm', 'py', 'pytest', 'pytest-runner', 'hgtools', 'irc'), ]) self.assertIn(tuple(names), expected) # Test with extras dists, problems = finder.find('Jinja2 (== 2.6)') self.assertFalse(problems) actual = sorted([d.name_and_version for d in dists]) self.assertEqual(actual, ['Jinja2 (2.6)']) dists, problems = finder.find('Jinja2 [i18n] (== 2.6)') self.assertFalse(problems) actual = sorted([d.name_and_version for d in dists]) self.assertEqual(actual[-2], 'Jinja2 (2.6)') self.assertTrue(actual[-1].startswith('pytz (')) self.assertTrue(actual[0].startswith('Babel (')) actual = [d.build_time_dependency for d in dists] self.assertEqual(actual, [False, False, False]) # Now test with extra in dependency locator.clear_cache() dummy = make_dist('dummy', '0.1') dummy.metadata.run_requires = [{'requires': ['Jinja2 [i18n]']}] dists, problems = finder.find(dummy) self.assertFalse(problems) actual = sorted([d.name_and_version for d in dists]) self.assertTrue(actual[0].startswith('Babel (')) locator.clear_cache() dummy.metadata.run_requires = [{'requires': ['Jinja2']}] dists, problems = finder.find(dummy) self.assertFalse(problems) actual = sorted([d.name_and_version for d in dists]) self.assertTrue(actual[0].startswith('Jinja2 (')) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_get_all_dist_names(self): for url in (None, PYPI_RPC_HOST): try: all_dists = get_all_distribution_names(url) except Exception: # pragma: no cover raise unittest.SkipTest('PyPI XML-RPC not available') self.assertGreater(len(all_dists), 0) def test_url_preference(self): cases = (('http://netloc/path', 'https://netloc/path'), ('http://pypi.python.org/path', 'http://netloc/path'), ('http://netloc/B', 'http://netloc/A')) for url1, url2 in cases: self.assertEqual(default_locator.prefer_url(url1, url2), url1) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_prereleases(self): locator = AggregatingLocator( JSONLocator(), SimpleScrapingLocator('https://pypi.python.org/simple/', timeout=3.0), scheme='legacy') REQT = 'SQLAlchemy (>0.5.8, < 0.6)' finder = DependencyFinder(locator) d = locator.locate(REQT) self.assertIsNone(d) d = locator.locate(REQT, True) self.assertIsNotNone(d) self.assertEqual(d.name_and_version, 'SQLAlchemy (0.6beta3)') dist = make_dist('dummy', '0.1') dist.metadata.run_requires = [{'requires': [REQT]}] dists, problems = finder.find(dist, prereleases=True) self.assertFalse(problems) actual = sorted(dists, key=lambda o: o.name_and_version) self.assertEqual(actual[0].name_and_version, 'SQLAlchemy (0.6beta3)') dists, problems = finder.find(dist) # Test changed since now prereleases as found as a last resort. #self.assertEqual(dists, set([dist])) #self.assertEqual(len(problems), 1) #problem = problems.pop() #self.assertEqual(problem, ('unsatisfied', REQT)) self.assertEqual(dists, set([actual[0], dist])) self.assertFalse(problems) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_dist_reqts(self): r = 'config (<=0.3.5)' dist = default_locator.locate(r) self.assertIsNotNone(dist) self.assertIsNone(dist.extras) self.assertTrue(dist.matches_requirement(r)) self.assertFalse(dist.matches_requirement('config (0.3.6)')) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_dist_reqts_extras(self): r = 'config[doc,test](<=0.3.5)' dist = default_locator.locate(r) self.assertIsNotNone(dist) self.assertTrue(dist.matches_requirement(r)) self.assertEqual(dist.extras, ['doc', 'test']) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_all(self): d = default_locator.get_project('setuptools') self.assertTrue('urls' in d) d = d['urls'] expected = set([ 'setuptools-0.6b1.zip', 'setuptools-0.6b2.zip', 'setuptools-0.6b3.zip', 'setuptools-0.6b4.zip', 'setuptools-0.6c10.tar.gz', 'setuptools-0.6c11.tar.gz', #'setuptools-0.6c12dev-r88997.tar.gz', #'setuptools-0.6c12dev-r88998.tar.gz', #'setuptools-0.6c12dev-r89000.tar.gz', 'setuptools-0.6c1.zip', 'setuptools-0.6c2.zip', 'setuptools-0.6c3.tar.gz', 'setuptools-0.6c4.tar.gz', 'setuptools-0.6c5.tar.gz', 'setuptools-0.6c6.tar.gz', 'setuptools-0.6c7.tar.gz', 'setuptools-0.6c8.tar.gz', 'setuptools-0.6c9.tar.gz', 'setuptools-0.7.2.tar.gz', 'setuptools-0.7.3.tar.gz', 'setuptools-0.7.4.tar.gz', 'setuptools-0.7.5.tar.gz', 'setuptools-0.7.6.tar.gz', 'setuptools-0.7.7.tar.gz', 'setuptools-0.7.8.tar.gz', 'setuptools-0.8.tar.gz', 'setuptools-0.9.1.tar.gz', 'setuptools-0.9.2.tar.gz', 'setuptools-0.9.3.tar.gz', 'setuptools-0.9.4.tar.gz', 'setuptools-0.9.5.tar.gz', 'setuptools-0.9.6.tar.gz', 'setuptools-0.9.7.tar.gz', 'setuptools-0.9.8.tar.gz', 'setuptools-0.9.tar.gz', 'setuptools-1.0.tar.gz', 'setuptools-1.1.1.tar.gz', 'setuptools-1.1.2.tar.gz', 'setuptools-1.1.3.tar.gz', 'setuptools-1.1.4.tar.gz', 'setuptools-1.1.5.tar.gz', 'setuptools-1.1.6.tar.gz', 'setuptools-1.1.7.tar.gz', 'setuptools-1.1.tar.gz', 'setuptools-1.2.tar.gz', 'setuptools-1.3.1.tar.gz', 'setuptools-1.3.2.tar.gz', 'setuptools-1.3.tar.gz', 'setuptools-1.4.1.tar.gz', 'setuptools-1.4.2.tar.gz', 'setuptools-1.4.tar.gz', 'setuptools-2.0.1.tar.gz', 'setuptools-2.0.2.tar.gz', 'setuptools-2.0.tar.gz', 'setuptools-2.1.1.tar.gz', 'setuptools-2.1.2.tar.gz', 'setuptools-2.1.tar.gz', 'setuptools-2.2.tar.gz', 'setuptools-3.0.1.tar.gz', 'setuptools-3.0.1.zip', 'setuptools-3.0.2.tar.gz', 'setuptools-3.0.2.zip', 'setuptools-3.0.tar.gz', 'setuptools-3.0.zip', 'setuptools-3.1.tar.gz', 'setuptools-3.1.zip', 'setuptools-3.2.tar.gz', 'setuptools-3.2.zip', 'setuptools-3.3.tar.gz', 'setuptools-3.3.zip', 'setuptools-3.4.1.tar.gz', 'setuptools-3.4.1.zip', 'setuptools-3.4.2.tar.gz', 'setuptools-3.4.2.zip', 'setuptools-3.4.3.tar.gz', 'setuptools-3.4.3.zip', 'setuptools-3.4.4.tar.gz', 'setuptools-3.4.4.zip', 'setuptools-3.4.tar.gz', 'setuptools-3.4.zip', 'setuptools-3.5.1.tar.gz', 'setuptools-3.5.1.zip', 'setuptools-3.5.2.tar.gz', 'setuptools-3.5.2.zip', 'setuptools-3.5.tar.gz', 'setuptools-3.5.zip', 'setuptools-3.6.tar.gz', 'setuptools-3.6.zip', 'setuptools-3.7.1.tar.gz', 'setuptools-3.7.1.zip', 'setuptools-3.7.tar.gz', 'setuptools-3.7.zip', 'setuptools-3.8.1.tar.gz', 'setuptools-3.8.1.zip', 'setuptools-3.8.tar.gz', 'setuptools-3.8.zip', 'setuptools-4.0.1.tar.gz', 'setuptools-4.0.1.zip', 'setuptools-4.0.tar.gz', 'setuptools-4.0.zip', 'setuptools-5.0.1.tar.gz', 'setuptools-5.0.1.zip', 'setuptools-5.0.2.tar.gz', 'setuptools-5.0.2.zip', 'setuptools-5.0.tar.gz', 'setuptools-5.0.zip', 'setuptools-5.1.tar.gz', 'setuptools-5.1.zip', 'setuptools-5.2.tar.gz', 'setuptools-5.2.zip', 'setuptools-5.3.tar.gz', 'setuptools-5.3.zip', 'setuptools-5.4.1.tar.gz', 'setuptools-5.4.1.zip', 'setuptools-5.4.2.tar.gz', 'setuptools-5.4.2.zip', 'setuptools-5.4.tar.gz', 'setuptools-5.4.zip', 'setuptools-5.5.1.tar.gz', 'setuptools-5.5.1.zip', 'setuptools-5.5.tar.gz', 'setuptools-5.5.zip', 'setuptools-5.6.tar.gz', 'setuptools-5.6.zip', 'setuptools-5.7.tar.gz', 'setuptools-5.7.zip', 'setuptools-5.8.tar.gz', 'setuptools-5.8.zip', 'setuptools-6.0.1.tar.gz', 'setuptools-6.0.1.zip', 'setuptools-6.0.2.tar.gz', 'setuptools-6.0.2.zip', # 'setuptools-6.0.tar.gz', 'setuptools-6.0.zip', ]) actual = set() for k, v in d.items(): for url in v: _, _, path, _, _, _ = urlparse(url) filename = path.rsplit('/', 1)[-1] actual.add(filename) self.assertEqual(actual & expected, expected) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_nonexistent(self): # See Issue #58 d = locate('foobarbazbishboshboo') self.assertTrue(d is None or isinstance(d, Distribution)) if __name__ == '__main__': # pragma: no cover import logging logging.basicConfig(level=logging.DEBUG, filename='test_locators.log', filemode='w', format='%(message)s') unittest.main() distlib-0.2.2/tests/good.bin0000664000000000000000000000001612103470076014426 0ustar rootrootHello, world! distlib-0.2.2/tests/distlib_tests.py0000664000000000000000000000215712163371552016247 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # import sys _ver = sys.version_info[:2] from test_database import (DataFilesTestCase, TestDatabase, TestDistribution, TestEggInfoDistribution, DepGraphTestCase) from test_index import PackageIndexTestCase from test_locators import LocatorTestCase from test_manifest import ManifestTestCase from test_markers import MarkersTestCase from test_metadata import MetadataTestCase, LegacyMetadataTestCase from test_resources import (ZipResourceTestCase, FileResourceTestCase, CacheTestCase) from test_scripts import ScriptTestCase from test_version import (VersionTestCase, CompatibilityTestCase, LegacyVersionTestCase, SemanticVersionTestCase) from test_wheel import WheelTestCase if _ver == (2, 6): from test_shutil import TestCopyFile, TestMove, TestShutil from test_sysconfig import TestSysConfig, MakefileTests from test_util import (UtilTestCase, ProgressTestCase, FileOpsTestCase, GlobTestCase) distlib-0.2.2/tests/test_sysconfig.py0000664000000000000000000003572312112523276016437 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # from __future__ import print_function from copy import copy import os import sys import subprocess import tempfile from compat import unittest from distlib._backport import shutil from distlib._backport import sysconfig from distlib._backport.sysconfig import ( get_paths, get_platform, get_config_vars, get_path, get_path_names, _SCHEMES, _get_default_scheme, _expand_vars, get_scheme_names, get_config_var, _main) from distlib.compat import StringIO import support class TestSysConfig(unittest.TestCase): def setUp(self): super(TestSysConfig, self).setUp() self.sys_path = sys.path[:] # patching os.uname if hasattr(os, 'uname'): self.uname = os.uname self._uname = os.uname() else: self.uname = None self._uname = None os.uname = self._get_uname # saving the environment self.name = os.name self.platform = sys.platform self.version = sys.version self.sep = os.sep self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive self._config_vars = copy(sysconfig._CONFIG_VARS) self._added_envvars = [] self._changed_envvars = [] for var in ('MACOSX_DEPLOYMENT_TARGET', 'PATH'): if var in os.environ: self._changed_envvars.append((var, os.environ[var])) else: self._added_envvars.append(var) fd, self.TESTFN = tempfile.mkstemp() os.close(fd) os.unlink(self.TESTFN) def tearDown(self): sys.path[:] = self.sys_path self._cleanup_testfn() if self.uname is not None: os.uname = self.uname else: del os.uname os.name = self.name sys.platform = self.platform sys.version = self.version os.sep = self.sep os.path.join = self.join os.path.isabs = self.isabs os.path.splitdrive = self.splitdrive sysconfig._CONFIG_VARS = copy(self._config_vars) for var, value in self._changed_envvars: os.environ[var] = value for var in self._added_envvars: os.environ.pop(var, None) super(TestSysConfig, self).tearDown() def _set_uname(self, uname): self._uname = uname def _get_uname(self): return self._uname def _cleanup_testfn(self): path = self.TESTFN if os.path.isfile(path): os.remove(path) elif os.path.isdir(path): shutil.rmtree(path) def test_get_path_names(self): self.assertEqual(get_path_names(), _SCHEMES.options('posix_prefix')) def test_get_paths(self): scheme = get_paths() default_scheme = _get_default_scheme() wanted = _expand_vars(default_scheme, None) wanted = sorted(wanted.items()) scheme = sorted(scheme.items()) self.assertEqual(scheme, wanted) def test_get_path(self): # XXX make real tests here for scheme in _SCHEMES.sections(): for name, _ in _SCHEMES.items(scheme): res = get_path(name, scheme) def test_get_config_vars(self): cvars = get_config_vars() self.assertIsInstance(cvars, dict) self.assertTrue(cvars) def test_get_platform(self): # get_config_vars() needs to be called before messing with # the variables as we do below. Otherwise, when we call # get_config_vars() below AFTER changing os.name to 'posix', # we'll get a failure because _init_posix() will get called # and look for a Makefile - which will not work on Windows :-( # # With the call to get_config_vars() here while os.name is still # 'nt', we call _init_non_posix(), _CONFIG_VARS is set up OK, # and so _init_posix() never gets called on Windows. get_config_vars() # windows XP, 32bits os.name = 'nt' sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' '[MSC v.1310 32 bit (Intel)]') sys.platform = 'win32' self.assertEqual(get_platform(), 'win32') # windows XP, amd64 os.name = 'nt' sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' '[MSC v.1310 32 bit (Amd64)]') sys.platform = 'win32' self.assertEqual(get_platform(), 'win-amd64') # windows XP, itanium os.name = 'nt' sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' '[MSC v.1310 32 bit (Itanium)]') sys.platform = 'win32' self.assertEqual(get_platform(), 'win-ia64') # macbook os.name = 'posix' sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) ' '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]') sys.platform = 'darwin' self._set_uname(('Darwin', 'macziade', '8.11.1', ('Darwin Kernel Version 8.11.1: ' 'Wed Oct 10 18:23:28 PDT 2007; ' 'root:xnu-792.25.20~1/RELEASE_I386'), 'PowerPC')) get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3' get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' '-fwrapv -O3 -Wall -Wstrict-prototypes') maxint = sys.maxsize try: sys.maxsize = 2147483647 self.assertEqual(get_platform(), 'macosx-10.3-ppc') sys.maxsize = 9223372036854775807 self.assertEqual(get_platform(), 'macosx-10.3-ppc64') finally: sys.maxsize = maxint self._set_uname(('Darwin', 'macziade', '8.11.1', ('Darwin Kernel Version 8.11.1: ' 'Wed Oct 10 18:23:28 PDT 2007; ' 'root:xnu-792.25.20~1/RELEASE_I386'), 'i386')) get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3' get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3' get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' '-fwrapv -O3 -Wall -Wstrict-prototypes') maxint = sys.maxsize try: sys.maxsize = 2147483647 self.assertEqual(get_platform(), 'macosx-10.3-i386') sys.maxsize = 9223372036854775807 self.assertEqual(get_platform(), 'macosx-10.3-x86_64') finally: sys.maxsize = maxint # macbook with fat binaries (fat, universal or fat64) get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.4' get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot ' '/Developer/SDKs/MacOSX10.4u.sdk ' '-fno-strict-aliasing -fno-common ' '-dynamic -DNDEBUG -g -O3') self.assertEqual(get_platform(), 'macosx-10.4-fat') get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot ' '/Developer/SDKs/MacOSX10.4u.sdk ' '-fno-strict-aliasing -fno-common ' '-dynamic -DNDEBUG -g -O3') self.assertEqual(get_platform(), 'macosx-10.4-intel') get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc -arch i386 -isysroot ' '/Developer/SDKs/MacOSX10.4u.sdk ' '-fno-strict-aliasing -fno-common ' '-dynamic -DNDEBUG -g -O3') self.assertEqual(get_platform(), 'macosx-10.4-fat3') get_config_vars()['CFLAGS'] = ('-arch ppc64 -arch x86_64 -arch ppc -arch i386 -isysroot ' '/Developer/SDKs/MacOSX10.4u.sdk ' '-fno-strict-aliasing -fno-common ' '-dynamic -DNDEBUG -g -O3') self.assertEqual(get_platform(), 'macosx-10.4-universal') get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc64 -isysroot ' '/Developer/SDKs/MacOSX10.4u.sdk ' '-fno-strict-aliasing -fno-common ' '-dynamic -DNDEBUG -g -O3') self.assertEqual(get_platform(), 'macosx-10.4-fat64') for arch in ('ppc', 'i386', 'x86_64', 'ppc64'): get_config_vars()['CFLAGS'] = ('-arch %s -isysroot ' '/Developer/SDKs/MacOSX10.4u.sdk ' '-fno-strict-aliasing -fno-common ' '-dynamic -DNDEBUG -g -O3' % arch) self.assertEqual(get_platform(), 'macosx-10.4-%s' % arch) # linux debian sarge os.name = 'posix' sys.version = ('2.3.5 (#1, Jul 4 2007, 17:28:59) ' '\n[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)]') sys.platform = 'linux2' self._set_uname(('Linux', 'aglae', '2.6.21.1dedibox-r7', '#1 Mon Apr 30 17:25:38 CEST 2007', 'i686')) self.assertEqual(get_platform(), 'linux-i686') # XXX more platforms to tests here def test_get_config_h_filename(self): config_h = sysconfig.get_config_h_filename() self.assertTrue(os.path.isfile(config_h), config_h) def test_get_scheme_names(self): wanted = ('nt', 'nt_user', 'os2', 'os2_home', 'osx_framework_user', 'posix_home', 'posix_prefix', 'posix_user') self.assertEqual(get_scheme_names(), wanted) @support.skip_unless_symlink def test_symlink(self): # On Windows, the EXE needs to know where pythonXY.dll is at so we have # to add the directory to the path. if sys.platform == 'win32': os.environ['PATH'] = ';'.join(( os.path.dirname(sys.executable), os.environ['PATH'])) # Issue 7880 def get(python): cmd = [python, '-c', 'from distlib._backport import sysconfig; ' 'print(sysconfig.get_platform())'] env = dict(os.environ) env['PYTHONPATH'] = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env) out, err = p.communicate() if out is not None: out = out.decode('utf-8') if err is not None: err = err.decode('utf-8') return out, err real = os.path.realpath(sys.executable) link = os.path.abspath(self.TESTFN) os.symlink(real, link) try: self.assertEqual(get(real), get(link)) finally: os.unlink(link) def test_user_similar(self): # Issue #8759: make sure the posix scheme for the users # is similar to the global posix_prefix one base = get_config_var('base') user = get_config_var('userbase') # the global scheme mirrors the distinction between prefix and # exec-prefix but not the user scheme, so we have to adapt the paths # before comparing (issue #9100) adapt = sys.prefix != sys.exec_prefix for name in ('stdlib', 'platstdlib', 'purelib', 'platlib'): global_path = get_path(name, 'posix_prefix') if adapt: global_path = global_path.replace(sys.exec_prefix, sys.prefix) base = base.replace(sys.exec_prefix, sys.prefix) user_path = get_path(name, 'posix_user') self.assertEqual(user_path, global_path.replace(base, user, 1)) def test_main(self): # just making sure _main() runs and returns things in the stdout self.addCleanup(setattr, sys, 'stdout', sys.stdout) sys.stdout = StringIO() _main() self.assertGreater(len(sys.stdout.getvalue().split('\n')), 0) @unittest.skipIf(sys.version_info[:2] == (2, 6), 'not reliable on 2.6') @unittest.skipIf(sys.platform == 'win32', 'does not apply to Windows') def test_ldshared_value(self): ldflags = sysconfig.get_config_var('LDFLAGS') ldshared = sysconfig.get_config_var('LDSHARED') self.assertIn(ldflags.strip(), ldshared.strip()) @unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX") def test_platform_in_subprocess(self): my_platform = sysconfig.get_platform() # Test without MACOSX_DEPLOYMENT_TARGET in the environment env = os.environ.copy() if 'MACOSX_DEPLOYMENT_TARGET' in env: del env['MACOSX_DEPLOYMENT_TARGET'] with open('/dev/null', 'w') as devnull_fp: p = subprocess.Popen([ sys.executable, '-c', 'from distlib._backport import sysconfig; ' 'print(sysconfig.get_platform())', ], stdout=subprocess.PIPE, stderr=devnull_fp, env=env) test_platform = p.communicate()[0].strip() test_platform = test_platform.decode('utf-8') status = p.wait() self.assertEqual(status, 0) self.assertEqual(my_platform, test_platform) # Test with MACOSX_DEPLOYMENT_TARGET in the environment, and # using a value that is unlikely to be the default one. env = os.environ.copy() env['MACOSX_DEPLOYMENT_TARGET'] = '10.1' with open('/dev/null') as dev_null: p = subprocess.Popen([ sys.executable, '-c', 'from distlib._backport import sysconfig; ' 'print(sysconfig.get_platform())', ], stdout=subprocess.PIPE, stderr=dev_null, env=env) test_platform = p.communicate()[0].strip() test_platform = test_platform.decode('utf-8') status = p.wait() self.assertEqual(status, 0) self.assertEqual(my_platform, test_platform) class MakefileTests(unittest.TestCase): def setUp(self): fd, self.TESTFN = tempfile.mkstemp() os.close(fd) def tearDown(self): os.unlink(self.TESTFN) @unittest.skipIf(sys.platform.startswith('win'), 'Test is not Windows compatible') def test_get_makefile_filename(self): makefile = sysconfig.get_makefile_filename() self.assertTrue(os.path.isfile(makefile), makefile) def test_parse_makefile(self): TESTFN = self.TESTFN with open(TESTFN, "w") as makefile: print("var1=a$(VAR2)", file=makefile) print("VAR2=b$(var3)", file=makefile) print("var3=42", file=makefile) print("var4=$/invalid", file=makefile) print("var5=dollar$$5", file=makefile) vars = sysconfig._parse_makefile(TESTFN) self.assertEqual(vars, { 'var1': 'ab42', 'VAR2': 'b42', 'var3': 42, 'var4': '$/invalid', 'var5': 'dollar$5', }) distlib-0.2.2/tests/dummy-0.1-py27-none-any.whl0000664000000000000000000000423512445642006017502 0ustar rootrootPKD*dummy-0.1.data/scripts/dummy.pySV,,SuJ+U(((+Q-/*RR K2Ksr4Kt R4NC]WY.2Rׄ(7@ 桺?/HP<@=%PKD_rdummy.pyK+U(((+Q-/*RR K2Ksr4Kt R4NC]WY.2Rׄ(7@ 桺?/HP<@=%PKD_rhooks.pyK+U(((+Q-/*RR K2Ksr4Kt R4NC]WY.2Rׄ(7@ 桺?/HP<@=%PKD ]rdummy-0.1.dist-info/METADATAM-ILI,I K-*ϳR03KMRH)ͭK%BEV Y⒢̤.̂bҜT +A PKD·Zdummy-0.1.dist-info/pydist.jsonTn0+<@nŀqnAPF&‡@RN%z̬ޝЕV4^62U+C*e 2Qq?!4Jq]] dh=',tM'~c_ 9+%wN nx'Q=<n+#)G\+/Ԙ0F:e%;hِ#wCA}A5N'_EX yu-?bGeݾo8OIu5GߪVm͐3ѓ0=*u ۛ!TC9ޟ ~rO͞gtE9'1yԭ"?l' }@U8 -ߺl>DZS".CpSGbowV&'sԋl3,|PKD*dummy-0.1.data/scripts/dummy.pyPKD_rdummy.pyPKD_rThooks.pyPKD ]rdummy-0.1.dist-info/METADATAPKD·Zdummy-0.1.dist-info/pydist.jsonPKD_WYdummy-0.1.dist-info/WHEELPKDr82>dummy-0.1.dist-info/RECORDPKdistlib-0.2.2/tests/testsrc/0000775000000000000000000000000012656456062014512 5ustar rootrootdistlib-0.2.2/tests/testsrc/subdir/0000775000000000000000000000000012656456062016002 5ustar rootrootdistlib-0.2.2/tests/testsrc/subdir/somedata.txt0000664000000000000000000000000012106251170020305 0ustar rootrootdistlib-0.2.2/tests/testsrc/subdir/subsubdir/0000775000000000000000000000000012656456062020004 5ustar rootrootdistlib-0.2.2/tests/testsrc/subdir/subsubdir/somedata.bin0000664000000000000000000000000012106231222022234 0ustar rootrootdistlib-0.2.2/tests/testsrc/subdir/lose/0000775000000000000000000000000012656456062016744 5ustar rootrootdistlib-0.2.2/tests/testsrc/subdir/lose/lose.txt0000664000000000000000000000004312106231514020423 0ustar rootrootThis should be removed by a prune. distlib-0.2.2/tests/testsrc/keep/0000775000000000000000000000000012656456062015436 5ustar rootrootdistlib-0.2.2/tests/testsrc/keep/keep.txt0000664000000000000000000000004112106231424017075 0ustar rootrootThis should be added by a graft. distlib-0.2.2/tests/testsrc/LICENSE0000664000000000000000000000001612106257046015503 0ustar rootrootBSD-licensed. distlib-0.2.2/tests/testsrc/.hidden0000664000000000000000000000004012106231162015716 0ustar rootrootThis is an example hidden file. distlib-0.2.2/tests/testsrc/README.txt0000664000000000000000000000005412106231074016167 0ustar rootrootThis is a test directory for test_manifest. distlib-0.2.2/tests/included.json0000664000000000000000000000004312137475420015473 0ustar rootroot{ "foo": "bar", "bar": "baz" } distlib-0.2.2/tests/test_metadata.py0000664000000000000000000006273512641245344016222 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # """Tests for distlib.metadata.""" from __future__ import unicode_literals import codecs import json import os import sys import codecs from textwrap import dedent from compat import unittest from distlib import __version__ from distlib.compat import StringIO from distlib.metadata import (LegacyMetadata, Metadata, METADATA_FILENAME, PKG_INFO_PREFERRED_VERSION, MetadataConflictError, MetadataMissingError, MetadataUnrecognizedVersionError, MetadataInvalidError, _ATTR2FIELD) from support import (LoggingCatcher, TempdirManager) HERE = os.path.abspath(os.path.dirname(__file__)) class LegacyMetadataTestCase(LoggingCatcher, TempdirManager, unittest.TestCase): maxDiff = None restore_environ = ['HOME'] def setUp(self): super(LegacyMetadataTestCase, self).setUp() self.argv = sys.argv, sys.argv[:] def tearDown(self): sys.argv = self.argv[0] sys.argv[:] = self.argv[1] super(LegacyMetadataTestCase, self).tearDown() #### Test various methods of the LegacyMetadata class def get_file_contents(self, name): name = os.path.join(HERE, name) f = codecs.open(name, 'r', encoding='utf-8') try: contents = f.read() % sys.platform finally: f.close() return contents def test_instantiation(self): PKG_INFO = os.path.join(HERE, 'PKG-INFO') f = codecs.open(PKG_INFO, 'r', encoding='utf-8') try: contents = f.read() finally: f.close() fp = StringIO(contents) m = LegacyMetadata() self.assertRaises(MetadataUnrecognizedVersionError, m.items) m = LegacyMetadata(PKG_INFO) self.assertEqual(len(m.items()), 22) m = LegacyMetadata(fileobj=fp) self.assertEqual(len(m.items()), 22) m = LegacyMetadata(mapping=dict(name='Test', version='1.0')) self.assertEqual(len(m.items()), 17) d = dict(m.items()) self.assertRaises(TypeError, LegacyMetadata, PKG_INFO, fileobj=fp) self.assertRaises(TypeError, LegacyMetadata, PKG_INFO, mapping=d) self.assertRaises(TypeError, LegacyMetadata, fileobj=fp, mapping=d) self.assertRaises(TypeError, LegacyMetadata, PKG_INFO, mapping=m, fileobj=fp) def test_mapping_api(self): content = self.get_file_contents('PKG-INFO') metadata = LegacyMetadata(fileobj=StringIO(content)) self.assertIn('Version', metadata.keys()) self.assertIn('0.5', metadata.values()) self.assertIn(('Version', '0.5'), metadata.items()) metadata.update({'version': '0.6'}) self.assertEqual(metadata['Version'], '0.6') metadata.update([('version', '0.7')]) self.assertEqual(metadata['Version'], '0.7') # use a kwarg to update metadata.update(version='0.6') self.assertEqual(metadata['Version'], '0.6') # make sure update method checks values like the set method does metadata.update({'version': '1--2'}) self.assertEqual(len(self.get_logs()), 1) self.assertEqual(list(metadata), metadata.keys()) def test_attribute_access(self): content = self.get_file_contents('PKG-INFO') metadata = LegacyMetadata(fileobj=StringIO(content)) for attr in _ATTR2FIELD: self.assertEqual(getattr(metadata, attr), metadata[attr]) def test_read_metadata(self): fields = {'name': 'project', 'version': '1.0', 'description': 'desc', 'summary': 'xxx', 'download_url': 'http://example.com', 'keywords': ['one', 'two'], 'requires_dist': ['foo']} metadata = LegacyMetadata(mapping=fields) PKG_INFO = StringIO() metadata.write_file(PKG_INFO) PKG_INFO.seek(0) metadata = LegacyMetadata(fileobj=PKG_INFO) self.assertEqual(metadata['name'], 'project') self.assertEqual(metadata['version'], '1.0') self.assertEqual(metadata['summary'], 'xxx') self.assertEqual(metadata['download_url'], 'http://example.com') self.assertEqual(metadata['keywords'], ['one', 'two']) self.assertEqual(metadata['platform'], []) self.assertEqual(metadata['obsoletes'], []) self.assertEqual(metadata['requires-dist'], ['foo']) def test_write_metadata(self): # check support of non-ASCII values tmp_dir = self.mkdtemp() my_file = os.path.join(tmp_dir, 'f') metadata = LegacyMetadata(mapping={'author': 'Mister Café', 'name': 'my.project', 'author': 'Café Junior', 'summary': 'Café torréfié', 'description': 'Héhéhé', 'keywords': ['café', 'coffee'] }) metadata.write(my_file) # the file should use UTF-8 metadata2 = LegacyMetadata() fp = codecs.open(my_file, encoding='utf-8') try: metadata2.read_file(fp) finally: fp.close() # XXX when keywords are not defined, metadata will have # 'Keywords': [] but metadata2 will have 'Keywords': [''] # because of a value.split(',') in LegacyMetadata.get self.assertEqual(metadata.items(), metadata2.items()) # ASCII also works, it's a subset of UTF-8 metadata = LegacyMetadata(mapping={'author': 'Mister Cafe', 'name': 'my.project', 'author': 'Cafe Junior', 'summary': 'Cafe torrefie', 'description': 'Hehehe' }) metadata.write(my_file) metadata2 = LegacyMetadata() fp = codecs.open(my_file, encoding='utf-8') try: metadata2.read_file(fp) finally: fp.close() def test_metadata_read_write(self): PKG_INFO = os.path.join(HERE, 'PKG-INFO') metadata = LegacyMetadata(PKG_INFO) out = StringIO() metadata.write_file(out) out.seek(0) res = LegacyMetadata() res.read_file(out) self.assertEqual(metadata.values(), res.values()) #### Test checks def test_check_version(self): metadata = LegacyMetadata() metadata['Name'] = 'vimpdb' metadata['Home-page'] = 'http://pypi.python.org' metadata['Author'] = 'Monty Python' missing, warnings = metadata.check() self.assertEqual(missing, ['Version']) def test_check_version_strict(self): metadata = LegacyMetadata() metadata['Name'] = 'vimpdb' metadata['Home-page'] = 'http://pypi.python.org' metadata['Author'] = 'Monty Python' self.assertRaises(MetadataMissingError, metadata.check, strict=True) def test_check_name(self): metadata = LegacyMetadata() metadata['Version'] = '1.0' metadata['Home-page'] = 'http://pypi.python.org' metadata['Author'] = 'Monty Python' missing, warnings = metadata.check() self.assertEqual(missing, ['Name']) def test_check_name_strict(self): metadata = LegacyMetadata() metadata['Version'] = '1.0' metadata['Home-page'] = 'http://pypi.python.org' metadata['Author'] = 'Monty Python' self.assertRaises(MetadataMissingError, metadata.check, strict=True) def test_check_author(self): metadata = LegacyMetadata() metadata['Version'] = '1.0' metadata['Name'] = 'vimpdb' metadata['Home-page'] = 'http://pypi.python.org' missing, warnings = metadata.check() self.assertEqual(missing, ['Author']) def test_check_homepage(self): metadata = LegacyMetadata() metadata['Version'] = '1.0' metadata['Name'] = 'vimpdb' metadata['Author'] = 'Monty Python' missing, warnings = metadata.check() self.assertEqual(missing, ['Home-page']) def test_check_matchers(self): metadata = LegacyMetadata() metadata['Version'] = 'rr' metadata['Name'] = 'vimpdb' metadata['Home-page'] = 'http://pypi.python.org' metadata['Author'] = 'Monty Python' metadata['Requires-dist'] = ['Foo (a)'] metadata['Obsoletes-dist'] = ['Foo (a)'] metadata['Provides-dist'] = ['Foo (a)'] missing, warnings = metadata.check() self.assertEqual(len(warnings), 4) #### Test fields and metadata versions def test_metadata_versions(self): metadata = LegacyMetadata(mapping={'name': 'project', 'version': '1.0'}) self.assertEqual(metadata['Metadata-Version'], PKG_INFO_PREFERRED_VERSION) self.assertNotIn('Provides', metadata) self.assertNotIn('Requires', metadata) self.assertNotIn('Obsoletes', metadata) metadata['Classifier'] = ['ok'] metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.1') metadata = LegacyMetadata() metadata['Download-URL'] = 'ok' metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.1') metadata = LegacyMetadata() metadata['Obsoletes'] = 'ok' metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.1') del metadata['Obsoletes'] metadata['Obsoletes-Dist'] = 'ok' metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.2') metadata.set('Obsoletes', 'ok') self.assertRaises(MetadataConflictError, metadata.set_metadata_version) del metadata['Obsoletes'] del metadata['Obsoletes-Dist'] metadata.set_metadata_version() metadata['Version'] = '1' self.assertEqual(metadata['Metadata-Version'], '1.1') # make sure the _best_version function works okay with # non-conflicting fields from 1.1 and 1.2 (i.e. we want only the # requires/requires-dist and co. pairs to cause a conflict, not all # fields in _314_MARKERS) metadata = LegacyMetadata() metadata['Requires-Python'] = '3' metadata['Classifier'] = ['Programming language :: Python :: 3'] metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.2') PKG_INFO = os.path.join(HERE, 'SETUPTOOLS-PKG-INFO') metadata = LegacyMetadata(PKG_INFO) self.assertEqual(metadata['Metadata-Version'], '1.1') PKG_INFO = os.path.join(HERE, 'SETUPTOOLS-PKG-INFO2') metadata = LegacyMetadata(PKG_INFO) self.assertEqual(metadata['Metadata-Version'], '1.1') # make sure an empty list for Obsoletes and Requires-dist gets ignored metadata['Obsoletes'] = [] metadata['Requires-dist'] = [] metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.1') # Update the _fields dict directly to prevent 'Metadata-Version' # from being updated by the _set_best_version() method. metadata._fields['Metadata-Version'] = '1.618' self.assertRaises(MetadataUnrecognizedVersionError, metadata.keys) def test_version(self): LegacyMetadata(mapping={'author': 'xxx', 'name': 'xxx', 'version': 'xxx', 'home_page': 'xxxx' }) logs = self.get_logs() self.assertEqual(1, len(logs)) self.assertIn('not a valid version', logs[0]) def test_description(self): content = self.get_file_contents('PKG-INFO') metadata = LegacyMetadata() metadata.read_file(StringIO(content)) # see if we can read the description now DESC = os.path.join(HERE, 'LONG_DESC.txt') f = open(DESC) try: wanted = f.read() finally: f.close() self.assertEqual(wanted, metadata['Description']) # save the file somewhere and make sure we can read it back out = StringIO() metadata.write_file(out) out.seek(0) out.seek(0) metadata = LegacyMetadata() metadata.read_file(out) self.assertEqual(wanted, metadata['Description']) def test_description_folding(self): # make sure the indentation is preserved out = StringIO() desc = dedent("""\ example:: We start here and continue here and end here. """) metadata = LegacyMetadata() metadata['description'] = desc metadata.write_file(out) # folded_desc = desc.replace('\n', '\n' + (7 * ' ') + '|') folded_desc = desc.replace('\n', '\n' + (8 * ' ')) self.assertIn(folded_desc, out.getvalue()) def test_project_url(self): metadata = LegacyMetadata() metadata['Project-URL'] = [('one', 'http://ok')] self.assertEqual(metadata['Project-URL'], [('one', 'http://ok')]) metadata.set_metadata_version() self.assertEqual(metadata['Metadata-Version'], '1.2') # make sure this particular field is handled properly when written fp = StringIO() metadata.write_file(fp) self.assertIn('Project-URL: one,http://ok', fp.getvalue().split('\n')) fp.seek(0) metadata = LegacyMetadata() metadata.read_file(fp) self.assertEqual(metadata['Project-Url'], [('one', 'http://ok')]) # TODO copy tests for v1.1 requires, obsoletes and provides from distutils # (they're useless but we support them so we should test them anyway) def test_provides_dist(self): fields = {'name': 'project', 'version': '1.0', 'provides_dist': ['project', 'my.project']} metadata = LegacyMetadata(mapping=fields) self.assertEqual(metadata['Provides-Dist'], ['project', 'my.project']) self.assertEqual(metadata['Metadata-Version'], '1.2', metadata) self.assertNotIn('Requires', metadata) self.assertNotIn('Obsoletes', metadata) def test_requires_dist(self): fields = {'name': 'project', 'version': '1.0', 'requires_dist': ['other', 'another (==1.0)']} metadata = LegacyMetadata(mapping=fields) self.assertEqual(metadata['Requires-Dist'], ['other', 'another (==1.0)']) self.assertEqual(metadata['Metadata-Version'], '1.2') self.assertNotIn('Provides', metadata) self.assertEqual(metadata['Requires-Dist'], ['other', 'another (==1.0)']) self.assertNotIn('Obsoletes', metadata) # make sure write_file uses one RFC 822 header per item fp = StringIO() metadata.write_file(fp) lines = fp.getvalue().split('\n') self.assertIn('Requires-Dist: other', lines) self.assertIn('Requires-Dist: another (==1.0)', lines) # test warnings for invalid version constraints # XXX this would cause no warnings if we used update (or the mapping # argument of the constructor), see comment in LegacyMetadata.update metadata = LegacyMetadata() metadata['Requires-Dist'] = 'Funky (Groovie)' metadata['Requires-Python'] = '1a-4' self.assertEqual(len(self.get_logs()), 2) # test multiple version matches metadata = LegacyMetadata() # XXX check PEP and see if 3 == 3.0 metadata['Requires-Python'] = '>=2.6, <3.0' metadata['Requires-Dist'] = ['Foo (>=2.6, <3.0)'] self.assertEqual(self.get_logs(), []) def test_obsoletes_dist(self): fields = {'name': 'project', 'version': '1.0', 'obsoletes_dist': ['other', 'another (<1.0)']} metadata = LegacyMetadata(mapping=fields) self.assertEqual(metadata['Obsoletes-Dist'], ['other', 'another (<1.0)']) self.assertEqual(metadata['Metadata-Version'], '1.2') self.assertNotIn('Provides', metadata) self.assertNotIn('Requires', metadata) self.assertEqual(metadata['Obsoletes-Dist'], ['other', 'another (<1.0)']) def test_fullname(self): md = LegacyMetadata() md['Name'] = 'a b c' md['Version'] = '1 0 0' s = md.get_fullname() self.assertEqual(s, 'a b c-1 0 0') s = md.get_fullname(True) self.assertEqual(s, 'a-b-c-1.0.0') def test_fields(self): md = LegacyMetadata() self.assertTrue(md.is_multi_field('Requires-Dist')) self.assertFalse(md.is_multi_field('Name')) self.assertTrue(md.is_field('Obsoleted-By')) self.assertFalse(md.is_field('Frobozz')) class MetadataTestCase(LoggingCatcher, TempdirManager, unittest.TestCase): def test_init(self): "Test initialisation" md = Metadata() self.assertIsNone(md._legacy) self.assertRaises(MetadataMissingError, md.validate) md.name = 'dummy' self.assertRaises(MetadataMissingError, md.validate) md.version = '0.1' self.assertRaises(MetadataMissingError, md.validate) md.summary = 'Summary' md.validate() self.assertEqual(md.name, 'dummy') self.assertEqual(md.version, '0.1') # Initialise from mapping md = Metadata(mapping={ 'metadata_version': '2.0', 'name': 'foo', 'version': '0.3.4', 'summary': 'Summary', }) md.validate() self.assertEqual(md.name, 'foo') self.assertEqual(md.version, '0.3.4') self.assertEqual(md.run_requires, []) self.assertEqual(md.meta_requires, []) self.assertEqual(md.provides, ['foo (0.3.4)']) # Initialise from legacy metadata fn = os.path.join(HERE, 'fake_dists', 'choxie-2.0.0.9.dist-info', 'METADATA') md = Metadata(path=fn) md.validate() self.assertIsNotNone(md._legacy) self.assertEqual(set(md.run_requires), set(['towel-stuff (0.1)', 'nut'])) self.assertEqual(md.metadata_version, '1.2') self.assertEqual(md.version, '2.0.0.9') self.assertEqual(md.meta_requires, []) self.assertEqual(set(md.provides), set(['choxie (2.0.0.9)', 'truffles (1.0)'])) # Initialise from new metadata fn = os.path.join(HERE, METADATA_FILENAME) md = Metadata(path=fn) md.validate() self.assertIsNone(md._legacy) self.assertEqual(md.metadata_version, '2.0') self.assertEqual(md.name, 'foobar') self.assertEqual(md.version, '0.1') self.assertEqual(md.provides, ['foobar (0.1)']) def test_add_requirements(self): md = Metadata() md.name = 'bar' md.version = '0.5' md.add_requirements(['foo (0.1.2)']) self.assertEqual(md.run_requires, [{ 'requires': ['foo (0.1.2)']}]) fn = os.path.join(HERE, 'fake_dists', 'choxie-2.0.0.9.dist-info', 'METADATA') md = Metadata(path=fn) md.add_requirements(['foo (0.1.2)']) self.assertEqual(set(md.run_requires), set(['towel-stuff (0.1)', 'nut', 'foo (0.1.2)'])) def test_requirements(self): fn = os.path.join(HERE, METADATA_FILENAME) md = Metadata(path=fn) self.assertEqual(md.meta_requires, [{'requires': ['bar (1.0)']}]) r = md.get_requirements(md.run_requires) self.assertEqual(r, ['foo']) r = md.get_requirements(md.run_requires, extras=['certs']) self.assertEqual(r, ['foo', 'certifi (0.0.8)']) r = md.get_requirements(md.run_requires, extras=['certs', 'ssl']) if sys.platform != 'win32': self.assertEqual(r, ['foo', 'certifi (0.0.8)']) else: self.assertEqual(set(r), set(['foo', 'certifi (0.0.8)', 'wincertstore (0.1)'])) for ver in ('2.5', '2.4'): env = {'python_version': ver} r = md.get_requirements(md.run_requires, extras=['certs', 'ssl'], env=env) if sys.platform != 'win32': self.assertEqual(set(r), set(['foo', 'certifi (0.0.8)', 'ssl (1.16)'])) elif ver == '2.4': self.assertEqual(set(r), set(['certifi (0.0.8)', 'ssl (1.16)', 'wincertstore (0.1)', 'foo', 'ctypes (1.0.2)'])) else: self.assertEqual(set(r), set(['certifi (0.0.8)', 'ssl (1.16)', 'wincertstore (0.1)', 'foo'])) env['sys_platform'] = 'win32' r = md.get_requirements(md.run_requires, extras=['certs', 'ssl'], env=env) self.assertEqual(set(r), set(['foo', 'certifi (0.0.8)', 'ssl (1.16)', 'ctypes (1.0.2)', 'wincertstore (0.1)'])) env['python_version'] = '2.5' r = md.get_requirements(md.run_requires, extras=['certs', 'ssl'], env=env) self.assertEqual(set(r), set(['foo', 'certifi (0.0.8)', 'ssl (1.16)', 'wincertstore (0.1)'])) r = md.get_requirements(md.run_requires, extras=[':test:']) self.assertEqual(r, ['foo', 'nose']) r = md.get_requirements(md.run_requires, extras=[':test:', 'udp']) self.assertEqual(set(r), set(['foo', 'nose', 'nose-udp'])) self.assertEqual(md.dependencies, { 'provides': ['foobar (0.1)'], 'meta_requires': [ { 'requires': ['bar (1.0)'] } ], 'extras': ['ssl', 'certs'], 'build_requires': [], 'test_requires': [ { 'requires': ['nose'], }, { 'requires': ['nose-udp'], 'extra': 'udp', } ], 'run_requires': [ { 'requires': ['foo'] }, { 'requires': ['certifi (0.0.8)'], 'extra': 'certs', }, { 'requires': ['wincertstore (0.1)'], 'extra': 'ssl', 'environment': "sys_platform=='win32'", }, { 'requires': ['ctypes (1.0.2)'], 'extra': 'ssl', 'environment': "sys_platform=='win32' and " "python_version=='2.4'", }, { 'requires': ['ssl (1.16)'], 'extra': 'ssl', 'environment': "python_version in '2.4, 2.5'", } ] }) def test_write(self): dfn = self.temp_filename() # Read legacy, write new sfn = os.path.join(HERE, 'fake_dists', 'choxie-2.0.0.9.dist-info', 'METADATA') md = Metadata(path=sfn) md.write(path=dfn) with codecs.open(dfn, 'r', 'utf-8') as f: data = json.load(f) self.assertEqual(data, { 'metadata_version': '2.0', 'generator': 'distlib (%s)' % __version__, 'name': 'choxie', 'version': '2.0.0.9', 'license': 'BSD', 'summary': 'Chocolate with a kick!', 'description': 'Chocolate with a longer kick!', 'provides': ['truffles (1.0)', 'choxie (2.0.0.9)'], 'run_requires': [{'requires': ['towel-stuff (0.1)', 'nut']}], 'keywords': [], }) # Write legacy, compare with original md.write(path=dfn, legacy=True) nmd = Metadata(path=dfn) d1 = md.todict() d2 = nmd.todict() self.assertEqual(d1, d2) def test_valid(self): """ Tests to check that missing and invalid metadata is caught. """ md = Metadata() self.assertRaises(MetadataMissingError, md.validate) try: md.name = 'Foo Bar' except MetadataInvalidError: pass md.name = 'foo_bar' # Name now OK, but version and summary to be checked self.assertRaises(MetadataMissingError, md.validate) try: md.version = '1.0a' except MetadataInvalidError: pass md.version = '1.0' # Name and version now OK, but summary to be checked self.assertRaises(MetadataMissingError, md.validate) try: md.summary = '' except MetadataInvalidError: pass try: md.summary = ' ' * 2048 except MetadataInvalidError: pass md.summary = ' ' * 2047 md.validate() md.summary = ' ' md.validate() if __name__ == '__main__': # pragma: no cover unittest.main() distlib-0.2.2/tests/minimext-0.1-cp27-none-linux_x86_64.whl0000664000000000000000000001746712137475420021556 0ustar rootrootPKeB&{C minimext.so|Ϙ_1`;.5U5~Y8}9souWyҕ4Jd!AhzHM5!<s8N$寗%$?UG>󴝚ԫy4$$jKWTVȿ%N$޶BmJAm/D>L+ijq !W',jrsw>F/FAR_G+*(ղ⥿{oGWm𾳑I-o^ky5k?KEE;cח_R~9rz_-DdK2QN$ (I<)O>1l>gXvh1ҹMvh`(n{x뾺E<ΛXz<㗯\d=V3G@6pB~YMχʎq/gL6c҉|.LcR6aF0 o{{2Ўǰ6^-2Qa{/X[wD"Nh)&&ֵD_ӖDwEb*6EE-.Q-$F5;gggggקzUVwPAV7?c{F21yRg Te˶^#aꬵEjRg zaL;Gd>n$}UHxWǥ[ 0N:O7 "UyչZo]/8ְ>Q٥i+Vn8cE%uIA̦ =hRmB2Q<XMl(bx6 T| ^ MEE0!1(m1D5p vL`ABBH pkWQŌР=m@0J(hax 8( `͇`K`=GHY)Q0a D(;;YzT`W)8z-p]t #5a'eC3:_Oj=>Q(m.}{(;՜~?ebLVHeW>BNG)ۋJ:Q֎VsQo''(EăUWcHB!iQق~ Ǔ40?8Gau"rЫó8xƓ 6'b**NU@ūHf o] QX+V=4"qҥT2NJbH5e2ڣr9c#`ѹ# #"G"ë?ĵ ,o'{4/ s5I^;4GKwHcCP &>~Dc%Fsdo7>ٛh=1}x< 0ڻWsBc{ОJ7K }M='3{g!]%RLn'ZpcwuoK"'!{D ZNMOq_;T=T{(pYN6'R;uh0ԇg 8Ea%a580=}5ʰJ`Mȩnv{$G9O'ΥHzOR< J8#X`gb'Z0nlL+UR c$c.uuÅ=Unv.N{CW d|n R; -VVQqk3fW?"zۘL &?}_1@SA3/y@@M0t(uWn#aRV #cOc;+ÕjN~^\罄Pv &OOph8"UywцUH5JQrvSI r%IΣ?=G>}KĮ.𔀘j=-~ ePL5" Hj.$&255x_ZHi۠FаEipV@:.*7a).}ZΧBM,#V.$=.tmAwx q]L}OG.!Z厧ߏ i/G^~w Ca #55w\ߙa WH"0w$ ~k0wQ]°% ݟQ ~Tch`6-WTwPnJf`$r K,SxGү2+߷;xmQ9@)ߔ(]Y{8<E!r,5׭ ȐqKѶZU?FΙ:xMn[Y򤢓Sh|Unu3S;ytRd 4S;"C`']_#B ta"A*]  +̃WB::UHXM!42 # ʯlA%?ZGϭ>ACkFK`7RaʏqѐtQu)T1 rX1A_'Zǹs*d3 Fx"4̀ ч}J6+ Bum\{Zj&mkc촒UI'u$Ӻ5ΞIJ]S;ri{i\2SJViix vg>7BܘD-;2;R`Z pt:](I` }p~)7&eZɢ9jRDXcKM]v7T; 5mR.I #n$0ҹB&4 Mk |(Eb$;)3npna @ niKI;_Dq|h>`M|f/1ۑ H#Ϛĺʀ$ N泅x6HYl1+] *>f(tGLf˅vPֽQ׀B!XŧB<|l*Ns>[؅m'R̓:dpbRN2@?^,[\O!aZҙGa.#+|CH<ꤦ\n HfV ߞ9$q+T]ewa(_P'KEL)sM ZaI-m)|&e(L`(B9Ϥ 0PNyLs`S)R(R L/Z2J[6"YЖ|N TOx?ߗIxJ0DŽBxjMQ&dϴ@3.ʼn%T:KtHR\\R2A0> +tts😟L>y%zUÔadLfr>@1]Ti%7<}IExxCAIE`\%R[r^kڸxVJdLW0A.4V6q$̎dcNΝ iźׂyDB#XT VeHk]PRM0rGH" ',XH6x(rbl Xڗ0ᐥ\)l7WfPpl+K䲳a[imXh@:٩: NVPߋ+}bMSak]jsNU%K"l:CL%٢#&(i#\22!\Ss)7g lA%9/kysB^ز{ K>Är;SKJ0&~)Q.nB ֗\;STV 6ET)&_ejMZ|ྒྷEU4ۓ"R4T?ԇ~u^TN>R2S^u';Jldϻ,UXd]gA9:]Q4ZY(zEv^.opҘʧSC|7kLuSPx,x18_ǑP 4hq{kO7FNbDoBlMx6yBN2(oY38(FuyPCDܦ ;3U'dQx%/>sozJg¤Oz>KOWM5Iي_=>}WWv~bWo6F짤)o oOT_5{/|jo_z6}^WoW6U?S§=e_ſ{]71o{ޟ?J~}y /?} S?'EÏ;1} xk]OlN؟>W{Hy_=n|RW}H}x?Ňo_Wi.S:0bh_ i_:IOC0u1~k(7ROxSYf}vwVOSe -}`g}ߋps/>^|z/[ |yo/{?gx5ξGv_i/~ȀwPzuN9uЋN J+2eG)'Y[A{a4?/S8RͧwZN[%~=.)ħig!/2'/W6I .q~M?IUѿHD9#!ǟ ?GӁo=|:䗖227~S{I~gtN I׫$Y-ވߘ-^2c劵 tct H华L>܈~{1m38wyt ӉOng%\ֲ˚W-u T}Z[뷐~ŧϥ%W7ZWii^iYluƺ斕KމWo=o{_?[^w2pw=75_ww PKeB)G!minimext-0.1.dist-info/EXTENSIONSRPPM(QBjPKeB`'4minimext-0.1.dist-info/METADATAm0}P"p0GA&ŶU!fKv&G-8g4xY#.Iħcl4H fxA&X1Ի]iq,iԦg-Qp9wfJnvs _h$ѣ4-~PV$dݼo->i9F=/PKeB2dcminimext-0.1.dist-info/WHEEL HM K-*ϳR03rOK-J,/RH,.LR033KI-3 /, (-JJY)%r$[)$dVWXśPKeB-7gminimext-0.1.dist-info/RECORDuKr0нg .@#MxnʒwЖ6sYXlG\P ϋ 5z}&TuƼyuȚ6"H,fm RYpTi9E<'}_GaUS7s)PA؀68D3evUM:;$V.[Eڋi9;|0#7H3;LŊ9N yWn=7y``_+dz`PKeB&{C minimext.soPKeB)G!minimext-0.1.dist-info/EXTENSIONSPKeB`'4minimext-0.1.dist-info/METADATAPKeB2dcminimext-0.1.dist-info/WHEELPKeB-7gminimext-0.1.dist-info/RECORDPKjdistlib-0.2.2/tests/SETUPTOOLS-PKG-INFO0000664000000000000000000002120112027456516015627 0ustar rootrootMetadata-Version: 1.0 Name: setuptools Version: 0.6c9 Summary: Download, build, install, upgrade, and uninstall Python packages -- easily! Home-page: http://pypi.python.org/pypi/setuptools Author: Phillip J. Eby Author-email: distutils-sig@python.org License: PSF or ZPL Description: =============================== Installing and Using Setuptools =============================== .. contents:: **Table of Contents** ------------------------- Installation Instructions ------------------------- Windows ======= Install setuptools using the provided ``.exe`` installer. If you've previously installed older versions of setuptools, please delete all ``setuptools*.egg`` and ``setuptools.pth`` files from your system's ``site-packages`` directory (and any other ``sys.path`` directories) FIRST. If you are upgrading a previous version of setuptools that was installed using an ``.exe`` installer, please be sure to also *uninstall that older version* via your system's "Add/Remove Programs" feature, BEFORE installing the newer version. Once installation is complete, you will find an ``easy_install.exe`` program in your Python ``Scripts`` subdirectory. Be sure to add this directory to your ``PATH`` environment variable, if you haven't already done so. RPM-Based Systems ================= Install setuptools using the provided source RPM. The included ``.spec`` file assumes you are installing using the default ``python`` executable, and is not specific to a particular Python version. The ``easy_install`` executable will be installed to a system ``bin`` directory such as ``/usr/bin``. If you wish to install to a location other than the default Python installation's default ``site-packages`` directory (and ``$prefix/bin`` for scripts), please use the ``.egg``-based installation approach described in the following section. Cygwin, Mac OS X, Linux, Other ============================== 1. Download the appropriate egg for your version of Python (e.g. ``setuptools-0.6c9-py2.4.egg``). Do NOT rename it. 2. Run it as if it were a shell script, e.g. ``sh setuptools-0.6c9-py2.4.egg``. Setuptools will install itself using the matching version of Python (e.g. ``python2.4``), and will place the ``easy_install`` executable in the default location for installing Python scripts (as determined by the standard distutils configuration files, or by the Python installation). If you want to install setuptools to somewhere other than ``site-packages`` or your default distutils installation locations for libraries and scripts, you may include EasyInstall command-line options such as ``--prefix``, ``--install-dir``, and so on, following the ``.egg`` filename on the same command line. For example:: sh setuptools-0.6c9-py2.4.egg --prefix=~ You can use ``--help`` to get a full options list, but we recommend consulting the `EasyInstall manual`_ for detailed instructions, especially `the section on custom installation locations`_. .. _EasyInstall manual: http://peak.telecommunity.com/DevCenter/EasyInstall .. _the section on custom installation locations: http://peak.telecommunity.com/DevCenter/EasyInstall#custom-installation-locations Cygwin Note ----------- If you are trying to install setuptools for the **Windows** version of Python (as opposed to the Cygwin version that lives in ``/usr/bin``), you must make sure that an appropriate executable (``python2.3``, ``python2.4``, or ``python2.5``) is on your **Cygwin** ``PATH`` when invoking the egg. For example, doing the following at a Cygwin bash prompt will install setuptools for the **Windows** Python found at ``C:\\Python24``:: ln -s /cygdrive/c/Python24/python.exe python2.4 PATH=.:$PATH sh setuptools-0.6c9-py2.4.egg rm python2.4 Downloads ========= All setuptools downloads can be found at `the project's home page in the Python Package Index`_. Scroll to the very bottom of the page to find the links. .. _the project's home page in the Python Package Index: http://pypi.python.org/pypi/setuptools In addition to the PyPI downloads, the development version of ``setuptools`` is available from the `Python SVN sandbox`_, and in-development versions of the `0.6 branch`_ are available as well. .. _0.6 branch: http://svn.python.org/projects/sandbox/branches/setuptools-0.6/#egg=setuptools-dev06 .. _Python SVN sandbox: http://svn.python.org/projects/sandbox/trunk/setuptools/#egg=setuptools-dev -------------------------------- Using Setuptools and EasyInstall -------------------------------- Here are some of the available manuals, tutorials, and other resources for learning about Setuptools, Python Eggs, and EasyInstall: * `The EasyInstall user's guide and reference manual`_ * `The setuptools Developer's Guide`_ * `The pkg_resources API reference`_ * `Package Compatibility Notes`_ (user-maintained) * `The Internal Structure of Python Eggs`_ Questions, comments, and bug reports should be directed to the `distutils-sig mailing list`_. If you have written (or know of) any tutorials, documentation, plug-ins, or other resources for setuptools users, please let us know about them there, so this reference list can be updated. If you have working, *tested* patches to correct problems or add features, you may submit them to the `setuptools bug tracker`_. .. _setuptools bug tracker: http://bugs.python.org/setuptools/ .. _Package Compatibility Notes: http://peak.telecommunity.com/DevCenter/PackageNotes .. _The Internal Structure of Python Eggs: http://peak.telecommunity.com/DevCenter/EggFormats .. _The setuptools Developer's Guide: http://peak.telecommunity.com/DevCenter/setuptools .. _The pkg_resources API reference: http://peak.telecommunity.com/DevCenter/PkgResources .. _The EasyInstall user's guide and reference manual: http://peak.telecommunity.com/DevCenter/EasyInstall .. _distutils-sig mailing list: http://mail.python.org/pipermail/distutils-sig/ ------- Credits ------- * The original design for the ``.egg`` format and the ``pkg_resources`` API was co-created by Phillip Eby and Bob Ippolito. Bob also implemented the first version of ``pkg_resources``, and supplied the OS X operating system version compatibility algorithm. * Ian Bicking implemented many early "creature comfort" features of easy_install, including support for downloading via Sourceforge and Subversion repositories. Ian's comments on the Web-SIG about WSGI application deployment also inspired the concept of "entry points" in eggs, and he has given talks at PyCon and elsewhere to inform and educate the community about eggs and setuptools. * Jim Fulton contributed time and effort to build automated tests of various aspects of ``easy_install``, and supplied the doctests for the command-line ``.exe`` wrappers on Windows. * Phillip J. Eby is the principal author and maintainer of setuptools, and first proposed the idea of an importable binary distribution format for Python application plug-ins. * Significant parts of the implementation of setuptools were funded by the Open Source Applications Foundation, to provide a plug-in infrastructure for the Chandler PIM application. In addition, many OSAF staffers (such as Mike "Code Bear" Taylor) contributed their time and stress as guinea pigs for the use of eggs and setuptools, even before eggs were "cool". (Thanks, guys!) Keywords: CPAN PyPI distutils eggs package management Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Python Software Foundation License Classifier: License :: OSI Approved :: Zope Public License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: System :: Archiving :: Packaging Classifier: Topic :: System :: Systems Administration Classifier: Topic :: Utilities distlib-0.2.2/tests/bad.bin0000664000000000000000000000001512103470076014223 0ustar rootrootHello, world distlib-0.2.2/tests/compat.py0000664000000000000000000000165412300015212014634 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # import sys _ver = sys.version_info[:2] if _ver >= (3, 2): import unittest elif _ver <= (2, 6): import unittest2 as unittest elif (2, 7) <= _ver < (3, 0): import unittest else: raise ValueError('Tests not supported under Python 3.0 and 3.1') if _ver[0] < 3: import Queue as queue from SimpleXMLRPCServer import SimpleXMLRPCServer from SimpleHTTPServer import SimpleHTTPRequestHandler from BaseHTTPServer import HTTPServer text_type = unicode from urllib import unquote from urllib2 import Request from urlparse import urlparse else: import queue from xmlrpc.server import SimpleXMLRPCServer from http.server import HTTPServer, SimpleHTTPRequestHandler text_type = str from urllib.parse import urlparse, unquote from urllib.request import Request distlib-0.2.2/tests/test_manifest.py0000664000000000000000000002070312445642006016233 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2013 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # import logging import logging.handlers import os import re from compat import unittest from distlib import DistlibException from distlib.manifest import Manifest logger = logging.getLogger(__name__) HERE = os.path.abspath(os.path.dirname(__file__)) class ManifestTestCase(unittest.TestCase): def setUp(self): self.base = os.path.join(HERE, 'testsrc') self.manifest = Manifest(self.base) def get_files(self, files): return set([os.path.relpath(p, self.base) for p in files]) def test_findall(self): mf = self.manifest mf.findall() actual = self.get_files(mf.allfiles) expected = set([ '.hidden', 'README.txt', 'LICENSE', os.path.join('subdir', 'somedata.txt'), os.path.join('subdir', 'lose', 'lose.txt'), os.path.join('subdir', 'subsubdir', 'somedata.bin'), os.path.join('keep', 'keep.txt'), ]) self.assertEqual(actual, expected) def test_add(self): mf = self.manifest mf.add('README.txt') actual = self.get_files(mf.files) expected = set(['README.txt']) def test_add_many(self): mf = self.manifest mf.add_many(['README.txt', 'LICENSE']) actual = self.get_files(mf.files) expected = set(['README.txt', 'LICENSE']) def test_clear(self): mf = self.manifest mf.findall() mf.add('abc') self.assertTrue(mf.files) mf.clear() self.assertFalse(mf.files) self.assertFalse(mf.allfiles) def test_invalid(self): mf = self.manifest self.assertRaises(DistlibException, mf.process_directive, 'random abc') for cmd in ('include', 'exclude', 'global-include', 'global-exclude'): self.assertRaises(DistlibException, mf.process_directive, cmd) for cmd in ('recursive-include', 'recursive-exclude'): s = '%s dir' % cmd self.assertRaises(DistlibException, mf.process_directive, s) for cmd in ('prune', 'graft'): self.assertRaises(DistlibException, mf.process_directive, cmd) s = '%s abc def' % cmd self.assertRaises(DistlibException, mf.process_directive, s) def test_default_action(self): mf = self.manifest mf.process_directive('*') actual = self.get_files(mf.files) expected = set(['.hidden', 'README.txt', 'LICENSE']) self.assertEqual(actual, expected) def test_include(self): mf = self.manifest mf.process_directive('include README.txt LICENSE') actual = self.get_files(mf.files) expected = set(['README.txt', 'LICENSE']) self.assertEqual(actual, expected) def test_exclude(self): mf = self.manifest mf.process_directive('global-include *.txt') mf.process_directive('exclude README.txt') actual = self.get_files(mf.files) expected = set([ os.path.join('keep', 'keep.txt'), os.path.join('subdir', 'somedata.txt'), os.path.join('subdir', 'lose', 'lose.txt'), ]) self.assertEqual(actual, expected) def test_exclude_regex_str(self): mf = self.manifest mf.process_directive('global-include *.txt') mf._exclude_pattern(r'R.*\.txt', is_regex=True) actual = self.get_files(mf.files) expected = set([ os.path.join('keep', 'keep.txt'), os.path.join('subdir', 'somedata.txt'), os.path.join('subdir', 'lose', 'lose.txt'), ]) self.assertEqual(actual, expected) def test_exclude_regex_re(self): mf = self.manifest mf.process_directive('global-include *.txt') mf._exclude_pattern(re.compile(r'R.*\.txt'), is_regex=True) actual = self.get_files(mf.files) expected = set([ os.path.join('keep', 'keep.txt'), os.path.join('subdir', 'somedata.txt'), os.path.join('subdir', 'lose', 'lose.txt'), ]) self.assertEqual(actual, expected) def test_global_include(self): mf = self.manifest mf.process_directive('global-include *.txt') actual = self.get_files(mf.files) expected = set([ 'README.txt', os.path.join('keep', 'keep.txt'), os.path.join('subdir', 'somedata.txt'), os.path.join('subdir', 'lose', 'lose.txt'), ]) self.assertEqual(actual, expected) def test_global_exclude(self): mf = self.manifest mf.process_directive('global-include *.txt') mf.process_directive('global-exclude *d*.txt') actual = self.get_files(mf.files) expected = set([ 'README.txt', os.path.join('keep', 'keep.txt'), os.path.join('subdir', 'lose', 'lose.txt'), ]) self.assertEqual(actual, expected) def test_recursive_include(self): mf = self.manifest mf.process_directive('recursive-include subdir *.txt') actual = self.get_files(mf.files) expected = set([ os.path.join('subdir', 'somedata.txt'), os.path.join('subdir', 'lose', 'lose.txt'), ]) self.assertEqual(actual, expected) def test_recursive_exclude(self): mf = self.manifest mf.process_directive('global-include *.txt') mf.process_directive('recursive-exclude subdir *d*.txt') actual = self.get_files(mf.files) expected = set([ 'README.txt', os.path.join('keep', 'keep.txt'), os.path.join('subdir', 'lose', 'lose.txt'), ]) self.assertEqual(actual, expected) def test_graft(self): mf = self.manifest mf.process_directive('graft keep') actual = self.get_files(mf.files) expected = set([ os.path.join('keep', 'keep.txt'), ]) self.assertEqual(actual, expected) def test_prune(self): mf = self.manifest mf.process_directive('graft subdir') mf.process_directive('prune subdir/lose') actual = self.get_files(mf.files) expected = set([ os.path.join('subdir', 'somedata.txt'), os.path.join('subdir', 'subsubdir', 'somedata.bin'), ]) self.assertEqual(actual, expected) def test_sorting(self): mf = self.manifest mf.process_directive('global-include *') actual = self.get_files(mf.sorted()) expected = set([ '.hidden', 'LICENSE', 'README.txt', os.path.join('subdir', 'somedata.txt'), os.path.join('subdir', 'lose', 'lose.txt'), os.path.join('subdir', 'subsubdir', 'somedata.bin'), os.path.join('keep', 'keep.txt'), ]) self.assertEqual(actual, expected) def test_find_warnings(self): mf = self.manifest lines = ( 'include nonexistent', 'exclude nonexistent', 'global-include nonexistent', 'global-exclude nonexistent', 'recursive-include subdir nonexistent', 'recursive-exclude subdir nonexistent', 'graft nonexistent', 'prune nonexistent', ) h = logging.handlers.MemoryHandler(len(lines)) dl_logger = logging.getLogger('distlib.manifest') dl_logger.addHandler(h) try: for line in lines: mf.process_directive(line) finally: dl_logger.removeHandler(h) h.close() actual = [r.getMessage() for r in h.buffer] expected = [ "no files found matching 'nonexistent'", #"no previously-included files found matching 'nonexistent'", "no files found matching 'nonexistent' anywhere in distribution", #"no previously-included files matching 'nonexistent' found " # "anywhere in distribution", "no files found matching 'nonexistent' under directory 'subdir'", #"no previously-included files matching 'nonexistent' found under " # "directory 'subdir'", "no directories found matching 'nonexistent'", "no previously-included directories found matching 'nonexistent'", ] self.assertEqual(actual, expected) if __name__ == '__main__': # pragma: no cover unittest.main() distlib-0.2.2/tests/bad_wheels/0000775000000000000000000000000012656456062015120 5ustar rootrootdistlib-0.2.2/tests/bad_wheels/dummy-0.1-py27-none-any.whl0000664000000000000000000000234012267352744021603 0ustar rootrootPKC}Bdummy.pyPKL4DKmdummy-0.1.dist-info/pydist.jsonUT RRux n0 <H[ll7$&4MicJ&s¸= !Z1"?8.G0O m a5Dâ(SТэo%1X9mR1Dx%eӆrTh&ąuHa8'}̱ZR3F*m4-ixE6GmxHV0k^PϿn1WYaj42;Jy*Y+#E }ym'mENUNVХO4I)TqnR~55~} ,Xh3PKQ}BjqMZZYdummy-0.1.dist-info/WHEEL HM K-*ϳR03rOK-J,/RH,.LR033KI-3 /, (-JJY)r$[)T&UPKQ}BJ5dummy-0.1.dist-info/RECORDm̻0@oiZ+vp@E֯7nnw'nRJ: {d0[u8{!<u'VJ8ÙN}`v Mq^70.6yO^N%ܷL=[F[(^7@Fu圱O<;tD6+BuΦE:':PKC}Bdummy.pyPKL4DKm(dummy-0.1.dist-info/pydist.jsonUTRux PKQ}BjqMZZYdummy-0.1.dist-info/WHEELPKQ}BJ5dummy-0.1.dist-info/RECORDPK*distlib-0.2.2/tests/testdist-0.1/0000775000000000000000000000000012656456062015162 5ustar rootrootdistlib-0.2.2/tests/testdist-0.1/PKG-INFO0000644000000000000000000000070712103333572016244 0ustar rootrootMetadata-Version: 1.2 Name: {username}_testdist Version: 0.1 Summary: A test project for distlib Description: This distribution is a test for distlib. Keywords: Home-page: http://pypi.python.org/pypi/{username}_testdist/ Author: Test User Author-email: test.user@testusers.org Maintainer: Test User Maintainer-email: test.user@testusers.org License: Copyright (C) 2013 by Test User. See LICENSE for details. Download-URL: UNKNOWN Requires-Python: UNKNOWN distlib-0.2.2/tests/testdist-0.1/testdist.py0000644000000000000000000000027212103333572017361 0ustar rootroot""" This is a test distribution for distlib. """ __author__ = "Test User " __status__ = "alpha" __version__ = "0.1" __date__ = "31 January 2013" distlib-0.2.2/tests/testdist-0.1/LICENSE0000644000000000000000000000166612103333572016161 0ustar rootrootCopyright (C) 2013 by Test User. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Vinay Sajip not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. distlib-0.2.2/tests/testdist-0.1/doc/0000775000000000000000000000000012656456062015727 5ustar rootrootdistlib-0.2.2/tests/testdist-0.1/doc/index.html0000664000000000000000000000023112103333572017703 0ustar rootroot A test distribution for distlib This is dummy documentation for a test distribution for distlib. distlib-0.2.2/tests/testdist-0.1/README.txt0000644000000000000000000000005612103333572016642 0ustar rootrootThis distribution is used to test distlib. distlib-0.2.2/tests/testdist-0.1/package.json0000664000000000000000000000104312103333572017431 0ustar rootroot{{ "source": {{ "modules": [ "testdist" ] }}, "version": "1", "metadata": {{ "maintainer": "Test User", "name": "{username}_testdist", "license": "Copyright (C) 2013 by Test User.", "author": "Test User", "home-page": "http://pypi.python.org/pypi/{username}_testdist/", "summary": "A test project for distlib", "version": "0.1", "maintainer-email": "test.user@testusers.org", "author-email": "test.user@testusers.org", "description": "This distribution is a test for distlib." }} }} distlib-0.2.2/tests/pydist-schema.json0000664000000000000000000001656612176222642016476 0ustar rootroot{ "id": "http://www.python.org/dev/peps/pep-0426/", "$schema": "http://json-schema.org/draft-04/schema#", "title": "Metadata for Python Software Packages 2.0", "type": "object", "properties": { "metadata_version": { "description": "Version of the file format", "type": "string", "pattern": "^(\\d+(\\.\\d+)*)$" }, "generator": { "description": "Name and version of the program that produced this file.", "type": "string", "pattern": "^[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])( \\(.*\\))?$" }, "name": { "description": "The name of the distribution.", "type": "string", "$ref": "#/definitions/valid_name" }, "version": { "description": "The distribution's public version identifier", "type": "string", "pattern": "^(\\d+(\\.\\d+)*)((a|b|c|rc)(\\d+))?(\\.(post)(\\d+))?(\\.(dev)(\\d+))?$" }, "source_label": { "description": "A constrained identifying text string", "type": "string", "pattern": "^[0-9a-z_.-+]+$" }, "source_url": { "description": "A string containing a full URL where the source for this specific version of the distribution can be downloaded.", "type": "string", "format": "uri" }, "summary": { "description": "A one-line summary of what the distribution does.", "type": "string" }, "document_names": { "description": "Names of supporting metadata documents", "type": "object", "properties": { "description": { "type": "string", "$ref": "#/definitions/document_name" }, "changelog": { "type": "string", "$ref": "#/definitions/document_name" }, "license": { "type": "string", "$ref": "#/definitions/document_name" } }, "additionalProperties": false }, "keywords": { "description": "A list of additional keywords to be used to assist searching for the distribution in a larger catalog.", "type": "array", "items": { "type": "string" } }, "license": { "description": "A string indicating the license covering the distribution.", "type": "string" }, "classifiers": { "description": "A list of strings, with each giving a single classification value for the distribution.", "type": "array", "items": { "type": "string" } }, "contacts": { "description": "A list of contributor entries giving the recommended contact points for getting more information about the project.", "type": "array", "items": { "type": "object", "$ref": "#/definitions/contact" } }, "contributors": { "description": "A list of contributor entries for other contributors not already listed as current project points of contact.", "type": "array", "items": { "type": "object", "$ref": "#/definitions/contact" } }, "project_urls": { "description": "A mapping of arbitrary text labels to additional URLs relevant to the project.", "type": "object" }, "extras": { "description": "A list of optional sets of dependencies that may be used to define conditional dependencies in \"may_require\" and similar fields.", "type": "array", "items": { "type": "string", "$ref": "#/definitions/extra_name" } }, "meta_requires": { "description": "A list of subdistributions made available through this metadistribution.", "type": "array", "$ref": "#/definitions/dependencies" }, "run_requires": { "description": "A list of other distributions needed to run this distribution.", "type": "array", "$ref": "#/definitions/dependencies" }, "test_requires": { "description": "A list of other distributions needed when this distribution is tested.", "type": "array", "$ref": "#/definitions/dependencies" }, "build_requires": { "description": "A list of other distributions needed when this distribution is built.", "type": "array", "$ref": "#/definitions/dependencies" }, "dev_requires": { "description": "A list of other distributions needed when this distribution is developed.", "type": "array", "$ref": "#/definitions/dependencies" }, "provides": { "description": "A list of strings naming additional dependency requirements that are satisfied by installing this distribution. These strings must be of the form Name or Name (Version)", "type": "array", "items": { "type": "string", "$ref": "#/definitions/provides_declaration" } }, "obsoleted_by": { "description": "A string that indicates that this project is no longer being developed. The named project provides a substitute or replacement.", "type": "string", "$ref": "#/definitions/requirement" }, "supports_environments": { "description": "A list of strings specifying the environments that the distribution explicitly supports.", "type": "array", "items": { "type": "string", "$ref": "#/definitions/environment_marker" } }, "install_hooks": { "description": "The install_hooks field is used to define various operations that may be invoked on a distribution in a platform independent manner.", "type": "object", "properties": { "postinstall": { "type": "string", "$ref": "#/definitions/entry_point" }, "preuninstall": { "type": "string", "$ref": "#/definitions/entry_point" } } }, "extensions": { "description": "Extensions to the metadata may be present in a mapping under the 'extensions' key.", "type": "object" } }, "required": ["metadata_version", "name", "version", "summary"], "additionalProperties": false, "definitions": { "contact": { "type": "object", "properties": { "name": { "type": "string" }, "email": { "type": "string" }, "url": { "type": "string" }, "role": { "type": "string" } }, "required": ["name"], "additionalProperties": false }, "dependencies": { "type": "array", "items": { "type": "object", "$ref": "#/definitions/dependency" } }, "dependency": { "type": "object", "properties": { "extra": { "type": "string", "$ref": "#/definitions/valid_name" }, "environment": { "type": "string", "$ref": "#/definitions/environment_marker" }, "requires": { "type": "array", "items": { "type": "string", "$ref": "#/definitions/requirement" } } }, "required": ["requires"], "additionalProperties": false }, "valid_name": { "type": "string", "pattern": "^[0-9A-Za-z]([0-9A-Za-z_.-]*[0-9A-Za-z])?$" }, "requirement": { "type": "string" }, "provides_declaration": { "type": "string" }, "environment_marker": { "type": "string" }, "entry_point": { "type": "string" }, "document_name": { "type": "string" }, "extra_name" : { "type": "string" } } } distlib-0.2.2/tests/fake_archives/0000775000000000000000000000000012656456062015615 5ustar rootrootdistlib-0.2.2/tests/fake_archives/coverage-3.4b2.tar.gz0000664000000000000000000000000012036421432021234 0ustar rootrootdistlib-0.2.2/tests/fake_archives/coverage-3.3.1.tar.gz0000664000000000000000000000000012036421420021143 0ustar rootrootdistlib-0.2.2/tests/fake_archives/subdir/0000775000000000000000000000000012656456062017105 5ustar rootrootdistlib-0.2.2/tests/fake_archives/subdir/config-0.3.7-py27-none-any.whl0000664000000000000000000000000012112527124024021 0ustar rootrootdistlib-0.2.2/tests/fake_archives/subdir/subsubdir/0000775000000000000000000000000012656456062021107 5ustar rootrootdistlib-0.2.2/tests/fake_archives/subdir/subsubdir/Flask-0.9.tar.gz0000664000000000000000000000000012036421732023554 0ustar rootrootdistlib-0.2.2/tests/fake_archives/subdir/subsubdir/Django-1.4.1.tar.gz0000664000000000000000000000000012036421702024046 0ustar rootrootdistlib-0.2.2/tests/fake_archives/subdir/python-gnupg-0.2.9.tar.gz0000664000000000000000000000000012036421652023312 0ustar rootrootdistlib-0.2.2/tests/fake_archives/coverage-3.5.2.tar.gz0000664000000000000000000000000012036421444021154 0ustar rootrootdistlib-0.2.2/tests/test_wheel.py0000664000000000000000000004663612641321230015535 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2013 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # from __future__ import unicode_literals import codecs import hashlib import os import re import shutil import subprocess import sys import tempfile from compat import unittest from distlib import DistlibException from distlib.compat import ZipFile, sysconfig, fsencode from distlib.database import DistributionPath, InstalledDistribution from distlib.manifest import Manifest from distlib.metadata import Metadata, METADATA_FILENAME from distlib.scripts import ScriptMaker from distlib.util import get_executable from distlib.wheel import (Wheel, PYVER, IMPVER, ARCH, ABI, COMPATIBLE_TAGS, is_compatible) try: with open(os.devnull, 'wb') as junk: subprocess.check_call(['pip', '--version'], stdout=junk, stderr=subprocess.STDOUT) PIP_AVAILABLE = True except Exception: PIP_AVAILABLE = False HERE = os.path.abspath(os.path.dirname(__file__)) EGG_INFO_RE = re.compile(r'(-py\d\.\d)?\.egg-info', re.I) def convert_egg_info(libdir, prefix): files = os.listdir(libdir) ei = list(filter(lambda d: d.endswith('.egg-info'), files))[0] olddn = os.path.join(libdir, ei) di = EGG_INFO_RE.sub('.dist-info', ei) newdn = os.path.join(libdir, di) os.rename(olddn, newdn) files = os.listdir(newdn) for oldfn in files: pn = os.path.join(newdn, oldfn) if oldfn == 'PKG-INFO': md = Metadata(path=pn) mn = os.path.join(newdn, METADATA_FILENAME) md.write(mn) os.remove(pn) manifest = Manifest(os.path.dirname(libdir)) manifest.findall() dp = DistributionPath([libdir]) dist = next(dp.get_distributions()) dist.write_installed_files(manifest.allfiles, prefix) def install_dist(distname, workdir): pfx = '--install-option=' purelib = pfx + '--install-purelib=%s/purelib' % workdir platlib = pfx + '--install-platlib=%s/platlib' % workdir headers = pfx + '--install-headers=%s/headers' % workdir scripts = pfx + '--install-scripts=%s/scripts' % workdir data = pfx + '--install-data=%s/data' % workdir cmd = ['pip', 'install', '--index-url', 'https://pypi.python.org/simple/', '--timeout', '3', '--default-timeout', '3', purelib, platlib, headers, scripts, data, distname] result = { 'scripts': os.path.join(workdir, 'scripts'), 'headers': os.path.join(workdir, 'headers'), 'data': os.path.join(workdir, 'data'), } p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout, _ = p.communicate() if p.returncode: raise ValueError('pip failed to install %s:\n%s' % (distname, stdout)) for dn in ('purelib', 'platlib'): libdir = os.path.join(workdir, dn) if os.path.isdir(libdir): result[dn] = libdir break convert_egg_info(libdir, workdir) dp = DistributionPath([libdir]) dist = next(dp.get_distributions()) md = dist.metadata result['name'] = md.name result['version'] = md.version return result class WheelTestCase(unittest.TestCase): def test_valid_filename(self): attrs = ('name', 'version', 'buildver', 'pyver', 'abi', 'arch') cases = ( ('pkg-1.0.0-cp32.cp33-noabi-noarch.whl', ('pkg', '1.0.0', '', ['cp32', 'cp33'], ['noabi'], ['noarch'])), ('package-1.0.0-cp33-noabi-linux_x86_64.whl', ('package', '1.0.0', '', ['cp33'], ['noabi'], ['linux_x86_64'])), ('test-1.0-1st-py2.py3-none-win32.whl', ('test', '1.0', '1st', ['py2', 'py3'], ['none'], ['win32'])), ('Pillow-2.8.1-cp27-none-macosx_10_6_intel.' 'macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.' 'macosx_10_10_x86_64.whl', ('Pillow', '2.8.1', '', ['cp27'], ['none'], ['macosx_10_6_intel', 'macosx_10_9_intel', 'macosx_10_9_x86_64', 'macosx_10_10_intel', 'macosx_10_10_x86_64'])), ) for name, values in cases: w = Wheel(name) self.assertEqual(w.wheel_version, (1, 1)) self.assertEqual(w.filename, name) for attr, value in zip(attrs, values): self.assertEqual(getattr(w, attr), value) def test_invalid_filename(self): names = ( '', 'package.whl', 'package-1.0.0-cp32.cp33.whl', 'package-1.0.0-cp32.cp33.whl', 'package-1.0.0-cp32.cp33-noabi.whl', 'package-1.0.0-cp32.cp33-noabi-noarch.zip', ) for name in names: self.assertRaises(DistlibException, Wheel, name) def test_valid_name(self): attrs = ('name', 'version', 'buildver', 'pyver', 'abi', 'arch') pyver = PYVER cases = ( ('pkg-1.0.0', ('pkg', '1.0.0', '', [PYVER], ['none'], ['any'])), ('test-1.0-1st', ('test', '1.0', '1st', [PYVER], ['none'], ['any'])), (None, ('dummy', '0.1', '', [PYVER], ['none'], ['any'])), ) ENDING = '-%s-none-any.whl' % PYVER for name, values in cases: w = Wheel(name) self.assertEqual(w.wheel_version, (1, 1)) self.assertTrue(w.filename.endswith(ENDING)) for attr, value in zip(attrs, values): self.assertEqual(getattr(w, attr), value) def test_compatible_tags(self): self.assertEqual(PYVER, 'py%d%d' % sys.version_info[:2]) tags = COMPATIBLE_TAGS self.assertIn((PYVER, 'none', 'any'), tags) self.assertIn((PYVER[:-1], 'none', 'any'), tags) this_arch = filter(lambda o: o[-1] == ARCH, tags) self.assertTrue(this_arch) def test_is_compatible(self): fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') if 'py27' <= PYVER < 'py32': self.assertTrue(is_compatible(fn)) self.assertTrue(Wheel(fn).is_compatible()) def test_metadata(self): fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') w = Wheel(fn) md = w.metadata self.assertEqual(md.name, 'dummy') self.assertEqual(md.version, '0.1') def test_invalid(self): fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') w = Wheel(fn) self.assertRaises(DistlibException, w.get_hash, b'', 'badalgo') def check_built_wheel(self, wheel, expected): for key in expected: self.assertEqual(expected[key], getattr(wheel, key)) fn = os.path.join(wheel.dirname, wheel.filename) self.assertTrue(os.path.exists(fn)) name, version = wheel.name, wheel.version with ZipFile(fn, 'r') as zf: for key in ('scripts', 'headers', 'data'): arcname = '%s-%s.data/%s/%s_file.txt' % (name, version, key, key) with zf.open(arcname) as bf: data = bf.read() expected = ('dummy data - %s' % key).encode('utf-8') if key == 'scripts': expected = b'#!python\n' + expected self.assertTrue(data, expected) def test_build_tags(self): workdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, workdir) name = 'dummy' version = '0.1' paths = {'prefix': workdir} for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): paths[key] = p = os.path.join(workdir, key) os.makedirs(p) fn = os.path.join(p, '%s_file.txt' % key) with open(fn, 'w') as f: f.write('dummy data - %s' % key) if key in ('purelib', 'platlib'): p = os.path.join(p, '%s-%s.dist-info' % (name, version)) os.makedirs(p) fn = os.path.join(p, 'RECORD') purelib = paths.pop('purelib') platlib = paths.pop('platlib') # Make a pure wheel with default tags paths['purelib'] = purelib wheel = Wheel('%s-%s' % (name, version)) wheel.dirname = workdir wheel.build(paths) expected = { 'name': name, 'version': version, 'pyver': [PYVER], 'abi': ['none'], 'arch': ['any'], 'filename': 'dummy-0.1-%s-none-any.whl' % PYVER, } self.check_built_wheel(wheel, expected) # Make a pure wheel with custom tags pyver = [PYVER[:-1], PYVER] wheel.build(paths, {'pyver': pyver}) expected = { 'name': name, 'version': version, 'pyver': pyver, 'abi': ['none'], 'arch': ['any'], 'filename': 'dummy-0.1-%s-none-any.whl' % '.'.join(pyver), } self.check_built_wheel(wheel, expected) # Make a non-pure wheel with default tags paths.pop('purelib') paths['platlib'] = platlib wheel.build(paths) expected['pyver'] = [IMPVER] expected['abi'] = [ABI] expected['arch'] = [ARCH] expected['filename'] = 'dummy-0.1-%s-%s-%s.whl' % (IMPVER, ABI, ARCH) self.check_built_wheel(wheel, expected) def do_build_and_install(self, dist): srcdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, srcdir) dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) paths = install_dist(dist, srcdir) paths['prefix'] = srcdir w = Wheel() w.name = paths.pop('name') w.version = paths.pop('version') w.dirname = srcdir pathname = w.build(paths) self.assertTrue(os.path.exists(pathname)) paths = {'prefix': dstdir} for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): paths[key] = os.path.join(dstdir, key) w = Wheel(pathname) maker = ScriptMaker(None, None, add_launchers=False) maker.executable = os.path.join(paths['scripts'], 'python') dist = w.install(paths, maker) self.assertIsNotNone(dist) self.assertEqual(dist.name, w.name) self.assertEqual(dist.version, w.version) shared = dist.shared_locations self.assertTrue(shared) os.remove(pathname) sm = Manifest(srcdir) sm.findall() sfiles = set([os.path.relpath(p, srcdir) for p in sm.allfiles]) dm = Manifest(dstdir) dm.findall() dfiles = set([os.path.relpath(p, dstdir) for p in dm.allfiles]) omitted = sfiles - dfiles omitted = omitted.pop() endings = os.path.join('.dist-info', 'WHEEL'), '.pyc', '.pyo' self.assertTrue(omitted.endswith(endings)) def test_version_incompatibility(self): class Warner(object): def __call__(self, wheel_version, file_version): self.wheel_version = wheel_version self.file_version = file_version fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) w = Wheel(fn) paths = {'prefix': dstdir} for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): paths[key] = os.path.join(dstdir, key) warner = Warner() maker = ScriptMaker(None, None) w.install(paths, maker, warner=warner) self.assertEqual(warner.wheel_version, w.wheel_version) self.assertEqual(warner.file_version, (2, 0)) # Now set the wheel's instance to the higher value and ensure # warner isn't called warner = Warner() w.wheel_version = (2, 0) w.install(paths, maker, warner=warner) self.assertFalse(hasattr(warner, 'wheel_version')) self.assertFalse(hasattr(warner, 'file_version')) def test_custom_executable(self): fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') for executable in 'mypython', None: dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) w = Wheel(fn) paths = {'prefix': dstdir} for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): paths[key] = os.path.join(dstdir, key) maker = ScriptMaker(None, None) maker.variants = set(['']) maker.executable = executable w.install(paths, maker) # On Windows there will be an exe file, and on POSIX a text file. # The test is structured to not care. p = paths['scripts'] # there should be just one file in the directory - dummy.py/dummy.exe p = os.path.join(p, os.listdir(p)[0]) with open(p, 'rb') as f: data = f.read() if executable is None: expected = fsencode(get_executable()) else: expected = executable.encode('utf-8') expected = b'#!' + expected + b' -E' self.assertIn(expected, data) def test_verify(self): fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') w = Wheel(fn) w.verify() fn = os.path.join(HERE, 'bad_wheels', 'dummy-0.1-py27-none-any.whl') w = Wheel(fn) self.assertRaises(DistlibException, w.verify) def wheel_modifier_nop(self, path_map): return False def wheel_modifier(self, path_map): mdpath = path_map['dummy-0.1.dist-info/pydist.json'] md = Metadata(path=mdpath) md.add_requirements(['numpy']) md.write(path=mdpath) return True def wheel_modifier_ver(self, path_map): mdpath = path_map['dummy-0.1.dist-info/pydist.json'] md = Metadata(path=mdpath) md.version = '0.1+123' md.write(path=mdpath) return True def test_update(self): workdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, workdir) fn = 'dummy-0.1-py27-none-any.whl' sfn = os.path.join(HERE, fn) dfn = os.path.join(workdir, fn) shutil.copyfile(sfn, dfn) mtime = os.stat(dfn).st_mtime w = Wheel(dfn) modified = w.update(self.wheel_modifier_nop) self.assertFalse(modified) self.assertEqual(mtime, os.stat(dfn).st_mtime) modified = w.update(self.wheel_modifier) self.assertTrue(modified) self.assertLessEqual(mtime, os.stat(dfn).st_mtime) w = Wheel(dfn) w.verify() md = w.metadata self.assertEqual(md.run_requires, [{'requires': ['numpy']}]) self.assertEquals(md.version, '0.1+1') modified = w.update(self.wheel_modifier_ver) self.assertTrue(modified) self.assertLessEqual(mtime, os.stat(dfn).st_mtime) w = Wheel(dfn) w.verify() md = w.metadata self.assertEqual(md.run_requires, [{'requires': ['numpy']}]) self.assertEquals(md.version, '0.1+123') def test_info(self): fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') w = Wheel(fn) actual = w.info actual.pop('Generator', None) expected = { 'Root-Is-Purelib': 'true', 'Tag': 'py27-none-any', 'Wheel-Version': '2.0' } self.assertEqual(actual, expected) @unittest.skipIf(sys.version_info[:2] != (2, 7), 'The test wheel is only ' '2.7 mountable') def test_mount(self): fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') w = Wheel(fn) self.assertNotIn(fn, sys.path) w.mount() self.assertIn(fn, sys.path) w.unmount() self.assertNotIn(fn, sys.path) def test_mount_extensions(self): if PYVER == 'py27': fn = 'minimext-0.1-cp27-none-linux_x86_64.whl' elif PYVER == 'py32': fn = 'minimext-0.1-cp32-cp32mu-linux_x86_64.whl' elif PYVER == 'py33': fn = 'minimext-0.1-cp33-cp33m-linux_x86_64.whl' else: fn = None if not fn: # pragma: no cover raise unittest.SkipTest('Suitable wheel not found.') fn = os.path.join(HERE, fn) w = Wheel(fn) if not w.is_compatible() or not w.is_mountable(): # pragma: no cover raise unittest.SkipTest('Wheel not suitable for mounting.') self.assertRaises(ImportError, __import__, 'minimext') w.mount() mod = __import__('minimext') self.assertIs(mod, sys.modules['minimext']) self.assertEqual(mod.fib(10), 55) w.unmount() del sys.modules['minimext'] self.assertRaises(ImportError, __import__, 'minimext') def test_local_version(self): w = Wheel('dummy-0.1_1.2') self.assertEqual(w.filename, 'dummy-0.1_1.2-%s' '-none-any.whl' % PYVER) self.assertEqual(w.name, 'dummy') self.assertEqual(w.version, '0.1-1.2') self.assertFalse(w.exists) w.version = '0.1-1.3' self.assertEqual(w.filename, 'dummy-0.1_1.3-%s' '-none-any.whl' % PYVER) def test_abi(self): pyver = sysconfig.get_config_var('py_version_nodot') if not pyver: pyver = '%s%s' % sys.version_info[:2] parts = ['cp', pyver] if sysconfig.get_config_var('Py_DEBUG'): parts.append('d') if sysconfig.get_config_var('WITH_PYMALLOC'): parts.append('m') if sysconfig.get_config_var('Py_UNICODE_SIZE') == 4: parts.append('u') if sys.version_info[:2] < (3, 5): abi = ABI else: abi = ABI.split('-')[0] self.assertEqual(''.join(parts), abi) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') @unittest.skipUnless(PIP_AVAILABLE, 'pip is needed for this test') def test_build_and_install_pure(self): self.do_build_and_install('sarge == 0.1') @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') @unittest.skipIf(hasattr(sys, 'pypy_version_info'), 'The test distribution' ' does not build on PyPy') @unittest.skipIf(sys.platform != 'linux2', 'The test distribution only ' 'builds on Linux') @unittest.skipUnless(PIP_AVAILABLE, 'pip is needed for this test') def test_build_and_install_plat(self): self.do_build_and_install('hiredis == 0.1.1') @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') @unittest.skipIf(sys.version_info[0] == 3, 'The test distribution is not ' '3.x compatible') @unittest.skipUnless(PIP_AVAILABLE, 'pip is needed for this test') def test_build_and_install_data(self): self.do_build_and_install('Werkzeug == 0.4') @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') @unittest.skipIf(sys.version_info[0] == 3, 'The test distribution is not ' '3.x compatible') @unittest.skipUnless(PIP_AVAILABLE, 'pip is needed for this test') def test_build_and_install_scripts(self): self.do_build_and_install('Babel == 0.9.6') if __name__ == '__main__': # pragma: no cover import logging logging.basicConfig(level=logging.DEBUG, filename='test_wheel.log', filemode='w', format='%(message)s') unittest.main() distlib-0.2.2/tests/keycert.pem0000664000000000000000000000366212106422554015170 0ustar rootroot-----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMl3Bj4QBMUiTi3N pPJICB1HJoxsIqF8xZ4vrw5THNpsUkLFrV76vymm+qNcNRB8F9DBcoR9GcBe6Bxm P0bTnn5cA+2qeOShhibHskD0V1uHfi3A9zYd/qj0Eg9Se7nFs73sXNF9FY6VKXEm HQtbIqK/28M9zbnYe3RwvP6pUKPTAgMBAAECgYEApWZnpJpoICSrBKW5zwPeTZM1 jcHVqLkUUWuaj+siXBzkaFd8n+bC/QJO8cFo+3C16Lh5OVavxqTkcTRsrMxeaK9H Ajqd9x4td+25Gu5YWDi742lRTvvWy4trpVH1KfS/LqOOssljswcXXvk008pEpMQB IH0TpC42LsQm90LnbNECQQD1SMTDyq5U4GyEPPn12VIKorcTHWe+3IID8ctHxLav iaA3q/m2s6lTULIXUeInaP8AV7Vn3eOPpy/UYY6DYLCbAkEA0kQvfhrvyBRQwqun CkbBv1WeJ5QtYcGOEJ8qYl9fHV9CnAicUcv2P64O1MRVVgmHnb6fKSNV6CzNtDW9 NUdBKQJARRUbpfE9rFYQ+iWaWO2+N5Sgb1fG0nCUhbvh/vKeaU4fu85J5HUxaW++ 2OaNBYCC4XvScdCCuQDjbbOUSdg/pQJALq9S+CXU7VCNadug1+hD5k6FMfZ1aQoH l+svBu5z+NqIuIo04vhtMVBdHKKG6/ZrtPt47TJaRZWFCqkP3H94mQJAJC/B+gIk xnBkHW4o2UEzxrwhAaeNpjODooCQqOeHH/uDXVyjJb19NCt5ba6eZn+PlR0EHdPe TLV9gZKEUEYQ3A== -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIC3jCCAkegAwIBAgIJANqYE3TB7bYrMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD VQQGEwJHQjEWMBQGA1UECAwNSGVydGZvcmRzaGlyZTEPMA0GA1UEBwwGQnVzaGV5 MSUwIwYDVQQKDBxSZWQgRG92ZSBDb25zdWx0YW50cyBMaW1pdGVkMRQwEgYDVQQL DAtEZXZlbG9wbWVudDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTEzMDIxMjA2MjAx M1oXDTIzMDIxMDA2MjAxM1owgYcxCzAJBgNVBAYTAkdCMRYwFAYDVQQIDA1IZXJ0 Zm9yZHNoaXJlMQ8wDQYDVQQHDAZCdXNoZXkxJTAjBgNVBAoMHFJlZCBEb3ZlIENv bnN1bHRhbnRzIExpbWl0ZWQxFDASBgNVBAsMC0RldmVsb3BtZW50MRIwEAYDVQQD DAlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMl3Bj4QBMUi Ti3NpPJICB1HJoxsIqF8xZ4vrw5THNpsUkLFrV76vymm+qNcNRB8F9DBcoR9GcBe 6BxmP0bTnn5cA+2qeOShhibHskD0V1uHfi3A9zYd/qj0Eg9Se7nFs73sXNF9FY6V KXEmHQtbIqK/28M9zbnYe3RwvP6pUKPTAgMBAAGjUDBOMB0GA1UdDgQWBBSbSzkK ZeuiK5I9alwtw0hyENEvWjAfBgNVHSMEGDAWgBSbSzkKZeuiK5I9alwtw0hyENEv WjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBABb7PCF09oErR3OKObNe 4ARiB7np6EchU/7eaegdM7rVaUEAMBh/xxrvaWhcqfwHDh1sAWnbvrKD+0Eg74Wq db2fqIQTQ5Zqip0i2F62cXA85OTAEeaOF2NJIRZyqthUU2hX3fri/HkdIF++fInx 6W9KH8ONyAEpKVzy2l4b4Pj9 -----END CERTIFICATE----- distlib-0.2.2/tests/test_util.py0000664000000000000000000011252312641266560015411 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # from io import BytesIO from itertools import islice import os import re import shutil import sys import tempfile import textwrap import time from compat import unittest from support import TempdirManager from distlib import DistlibException from distlib.compat import cache_from_source, Container from distlib.util import (get_export_entry, ExportEntry, resolve, get_cache_base, path_to_cache_dir, zip_dir, parse_credentials, ensure_slash, split_filename, EventMixin, Sequencer, unarchive, Progress, iglob, RICH_GLOB, parse_requirement, get_extras, Configurator, read_exports, write_exports, FileOperator, is_string_sequence, get_package_data) HERE = os.path.dirname(os.path.abspath(__file__)) class TestContainer(object): def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs class UtilTestCase(unittest.TestCase): def check_entry(self, entry, name, prefix, suffix, flags): self.assertEqual(entry.name, name) self.assertEqual(entry.prefix, prefix) self.assertEqual(entry.suffix, suffix) self.assertEqual(entry.flags, flags) def test_export_entry(self): self.assertIsNone(get_export_entry('foo.py')) self.assertIsNone(get_export_entry('foo.py=')) for spec in ('foo=foo:main', 'foo =foo:main', 'foo= foo:main', 'foo = foo:main'): self.check_entry(get_export_entry(spec), 'foo', 'foo', 'main', []) self.check_entry(get_export_entry('foo=foo.bar:main'), 'foo', 'foo.bar', 'main', []) self.check_entry(get_export_entry('foo=foo.bar:main [a]'), 'foo', 'foo.bar', 'main', ['a']) self.check_entry(get_export_entry('foo=foo.bar:main [ a ]'), 'foo', 'foo.bar', 'main', ['a']) self.check_entry(get_export_entry('foo=foo.bar:main [a=b, c=d,e, f=g]'), 'foo', 'foo.bar', 'main', ['a=b', 'c=d', 'e', 'f=g']) self.check_entry(get_export_entry('foo=foo.bar:main [a=9, 9=8,e, f9=g8]'), 'foo', 'foo.bar', 'main', ['a=9', '9=8', 'e', 'f9=g8']) self.check_entry(get_export_entry('foo=foo.bar:main[x]'), 'foo', 'foo.bar', 'main', ['x']) self.check_entry(get_export_entry('foo=abc'), 'foo', 'abc', None, []) self.assertRaises(DistlibException, get_export_entry, 'foo=foo.bar:x:y') self.assertRaises(DistlibException, get_export_entry, 'foo=foo.bar:x [') self.assertRaises(DistlibException, get_export_entry, 'foo=foo.bar:x ]') self.assertRaises(DistlibException, get_export_entry, 'foo=foo.bar:x []') self.assertRaises(DistlibException, get_export_entry, 'foo=foo.bar:x [\]') self.assertRaises(DistlibException, get_export_entry, 'foo=foo.bar:x [a=]') self.assertRaises(DistlibException, get_export_entry, 'foo=foo.bar:x [a,]') self.assertRaises(DistlibException, get_export_entry, 'foo=foo.bar:x [a,,b]') self.assertRaises(DistlibException, get_export_entry, 'foo=foo.bar:x [a b]') def test_resolve(self): import logging import logging.handlers self.assertIs(resolve('logging', None), logging) self.assertIs(resolve('logging.handlers', None), logging.handlers) self.assertIs(resolve('logging', 'root'), logging.root) self.assertEqual(resolve('logging', 'root.debug'), logging.root.debug) def test_cache_base(self): actual = get_cache_base() if os.name == 'nt' and 'LOCALAPPDATA' in os.environ: expected = os.path.expandvars('$localappdata') else: expected = os.path.expanduser('~') expected = os.path.join(expected, '.distlib') self.assertEqual(expected, actual) self.assertTrue(os.path.isdir(expected)) @unittest.skipIf(os.name != 'posix', 'Test is only valid for POSIX') def test_path_to_cache_dir_posix(self): self.assertEqual(path_to_cache_dir('/home/user/some-file.zip'), '--home--user--some-file.zip.cache') @unittest.skipIf(os.name != 'nt', 'Test is only valid for Windows') def test_path_to_cache_dir_nt(self): self.assertEqual(path_to_cache_dir(r'c:\Users\User\Some-File.zip'), 'c-----Users--User--Some-File.zip.cache') def test_parse_credentials(self): self.assertEqual(parse_credentials('example.com', ), (None, None, 'example.com')) self.assertEqual(parse_credentials('user@example.com', ), ('user', None, 'example.com')) self.assertEqual(parse_credentials('user:pwd@example.com', ), ('user', 'pwd', 'example.com')) def test_ensure_slash(self): self.assertEqual(ensure_slash(''), '/') self.assertEqual(ensure_slash('/'), '/') self.assertEqual(ensure_slash('abc'), 'abc/') self.assertEqual(ensure_slash('def/'), 'def/') def test_split_filename(self): self.assertIsNone(split_filename('abl.jquery')) self.assertEqual(split_filename('abl.jquery-1.4.2-2'), ('abl.jquery', '1.4.2-2', None)) self.assertEqual(split_filename('python-gnupg-0.1'), ('python-gnupg', '0.1', None)) self.assertEqual(split_filename('baklabel-1.0.3-2729-py3.2'), ('baklabel', '1.0.3-2729', '3.2')) self.assertEqual(split_filename('baklabel-1.0.3-2729-py27'), ('baklabel', '1.0.3-2729', '27')) self.assertEqual(split_filename('advpy-0.99b'), ('advpy', '0.99b', None)) self.assertEqual(split_filename('asv_files-dev-20120501-01', 'asv_files'), ('asv_files', 'dev-20120501-01', None)) self.assertEqual(split_filename('greenlet-0.4.0-py27-win32'), ('greenlet', '0.4.0', '27')) self.assertEqual(split_filename('greenlet-0.4.0-py27-linux_x86_64'), ('greenlet', '0.4.0', '27')) self.assertEqual(split_filename('django-altuser-v0.6.8'), ('django-altuser', 'v0.6.8', None)) self.assertEqual(split_filename('youtube_dl_server-alpha.1'), ('youtube_dl_server', 'alpha.1', None)) self.assertEqual(split_filename('pytest-xdist-dev'), ('pytest-xdist', 'dev', None)) self.assertEqual(split_filename('pytest_xdist-0.1_myfork', None), ('pytest_xdist', '0.1_myfork', None)) self.assertEqual(split_filename('pytest_xdist-0.1_myfork', 'pytest-xdist'), ('pytest_xdist', '0.1_myfork', None)) self.assertEqual(split_filename('pytest_xdist-0.1_myfork', 'pytest_dist'), ('pytest_xdist', '0.1_myfork', None)) def test_events(self): collected = [] def handler1(e, *args, **kwargs): collected.append((1, e, args, kwargs)) def handler2(e, *args, **kwargs): collected.append((2, e, args, kwargs)) def handler3(e, *args, **kwargs): if not args: raise NotImplementedError('surprise!') collected.append((3, e, args, kwargs)) return (args, kwargs) e = EventMixin() e.add('A', handler1) self.assertRaises(ValueError, e.remove, 'B', handler1) cases = ( ((1, 2), {'buckle': 'my shoe'}), ((3, 4), {'shut': 'the door'}), ) for case in cases: e.publish('A', *case[0], **case[1]) e.publish('B', *case[0], **case[1]) for actual, source in zip(collected, cases): self.assertEqual(actual, (1, 'A') + source[:1] + source[1:]) collected = [] e.add('B', handler2) self.assertEqual(tuple(e.get_subscribers('A')), (handler1,)) self.assertEqual(tuple(e.get_subscribers('B')), (handler2,)) self.assertEqual(tuple(e.get_subscribers('C')), ()) for case in cases: e.publish('A', *case[0], **case[1]) e.publish('B', *case[0], **case[1]) actuals = islice(collected, 0, None, 2) for actual, source in zip(actuals, cases): self.assertEqual(actual, (1, 'A') + source[:1] + source[1:]) actuals = islice(collected, 1, None, 2) for actual, source in zip(actuals, cases): self.assertEqual(actual, (2, 'B') + source[:1] + source[1:]) e.remove('B', handler2) collected = [] for case in cases: e.publish('A', *case[0], **case[1]) e.publish('B', *case[0], **case[1]) for actual, source in zip(collected, cases): self.assertEqual(actual, (1, 'A') + source[:1] + source[1:]) e.add('C', handler3) collected = [] returned = [] for case in cases: returned.extend(e.publish('C', *case[0], **case[1])) returned.extend(e.publish('C')) for actual, source in zip(collected, cases): self.assertEqual(actual, (3, 'C') + source[:1] + source[1:]) self.assertEqual(tuple(islice(returned, 1, None, 2)), (None, None)) actuals = islice(returned, 0, None, 2) for actual, expected in zip(actuals, cases): self.assertEqual(actual, expected) def test_sequencer_basic(self): seq = Sequencer() steps = ( ('check', 'sdist'), ('check', 'register'), ('check', 'sdist'), ('check', 'register'), ('register', 'upload_sdist'), ('sdist', 'upload_sdist'), ('check', 'build_clibs'), ('build_clibs', 'build_ext'), ('build_ext', 'build_py'), ('build_py', 'build_scripts'), ('build_scripts', 'build'), ('build', 'test'), ('register', 'upload_bdist'), ('build', 'upload_bdist'), ('build', 'install_headers'), ('install_headers', 'install_lib'), ('install_lib', 'install_scripts'), ('install_scripts', 'install_data'), ('install_data', 'install_distinfo'), ('install_distinfo', 'install') ) for pred, succ in steps: seq.add(pred, succ) # Note: these tests are sensitive to dictionary ordering # but work under Python 2.6, 2.7, 3.2, 3.3, 3.4 and PyPy 2.5 cases = ( ('check', ['check']), ('register', ['check', 'register']), ('sdist', ['check', 'sdist']), ('build_clibs', ['check', 'build_clibs']), ('build_ext', ['check', 'build_clibs', 'build_ext']), ('build_py', ['check', 'build_clibs', 'build_ext', 'build_py']), ('build_scripts', ['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts']), ('build', ['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts', 'build']), ('test', ['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts', 'build', 'test']), ('install_headers', ['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts', 'build', 'install_headers']), ('install_lib', ['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts', 'build', 'install_headers', 'install_lib']), ('install_scripts', ['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts', 'build', 'install_headers', 'install_lib', 'install_scripts']), ('install_data', ['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts', 'build', 'install_headers', 'install_lib', 'install_scripts', 'install_data']), ('install_distinfo', ['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts', 'build', 'install_headers', 'install_lib', 'install_scripts', 'install_data', 'install_distinfo']), ('install', ['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts', 'build', 'install_headers', 'install_lib', 'install_scripts', 'install_data', 'install_distinfo', 'install']), ('upload_sdist', (['check', 'register', 'sdist', 'upload_sdist'], ['check', 'sdist', 'register', 'upload_sdist'])), ('upload_bdist', (['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts', 'build', 'register', 'upload_bdist'], ['check', 'build_clibs', 'build_ext', 'build_py', 'build_scripts', 'register', 'build', 'upload_bdist'])), ) for final, expected in cases: actual = list(seq.get_steps(final)) if isinstance(expected, tuple): self.assertIn(actual, expected) else: self.assertEqual(actual, expected) dot = seq.dot expected = ''' digraph G { check -> build_clibs; install_lib -> install_scripts; register -> upload_bdist; build -> upload_bdist; build_ext -> build_py; install_scripts -> install_data; check -> sdist; check -> register; build -> install_headers; install_data -> install_distinfo; sdist -> upload_sdist; register -> upload_sdist; install_distinfo -> install; build -> test; install_headers -> install_lib; build_py -> build_scripts; build_clibs -> build_ext; build_scripts -> build; } ''' expected = textwrap.dedent(expected).strip().splitlines() actual = dot.splitlines() self.assertEqual(expected[0], actual[0]) self.assertEqual(expected[-1], actual[-1]) self.assertEqual(set(expected[1:-1]), set(actual[1:-1])) actual = seq.strong_connections expected = ( [ ('test',), ('upload_bdist',), ('install',), ('install_distinfo',), ('install_data',), ('install_scripts',), ('install_lib',), ('install_headers',), ('build',), ('build_scripts',), ('build_py',), ('build_ext',), ('build_clibs',), ('upload_sdist',), ('sdist',), ('register',), ('check',) ], [ ('install',), ('install_distinfo',), ('install_data',), ('install_scripts',), ('install_lib',), ('install_headers',), ('test',), ('upload_bdist',), ('build',), ('build_scripts',), ('build_py',), ('build_ext',), ('build_clibs',), ('upload_sdist',), ('sdist',), ('register',), ('check',) ], [ ('upload_sdist',), ('sdist',), ('install',), ('install_distinfo',), ('install_data',), ('upload_bdist',), ('register',), ('install_scripts',), ('install_lib',), ('install_headers',), ('test',), ('build',), ('build_scripts',), ('build_py',), ('build_ext',), ('build_clibs',), ('check',) ], # Next case added for PyPy [ ('upload_sdist',), ('sdist',), ('upload_bdist',), ('register',), ('test',), ('install',), ('install_distinfo',), ('install_data',), ('install_scripts',), ('install_lib',), ('install_headers',), ('build',), ('build_scripts',), ('build_py',), ('build_ext',), ('build_clibs',), ('check',) ] ) self.assertIn(actual, expected) def test_sequencer_cycle(self): seq = Sequencer() seq.add('A', 'B') seq.add('B', 'C') seq.add('C', 'D') self.assertEqual(list(seq.get_steps('D')), ['A', 'B', 'C', 'D']) seq.add('C', 'A') self.assertEqual(list(seq.get_steps('D')), ['C', 'A', 'B', 'D']) self.assertFalse(seq.is_step('E')) self.assertRaises(ValueError, seq.get_steps, 'E') seq.add_node('E') self.assertTrue(seq.is_step('E')) self.assertEqual(list(seq.get_steps('E')), ['E']) seq.remove_node('E') self.assertFalse(seq.is_step('E')) self.assertRaises(ValueError, seq.get_steps, 'E') seq.remove('C', 'A') self.assertEqual(list(seq.get_steps('D')), ['A', 'B', 'C', 'D']) def test_sequencer_removal(self): seq = Sequencer() seq.add('A', 'B') seq.add('B', 'C') seq.add('C', 'D') preds = { 'B': set(['A']), 'C': set(['B']), 'D': set(['C']) } succs = { 'A': set(['B']), 'B': set(['C']), 'C': set(['D']) } self.assertEqual(seq._preds, preds) self.assertEqual(seq._succs, succs) seq.remove_node('C') self.assertEqual(seq._preds, preds) self.assertEqual(seq._succs, succs) seq.remove_node('C', True) self.assertEqual(seq._preds, {'B': set(['A'])}) self.assertEqual(seq._succs, {'A': set(['B'])}) def test_unarchive(self): import zipfile, tarfile good_archives = ( ('good.zip', zipfile.ZipFile, 'r', 'namelist'), ('good.tar', tarfile.open, 'r', 'getnames'), ('good.tar.gz', tarfile.open, 'r:gz', 'getnames'), ('good.tar.bz2', tarfile.open, 'r:bz2', 'getnames'), ) bad_archives = ('bad.zip', 'bad.tar', 'bad.tar.gz', 'bad.tar.bz2') for name, cls, mode, lister in good_archives: td = tempfile.mkdtemp() archive = None try: name = os.path.join(HERE, name) unarchive(name, td) archive = cls(name, mode) names = getattr(archive, lister)() for name in names: p = os.path.join(td, name) self.assertTrue(os.path.exists(p)) finally: shutil.rmtree(td) if archive: archive.close() for name in bad_archives: name = os.path.join(HERE, name) td = tempfile.mkdtemp() try: self.assertRaises(ValueError, unarchive, name, td) finally: shutil.rmtree(td) def test_string_sequence(self): self.assertTrue(is_string_sequence(['a'])) self.assertTrue(is_string_sequence(['a', 'b'])) self.assertFalse(is_string_sequence(['a', 'b', None])) self.assertRaises(AssertionError, is_string_sequence, []) @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_package_data(self): data = get_package_data(name='config', version='0.3.6') self.assertTrue(data) self.assertTrue('index-metadata' in data) metadata = data['index-metadata'] self.assertEqual(metadata['name'], 'config') self.assertEqual(metadata['version'], '0.3.6') data = get_package_data(name='config', version='0.3.5') self.assertFalse(data) def test_zip_dir(self): d = os.path.join(HERE, 'foofoo') data = zip_dir(d) self.assertIsInstance(data, BytesIO) def test_configurator(self): d = { 'a': 1, 'b': 2.0, 'c': 'xyz', 'd': 'inc://' + os.path.join(HERE, 'included.json'), 'e': 'inc://' + 'included.json', 'stderr': 'ext://sys.stderr', 'list_o_stuff': [ 'cfg://stderr', 'ext://sys.stdout', 'ext://logging.NOTSET', ], 'dict_o_stuff': { 'k1': 'cfg://list_o_stuff[1]', 'k2': 'abc', 'k3': 'cfg://list_o_stuff', }, 'another_dict_o_stuff': { 'k1': 'cfg://dict_o_stuff[k2]', 'k2': 'ext://re.I', 'k3': 'cfg://dict_o_stuff[k3][0]', }, 'custom': { '()': __name__ + '.TestContainer', '[]': [1, 'a', 2.0, ('b', 'c', 'd')], '.': { 'p1': 'a', 'p2': 'b', 'p3': { '()' : __name__ + '.TestContainer', '[]': [1, 2], '.': { 'p1': 'c', }, }, }, 'k1': 'v1', 'k2': 'v2', } } cfg = Configurator(d, HERE) self.assertEqual(cfg['a'], 1) self.assertEqual(cfg['b'], 2.0) self.assertEqual(cfg['c'], 'xyz') self.assertIs(cfg['stderr'], sys.stderr) self.assertIs(cfg['list_o_stuff'][0], sys.stderr) self.assertIs(cfg['list_o_stuff'][1], sys.stdout) self.assertIs(cfg['list_o_stuff'][-1], 0) # logging.NOTSET == 0 self.assertIs(cfg['dict_o_stuff']['k1'], sys.stdout) self.assertIs(cfg['another_dict_o_stuff']['k1'], 'abc') self.assertIs(cfg['another_dict_o_stuff']['k2'], re.I) self.assertIs(cfg['another_dict_o_stuff']['k3'], sys.stderr) custom = cfg['custom'] self.assertIsInstance(custom, TestContainer) self.assertEqual(custom.args, (1, 'a', 2.0, ('b', 'c', 'd'))) self.assertEqual(custom.kwargs, {'k1': 'v1', 'k2': 'v2'}) self.assertEqual(custom.p1, 'a') self.assertEqual(custom.p2, 'b') self.assertIsInstance(custom.p3, TestContainer) self.assertEqual(custom.p3.args, (1, 2)) self.assertEqual(custom.p3.kwargs, {}) self.assertEqual(custom.p3.p1, 'c') self.assertEqual(cfg['d'], {'foo': 'bar', 'bar': 'baz'}) self.assertEqual(cfg['e'], {'foo': 'bar', 'bar': 'baz'}) def _speed_range(min_speed, max_speed): return tuple(['%d KB/s' % v for v in range(min_speed, max_speed + 1)]) def _eta_range(min_eta, max_eta, prefix='ETA '): msg = prefix + ': 00:00:%02d' return tuple([msg % v for v in range(min_eta, max_eta + 1)]) class ProgressTestCase(unittest.TestCase): def test_basic(self): # These ranges may need tweaking to cater for especially slow # machines if os.name == 'nt': speed1 = _speed_range(18, 20) speed2 = _speed_range(20, 22) else: speed1 = _speed_range(16, 19) speed2 = _speed_range(20, 22) expected = ( (' 10 %', _eta_range(4, 7), speed1), (' 20 %', _eta_range(4, 7), speed1), (' 30 %', _eta_range(3, 4), speed1), (' 40 %', _eta_range(3, 3), speed1), (' 50 %', _eta_range(2, 2), speed1), (' 60 %', _eta_range(2, 2), speed1), (' 70 %', _eta_range(1, 1), speed1), (' 80 %', _eta_range(1, 1), speed1), (' 90 %', _eta_range(0, 0), speed1), ('100 %', _eta_range(4, 5, 'Done'), speed2), ) bar = Progress(maxval=100000).start() for i, v in enumerate(range(10000, 100000, 10000)): time.sleep(0.5) bar.update(v) p, e, s = expected[i] self.assertEqual(bar.percentage, p) self.assertIn(bar.ETA, e, p) self.assertIn(bar.speed, s) bar.stop() p, e, s = expected[i + 1] self.assertEqual(bar.percentage, p) self.assertIn(bar.ETA, e, p) self.assertIn(bar.speed, s) def test_unknown(self): if os.name == 'nt': speed = _speed_range(17, 20) else: speed = _speed_range(17, 19) expected = ( (' ?? %', 'ETA : ??:??:??', speed), (' ?? %', 'ETA : ??:??:??', speed), (' ?? %', 'ETA : ??:??:??', speed), (' ?? %', 'ETA : ??:??:??', speed), (' ?? %', 'ETA : ??:??:??', speed), (' ?? %', 'ETA : ??:??:??', speed), (' ?? %', 'ETA : ??:??:??', speed), (' ?? %', 'ETA : ??:??:??', speed), (' ?? %', 'ETA : ??:??:??', speed), ('100 %', 'Done: 00:00:04', speed), ) bar = Progress(maxval=None).start() for i, v in enumerate(range(10000, 100000, 10000)): time.sleep(0.5) bar.update(v) p, e, s = expected[i] self.assertEqual(bar.percentage, p) self.assertEqual(bar.ETA, e) self.assertIn(bar.speed, s) bar.stop() p, e, s = expected[i + 1] self.assertEqual(bar.percentage, p) self.assertEqual(bar.ETA, e) self.assertIn(bar.speed, s) class FileOpsTestCase(unittest.TestCase): def setUp(self): self.fileop = FileOperator() self.workdir = tempfile.mkdtemp() def tearDown(self): if os.path.isdir(self.workdir): shutil.rmtree(self.workdir) def test_ensure_dir(self): td = self.workdir os.rmdir(td) self.fileop.ensure_dir(td) self.assertTrue(os.path.exists(td)) self.fileop.dry_run = True os.rmdir(td) self.fileop.ensure_dir(td) self.assertFalse(os.path.exists(td)) def test_ensure_removed(self): td = self.workdir self.assertTrue(os.path.exists(td)) self.fileop.dry_run = True self.fileop.ensure_removed(td) self.assertTrue(os.path.exists(td)) self.fileop.dry_run = False self.fileop.ensure_removed(td) self.assertFalse(os.path.exists(td)) def test_is_writable(self): sd = 'subdir' ssd = 'subsubdir' path = os.path.join(self.workdir, sd, ssd) os.makedirs(path) path = os.path.join(path, 'test') self.assertTrue(self.fileop.is_writable(path)) if os.name == 'posix': self.assertFalse(self.fileop.is_writable('/etc')) def test_byte_compile(self): path = os.path.join(self.workdir, 'hello.py') dpath = cache_from_source(path, True) self.fileop.write_text_file(path, 'print("Hello, world!")', 'utf-8') self.fileop.byte_compile(path, optimize=False) self.assertTrue(os.path.exists(dpath)) def write_some_files(self): path = os.path.join(self.workdir, 'file1') written = [] self.fileop.write_text_file(path, 'test', 'utf-8') written.append(path) path = os.path.join(self.workdir, 'file2') self.fileop.copy_file(written[0], path) written.append(path) path = os.path.join(self.workdir, 'dir1') self.fileop.ensure_dir(path) return set(written), set([path]) def test_copy_check(self): srcpath = os.path.join(self.workdir, 'file1') self.fileop.write_text_file(srcpath, 'test', 'utf-8') dstpath = os.path.join(self.workdir, 'file2') os.mkdir(dstpath) self.assertRaises(ValueError, self.fileop.copy_file, srcpath, dstpath) os.rmdir(dstpath) if os.name == 'posix': # symlinks available linkpath = os.path.join(self.workdir, 'file3') self.fileop.write_text_file(linkpath, 'linkdest', 'utf-8') os.symlink(linkpath, dstpath) self.assertRaises(ValueError, self.fileop.copy_file, srcpath, dstpath) def test_commit(self): # will assert if record isn't set self.assertRaises(AssertionError, self.fileop.commit) self.fileop.record = True expected = self.write_some_files() actual = self.fileop.commit() self.assertEqual(actual, expected) self.assertFalse(self.fileop.record) def test_rollback(self): # will assert if record isn't set self.assertRaises(AssertionError, self.fileop.commit) self.fileop.record = True expected = self.write_some_files() actual = self.fileop.rollback() self.assertEqual(os.listdir(self.workdir), []) self.assertFalse(self.fileop.record) class GlobTestCaseBase(TempdirManager, unittest.TestCase): def build_files_tree(self, files): tempdir = self.mkdtemp() for filepath in files: is_dir = filepath.endswith('/') filepath = os.path.join(tempdir, *filepath.split('/')) if is_dir: dirname = filepath else: dirname = os.path.dirname(filepath) if dirname and not os.path.exists(dirname): os.makedirs(dirname) if not is_dir: self.write_file(filepath, 'babar') return tempdir @staticmethod def os_dependent_path(path): path = path.rstrip('/').split('/') return os.path.join(*path) def clean_tree(self, spec): files = [] for path, includes in spec.items(): if includes: files.append(self.os_dependent_path(path)) return sorted(files) class GlobTestCase(GlobTestCaseBase): def assertGlobMatch(self, glob, spec): tempdir = self.build_files_tree(spec) expected = self.clean_tree(spec) os.chdir(tempdir) result = sorted(iglob(glob)) self.assertEqual(expected, result) def test_regex_rich_glob(self): matches = RICH_GLOB.findall( r"babar aime les {fraises} est les {huitres}") self.assertEqual(["fraises", "huitres"], matches) def test_simple_glob(self): glob = '*.tp?' spec = {'coucou.tpl': True, 'coucou.tpj': True, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_simple_glob_in_dir(self): glob = os.path.join('babar', '*.tp?') spec = {'babar/coucou.tpl': True, 'babar/coucou.tpj': True, 'babar/toto.bin': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_recursive_glob_head(self): glob = os.path.join('**', 'tip', '*.t?l') spec = {'babar/zaza/zuzu/tip/coucou.tpl': True, 'babar/z/tip/coucou.tpl': True, 'babar/tip/coucou.tpl': True, 'babar/zeop/tip/babar/babar.tpl': False, 'babar/z/tip/coucou.bin': False, 'babar/toto.bin': False, 'zozo/zuzu/tip/babar.tpl': True, 'zozo/tip/babar.tpl': True, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_recursive_glob_tail(self): glob = os.path.join('babar', '**') spec = {'babar/zaza/': True, 'babar/zaza/zuzu/': True, 'babar/zaza/zuzu/babar.xml': True, 'babar/zaza/zuzu/toto.xml': True, 'babar/zaza/zuzu/toto.csv': True, 'babar/zaza/coucou.tpl': True, 'babar/bubu.tpl': True, 'zozo/zuzu/tip/babar.tpl': False, 'zozo/tip/babar.tpl': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_recursive_glob_middle(self): glob = os.path.join('babar', '**', 'tip', '*.t?l') spec = {'babar/zaza/zuzu/tip/coucou.tpl': True, 'babar/z/tip/coucou.tpl': True, 'babar/tip/coucou.tpl': True, 'babar/zeop/tip/babar/babar.tpl': False, 'babar/z/tip/coucou.bin': False, 'babar/toto.bin': False, 'zozo/zuzu/tip/babar.tpl': False, 'zozo/tip/babar.tpl': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_glob_set_tail(self): glob = os.path.join('bin', '*.{bin,sh,exe}') spec = {'bin/babar.bin': True, 'bin/zephir.sh': True, 'bin/celestine.exe': True, 'bin/cornelius.bat': False, 'bin/cornelius.xml': False, 'toto/yurg': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_glob_set_middle(self): glob = os.path.join('xml', '{babar,toto}.xml') spec = {'xml/babar.xml': True, 'xml/toto.xml': True, 'xml/babar.xslt': False, 'xml/cornelius.sgml': False, 'xml/zephir.xml': False, 'toto/yurg.xml': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_glob_set_head(self): glob = os.path.join('{xml,xslt}', 'babar.*') spec = {'xml/babar.xml': True, 'xml/toto.xml': False, 'xslt/babar.xslt': True, 'xslt/toto.xslt': False, 'toto/yurg.xml': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_glob_all(self): dirs = '{%s,%s}' % (os.path.join('xml', '*'), os.path.join('xslt', '**')) glob = os.path.join(dirs, 'babar.xml') spec = {'xml/a/babar.xml': True, 'xml/b/babar.xml': True, 'xml/a/c/babar.xml': False, 'xslt/a/babar.xml': True, 'xslt/b/babar.xml': True, 'xslt/a/c/babar.xml': True, 'toto/yurg.xml': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_invalid_glob_pattern(self): invalids = [ 'ppooa**', 'azzaeaz4**/', '/**ddsfs', '**##1e"&e', 'DSFb**c009', '{', '{aaQSDFa', '}', 'aQSDFSaa}', '{**a,', ',**a}', '{a**,', ',b**}', '{a**a,babar}', '{bob,b**z}', ] for pattern in invalids: self.assertRaises(ValueError, iglob, pattern) def test_parse_requirement(self): #Invalid requirements self.assertIsNone(parse_requirement('')) self.assertIsNone(parse_requirement('a (')) self.assertIsNone(parse_requirement('a/')) self.assertIsNone(parse_requirement('a$')) self.assertIsNone(parse_requirement('a ()')) self.assertIsNone(parse_requirement('a [')) self.assertIsNone(parse_requirement('a () []')) # Valid requirements def validate(r, values): self.assertEqual(r.name, values[0]) self.assertEqual(r.constraints, values[1]) self.assertEqual(r.extras, values[2]) self.assertEqual(r.requirement, values[3]) self.assertEqual(r.url, values[4]) r = parse_requirement('a') validate(r, ('a', None, None, 'a', None)) r = parse_requirement('a 1.2') validate(r, ('a', [('~=', '1.2')], None, 'a (~= 1.2)', None)) r = parse_requirement('a >= 1.2, <2.0,!=1.7') validate(r, ('a', [('>=', '1.2'), ('<', '2.0'), ('!=', '1.7')], None, 'a (>= 1.2, < 2.0, != 1.7)', None)) r = parse_requirement('a [ab,cd , ef] >= 1.2, <2.0') validate(r, ('a', [('>=', '1.2'), ('<', '2.0')], ['ab', 'cd', 'ef'], 'a (>= 1.2, < 2.0)', None)) r = parse_requirement('a[]') validate(r, ('a', None, None, 'a', None)) r = parse_requirement('a (== 1.2.*, != 1.2.1.*)') validate(r, ('a', [('==', '1.2.*'), ('!=', '1.2.1.*')], None, 'a (== 1.2.*, != 1.2.1.*)', None)) r = parse_requirement('a (from http://domain.com/path#abc=def )') validate(r, ('a', None, None, 'a', 'http://domain.com/path#abc=def')) for e in ('*', ':*:', ':meta:', '-', '-abc'): r = parse_requirement('a [%s]' % e) validate(r, ('a', None, [e], 'a', None)) def test_write_exports(self): exports = { 'foo': { 'v1': ExportEntry('v1', 'p1', 's1', []), 'v2': ExportEntry('v2', 'p2', 's2', ['f2=a', 'g2']), }, 'bar': { 'v3': ExportEntry('v3', 'p3', 's3', ['f3', 'g3=h']), 'v4': ExportEntry('v4', 'p4', 's4', ['f4', 'g4']), }, } fd, fn = tempfile.mkstemp() try: os.close(fd) with open(fn, 'wb') as f: write_exports(exports, f) with open(fn, 'rb') as f: actual = read_exports(f) self.assertEqual(actual, exports) finally: os.remove(fn) def test_get_extras(self): cases = ( (['*'], ['i18n'], set(['i18n'])), (['*', '-bar'], ['foo', 'bar'], set(['foo'])), ) for requested, available, expected in cases: actual = get_extras(requested, available) self.assertEqual(actual, expected) if __name__ == '__main__': # pragma: no cover unittest.main() distlib-0.2.2/tests/foo.zip0000664000000000000000000000157312027456516014334 0ustar rootrootPK N4Aԉ foo/foo_resource.binUT }[P}[Pux more_data PK B4Afoo/__init__.pyUT [P}[Pux # empty PK T4Actffoo/bar/baz.pyUT [P}[Pux # This is baz PK M4Afoo/bar/__init__.pyUT [P}[Pux # empty PK 54Afoo/bar/bar_resource.binUT }[P}[Pux data PK N4Aԉ foo/foo_resource.binUT}[Pux PK B4AXfoo/__init__.pyUT[Pux PK T4Actffoo/bar/baz.pyUT[Pux PK M4Afoo/bar/__init__.pyUT[Pux PK 54ATfoo/bar/bar_resource.binUT}[Pux PKdistlib-0.2.2/tests/fake_dists/0000775000000000000000000000000012656456062015137 5ustar rootrootdistlib-0.2.2/tests/fake_dists/towel_stuff-0.1/0000775000000000000000000000000012656456062017774 5ustar rootrootdistlib-0.2.2/tests/fake_dists/towel_stuff-0.1/towel_stuff/0000775000000000000000000000000012656456062022335 5ustar rootrootdistlib-0.2.2/tests/fake_dists/towel_stuff-0.1/towel_stuff/__init__.py0000664000000000000000000000074112027456516024444 0ustar rootroot# -*- coding: utf-8 -*- class Towel(object): """A towel, that one should never be without.""" def __init__(self, color='tie-dye'): self.color = color self.wrapped_obj = None def wrap(self, obj): """Wrap an object up in our towel.""" self.wrapped_obj = obj def unwrap(self): """Unwrap whatever is in our towel and return whatever it is.""" obj = self.wrapped_obj self.wrapped_obj = None return obj distlib-0.2.2/tests/fake_dists/banana-0.4.egg/0000775000000000000000000000000012656456062017417 5ustar rootrootdistlib-0.2.2/tests/fake_dists/banana-0.4.egg/EGG-INFO/0000775000000000000000000000000012656456062020552 5ustar rootrootdistlib-0.2.2/tests/fake_dists/banana-0.4.egg/EGG-INFO/PKG-INFO0000664000000000000000000000107012027456516021641 0ustar rootrootMetadata-Version: 1.0 Name: banana Version: 0.4 Summary: A yellow fruit Home-page: http://en.wikipedia.org/wiki/Banana Author: Josip Djolonga Author-email: foo@nbar.com License: BSD Description: A fruit Keywords: foo bar Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Scientific/Engineering :: GIS distlib-0.2.2/tests/fake_dists/banana-0.4.egg/EGG-INFO/not-zip-safe0000664000000000000000000000000112027456516022774 0ustar rootroot distlib-0.2.2/tests/fake_dists/banana-0.4.egg/EGG-INFO/top_level.txt0000664000000000000000000000000012027456516023266 0ustar rootrootdistlib-0.2.2/tests/fake_dists/banana-0.4.egg/EGG-INFO/requires.txt0000664000000000000000000000011012147254670023136 0ustar rootroot# this should be ignored strawberry >=0.5 [section ignored] foo ==0.5 distlib-0.2.2/tests/fake_dists/banana-0.4.egg/EGG-INFO/dependency_links.txt0000664000000000000000000000000112027456516024614 0ustar rootroot distlib-0.2.2/tests/fake_dists/banana-0.4.egg/EGG-INFO/SOURCES.txt0000664000000000000000000000000012027456516022420 0ustar rootrootdistlib-0.2.2/tests/fake_dists/banana-0.4.egg/EGG-INFO/entry_points.txt0000664000000000000000000000004512027456516024043 0ustar rootroot # -*- Entry points: -*- distlib-0.2.2/tests/fake_dists/strawberry-0.6.egg0000664000000000000000000000257212027456516020332 0ustar rootroot#!/bin/sh if [ `basename $0` = "setuptools-0.6c11-py2.3.egg" ] then exec python2.3 -c "import sys, os; sys.path.insert(0, os.path.abspath('$0')); from setuptools.command.easy_install import bootstrap; sys.exit(bootstrap())" "$@" else echo $0 is not the correct name for this egg file. echo Please rename it back to setuptools-0.6c11-py2.3.egg and try again. exec false fi PK v<EGG-INFO/top_level.txtUT LLux PK z<EGG-INFO/SOURCES.txtUT LLux PKFq<EGG-INFO/PKG-INFOUT $ L$ Lux =NN@ +IʅÞ@ ڪR%\ۘ!^=)R<43{SEsvJЫtfU1%96V7ZBqn'½P6FLB<֫Zu)As '!`/^*7.̋o g_& qפԿw+ϓZ?UL PK <EGG-INFO/entry_points.txtUT LLux PKPT;2EGG-INFO/dependency_links.txt PK v<zEGG-INFO/top_level.txtUTLux PK z<EGG-INFO/SOURCES.txtUTLux PKFq<EGG-INFO/PKG-INFOUT$ Lux PK <EGG-INFO/entry_points.txtUTLux PKPT;2qEGG-INFO/dependency_links.txtPKdistlib-0.2.2/tests/fake_dists/grammar-1.0a4/0000775000000000000000000000000012656456062017306 5ustar rootrootdistlib-0.2.2/tests/fake_dists/grammar-1.0a4/grammar/0000775000000000000000000000000012656456062020734 5ustar rootrootdistlib-0.2.2/tests/fake_dists/grammar-1.0a4/grammar/utils.py0000664000000000000000000000024212027456516022440 0ustar rootroot# -*- coding: utf-8 -*- from random import randint def is_valid_grammar(sentence): if randint(0, 10) < 2: return False else: return True distlib-0.2.2/tests/fake_dists/grammar-1.0a4/grammar/__init__.py0000664000000000000000000000003012027456516023032 0ustar rootroot# -*- coding: utf-8 -*- distlib-0.2.2/tests/fake_dists/truffles-5.0.egg-info0000664000000000000000000000006212027456516020700 0ustar rootrootMetadata-Version: 1.2 Name: truffles Version: 5.0 distlib-0.2.2/tests/fake_dists/grammar-1.0a4.dist-info/0000775000000000000000000000000012656456062021201 5ustar rootrootdistlib-0.2.2/tests/fake_dists/grammar-1.0a4.dist-info/INSTALLER0000664000000000000000000000000012027456516022443 0ustar rootrootdistlib-0.2.2/tests/fake_dists/grammar-1.0a4.dist-info/RECORD0000664000000000000000000000000012027456516022064 0ustar rootrootdistlib-0.2.2/tests/fake_dists/grammar-1.0a4.dist-info/REQUESTED0000664000000000000000000000000012027456516022447 0ustar rootrootdistlib-0.2.2/tests/fake_dists/grammar-1.0a4.dist-info/METADATA0000664000000000000000000000015312027456516022277 0ustar rootrootMetadata-Version: 1.2 Name: grammar Version: 1.0a4 Requires-Dist: truffles (>=1.2) Author: Sherlock Holmes distlib-0.2.2/tests/fake_dists/grammar-1.0a4.dist-info/pydist.json0000664000000000000000000000050312445642006023375 0ustar rootroot{ "generator": "distlib (0.1.3.dev0)", "run_requires": [ { "requires": [ "truffles (>=1.2)" ] } ], "metadata_version": "2.0", "version": "1.0a4", "provides": [ "grammar (1.0a4)" ], "extensions": { "python.details": { "keywords": [] } }, "name": "grammar" } distlib-0.2.2/tests/fake_dists/towel_stuff-0.1.dist-info/0000775000000000000000000000000012656456062021667 5ustar rootrootdistlib-0.2.2/tests/fake_dists/towel_stuff-0.1.dist-info/INSTALLER0000664000000000000000000000000012027456516023131 0ustar rootrootdistlib-0.2.2/tests/fake_dists/towel_stuff-0.1.dist-info/pydist-exports.json0000664000000000000000000000055512445642006025574 0ustar rootroot{ "metadata_version": "2.0", "generator": "distlib (0.1.3.dev0)", "name": "towel-stuff", "extensions": { "python.exports": { "exports": { "foo": { "bar": "towel:towel", "baz": "towel:beach_towel" }, "bar.baz": { "foobar": "hoopy:frood [dent]" } } } }, "version": "0.1" } distlib-0.2.2/tests/fake_dists/towel_stuff-0.1.dist-info/RECORD0000664000000000000000000000000012027456516022552 0ustar rootrootdistlib-0.2.2/tests/fake_dists/towel_stuff-0.1.dist-info/REQUESTED0000664000000000000000000000000012027456516023135 0ustar rootrootdistlib-0.2.2/tests/fake_dists/towel_stuff-0.1.dist-info/METADATA0000664000000000000000000000027112163330134022752 0ustar rootrootMetadata-Version: 1.2 Name: towel-stuff Version: 0.1 Provides-Dist: truffles (1.1.2) Provides-Dist: towel-stuff (0.1) Obsoletes-Dist: truffles (!=0.8,<1.0) Requires-Dist: bacon (<=0.2) distlib-0.2.2/tests/fake_dists/towel_stuff-0.1.dist-info/pydist.json0000664000000000000000000000053412445642006024067 0ustar rootroot{ "generator": "distlib (0.1.3.dev0)", "run_requires": [ { "requires": [ "bacon (<=0.2)" ] } ], "metadata_version": "2.0", "version": "0.1", "provides": [ "truffles (1.1.2)", "towel-stuff (0.1)" ], "extensions": { "python-details": { "keywords": [] } }, "name": "towel-stuff" } distlib-0.2.2/tests/fake_dists/bacon-0.1.egg-info/0000775000000000000000000000000012656456062020207 5ustar rootrootdistlib-0.2.2/tests/fake_dists/bacon-0.1.egg-info/PKG-INFO0000664000000000000000000000021712027456516021300 0ustar rootrootMetadata-Version: 1.2 Name: bacon Version: 0.1 Provides-Dist: truffles (2.0) Provides-Dist: bacon (0.1) Obsoletes-Dist: truffles (>=0.9,<=1.5) distlib-0.2.2/tests/fake_dists/bacon-0.1.egg-info/installed-files.txt0000664000000000000000000000012412045563526024020 0ustar rootroot../dummy.py ../dummy.pyc ./ PKG-INFO SOURCES.txt top_level.txt dependency_links.txt distlib-0.2.2/tests/fake_dists/nut-funkyversion.egg-info0000664000000000000000000000006612027456516022120 0ustar rootrootMetadata-Version: 1.2 Name: nut Version: funkyversion distlib-0.2.2/tests/fake_dists/coconuts-aster-10.3.egg-info/0000775000000000000000000000000012656456062022161 5ustar rootrootdistlib-0.2.2/tests/fake_dists/coconuts-aster-10.3.egg-info/PKG-INFO0000664000000000000000000000016512027456516023254 0ustar rootrootMetadata-Version: 1.2 Name: coconuts-aster Version: 10.3 Provides-Dist: strawberry (0.6) Provides-Dist: banana (0.4) distlib-0.2.2/tests/fake_dists/babar-0.1.dist-info/0000775000000000000000000000000012656456062020375 5ustar rootrootdistlib-0.2.2/tests/fake_dists/babar-0.1.dist-info/INSTALLER0000664000000000000000000000000012027456516021637 0ustar rootrootdistlib-0.2.2/tests/fake_dists/babar-0.1.dist-info/pydist-exports.json0000664000000000000000000000055712445642006024304 0ustar rootroot{ "metadata_version": "2.0", "generator": "distlib (0.1.3.dev0)", "name": "babar", "extensions": { "python.exports": { "exports": { "foo": { "bar": "baz:barbaz [a=10, b]" }, "bar.baz": { "foofoo": "baz.foo:bazbar", "real": "cgi:print_directory" } } } }, "version": "0.1" } distlib-0.2.2/tests/fake_dists/babar-0.1.dist-info/RECORD0000664000000000000000000000000012027456516021260 0ustar rootrootdistlib-0.2.2/tests/fake_dists/babar-0.1.dist-info/RESOURCES0000664000000000000000000000004712027456516021667 0ustar rootrootbabar.png,babar.png babar.cfg,babar.cfgdistlib-0.2.2/tests/fake_dists/babar-0.1.dist-info/REQUESTED0000664000000000000000000000000012027456516021643 0ustar rootrootdistlib-0.2.2/tests/fake_dists/babar-0.1.dist-info/METADATA0000664000000000000000000000010112027456516021464 0ustar rootrootMetadata-version: 1.2 Name: babar Version: 0.1 Author: FELD Borisdistlib-0.2.2/tests/fake_dists/babar-0.1.dist-info/pydist.json0000664000000000000000000000033712445642006022576 0ustar rootroot{ "metadata_version": "2.0", "generator": "distlib (0.1.3.dev0)", "version": "0.1", "provides": [ "babar (0.1)" ], "extensions": { "python.details": { "keywords": [] } }, "name": "babar" } distlib-0.2.2/tests/fake_dists/choxie-2.0.0.9/0000775000000000000000000000000012656456062017220 5ustar rootrootdistlib-0.2.2/tests/fake_dists/choxie-2.0.0.9/choxie/0000775000000000000000000000000012656456062020477 5ustar rootrootdistlib-0.2.2/tests/fake_dists/choxie-2.0.0.9/choxie/chocolate.py0000664000000000000000000000032612027456516023007 0ustar rootroot# -*- coding: utf-8 -*- from towel_stuff import Towel class Chocolate(object): """A piece of chocolate.""" def wrap_with_towel(self): towel = Towel() towel.wrap(self) return towel distlib-0.2.2/tests/fake_dists/choxie-2.0.0.9/choxie/__init__.py0000664000000000000000000000003012027456516022575 0ustar rootroot# -*- coding: utf-8 -*- distlib-0.2.2/tests/fake_dists/choxie-2.0.0.9/truffles.py0000664000000000000000000000015712027456516021423 0ustar rootroot# -*- coding: utf-8 -*- from choxie.chocolate import Chocolate class Truffle(Chocolate): """A truffle.""" distlib-0.2.2/tests/fake_dists/babar.png0000664000000000000000000000000012027456516016676 0ustar rootrootdistlib-0.2.2/tests/fake_dists/cheese-2.0.2.egg-info0000664000000000000000000000017112027456516020440 0ustar rootrootMetadata-Version: 1.2 Name: cheese Version: 2.0.2 Provides-Dist: truffles (1.0.2) Obsoletes-Dist: truffles (!=1.2,<=2.0) distlib-0.2.2/tests/fake_dists/choxie-2.0.0.9.dist-info/0000775000000000000000000000000012656456062021113 5ustar rootrootdistlib-0.2.2/tests/fake_dists/choxie-2.0.0.9.dist-info/INSTALLER0000664000000000000000000000000012027456516022355 0ustar rootrootdistlib-0.2.2/tests/fake_dists/choxie-2.0.0.9.dist-info/pydist-exports.json0000664000000000000000000000047712445642006025023 0ustar rootroot{ "metadata_version": "2.0", "generator": "distlib (0.1.3.dev0)", "name": "choxie", "extensions": { "python.exports": { "exports": { "foo": { "bar": "crunchie" }, "bar.baz": { "foofoo": "ferrero:rocher" } } } }, "version": "2.0.0.9" } distlib-0.2.2/tests/fake_dists/choxie-2.0.0.9.dist-info/RECORD0000664000000000000000000000000012027456516021776 0ustar rootrootdistlib-0.2.2/tests/fake_dists/choxie-2.0.0.9.dist-info/REQUESTED0000664000000000000000000000000012027456516022361 0ustar rootrootdistlib-0.2.2/tests/fake_dists/choxie-2.0.0.9.dist-info/METADATA0000664000000000000000000000045412160413550022202 0ustar rootrootMetadata-Version: 1.2 Name: choxie Version: 2.0.0.9 Summary: Chocolate with a kick! Description: Chocolate with a longer kick! Requires-Dist: towel-stuff (0.1) Requires-Dist: nut Provides-Dist: truffles (1.0) Obsoletes-Dist: truffles (<=0.8,>=0.5) Obsoletes-Dist: truffles (<=0.9,>=0.6) License: BSD distlib-0.2.2/tests/fake_dists/choxie-2.0.0.9.dist-info/pydist.json0000664000000000000000000000073412445642006023315 0ustar rootroot{ "run_requires": [ { "requires": [ "towel-stuff (0.1)", "nut" ] } ], "generator": "distlib (0.1.3.dev0)", "extensions": { "python.details": { "keywords": [], "license": "BSD" } }, "description": "Chocolate with a longer kick!", "summary": "Chocolate with a kick!", "metadata_version": "2.0", "version": "2.0.0.9", "provides": [ "truffles (1.0)", "choxie (2.0.0.9)" ], "name": "choxie" } distlib-0.2.2/tests/fake_dists/babar.cfg0000664000000000000000000000000612027456516016657 0ustar rootrootConfigdistlib-0.2.2/tests/minimext-0.1-cp33-cp33m-linux_x86_64.whl0000664000000000000000000001752212137475420021531 0ustar rootrootPKTeB]D minimext.soTQZV2Ļ|.,%*ɮI;Y^Ȳ%3.)Y^F+% ːWjg#dMkΟ?P՞n~/솩_{Xp:<qj|Ox۞{O2^mϫ?&eBhzn(x~EGȟ3F;ppGo,c^{ p~X&tJ9 _鉦$)0YSӈOMuCM0VÉnhkviaD0t #s%ۣuޕ$t@hsDls8CdjIMצcf/$x$c PQ5M01 a"R1}y00D;H~LseHm 7_!MG3>/!~%rJKM:]/ 3xoHsY_k |PTT E3j^ }~5C ^l:{fi~@]qEta#l>RצK/tmE-1+,jC_D)FAqpv o-t}wmҶOi+sh~|ho ΀*g_Uם讚v$s K׵\f) :irKW6-0૮!I|^ӭMk m. Uз/ ?؍?5'3b ɥ&| } 4`/{trX695Wrb_x\\/qbe L,D4\Sh4L=kB:}Eדc~D% q7 (#b‹@hN2\q!?_ehO} -ڛܫUrϔ͈X~Z =x?>>>?^*Ke" P7. <'^.4UҧR흆>Ke7 };.R9YX n9 \mOj^%Ͳ宋Ī}yK‰`3ڥj߮MK>^ٳyUZ`ݦH.e;+.5̿<Ǒ DD NE$nEO; RĝgquMPu3XPcvy{#KqO H0.@'<$Xnzj%d=%XjP$ 6Qd 6 3Eͬf w;Y '(-W(y6a6wY{ewQD$hzpmCBOKWß lxՙi((;'9!.GKM.#0ؾFP%eGQP:n{17k=OK|8O /p'| g Dwa`XT``*x2Rj?b]VҳG'l FGQ?A]lҔ#`HZ|݁Dh"(5`R3zRİ4{KE>C.vR!)u,]" Cp=Z!r'w3C@:Rn.x*E@>^G"XW/ 5~*z4\)"OHKe6hc*e^)#qtvۓ4"@8]#LF+]Ct;Pq'gF4/o?M2?Mʖn_ Q֍H9aMT!6eG|t.vڳ>h~迋]z3迋q17ʿ?bFtMJ_G]l7=.IoϡW '"}z!b^(#n}TLvRl'o :1w_-Cg}GdנEl;*Y_ߕ8O2HEqP}O@;WzJj1Hp10ϲ=L""Pf+ӏs'w=i#&.4_rX"= >r)*+&9\բR9n|58E=*,51s (C޿ w3z]@AIR_c$yT8\%&O'o By O1J&tz'aRKgyFM2.I'ѕ^Se)r[u*D6i|V0NuFj`ggk JH"X^cXOۀel[HU$4./bZhغ[⭸×gx*k2A^AU,q;W JK έDJ" bήDecf2 .c`ʼnB?)T}ҖyWE.@ԲzW Ja5HJ-}K0Ʈ*5&WWY|I+eJy{%,A9><:Lě˹Cr[_ ƱyU"+6G,XM1.^h+P/2|v&) Zg oP:*yrFq(YA 0ޅ=`ykA_y+.䎦|| |U>ìe|Xd"w"gHgE <#~w-AΗ@h|ޅBS﫨i*=b-%im[|W&{6/chwtex':Sy"N_|Pǥ=@09I<dS@us^A="@>5Hk%2.MQ? 1a-eHr L- N)9ꉇmC 앳6tfe[aP_r/޸R:{?>NOtyO#s>>L[=r`"dν؛q9z5I7V!rDW JlCc q?^ ?|WA;*ޯWAF VS&U r0D p}H諴T!aՈNګ?*Q4/cxzi` 奎CllVScN k3%C0 g*R걨\t 汼Th?}6c*]->\g(nhؒ3'@$.b믄_~ tRO3v=j+O#=h}Sָx~"Ix*tA+iHt42fo:((I׼(i@F7x.JU dYY$I 11݈fm$I!ڥkW mß~3 ]fz~tmq +RԳݹThZ[3I*SD8kF.bfQh5<ݢe,Ѣx$ÆwuzF=l.j(;NgX|Wkf{Z_лH -N-q&:s[rXd⩞| Z>(4 4 >F>p P9~ PV%s 3I @:~x@6z9?ȍݸ0z@WYi BbWMz6HǤiptG.#&4È!Ph.EӉ\8!@ϣrCt")ub۲gw1mI)p/=rOLɂܙplt *6GX01| ar DC+HxHģ:Q2*ʬAn:>ASѰ U5D3rWї'ED[RqSd= i~Ш4%*>(ı|Q212,[~H;70c!N,Ubj8b>@ѡ#\!gV*OusnyUW8P_asaWܐ t:ݐq(gb~5DP, weU{J%O%="DSβxjg.G+NH "P0L? B4,FMRzJ&V)x9{b& \/P]a(@8D`6YICߙS8vȓ)"?lQW|$D,eX"2NifGZ 8Vc<8#(ŤG8`<,Ȅm _}Pj<M'30FjTçd[)[W fRY^X84 o S'Vʷqb^Si,bx>]dYV"j(byW'00PK 1QkFF9jq+%:]i2zt"uJ 9aMTp.7 1O*s)W,yUr\(N@9 (ZyEQU-6V7`r}*L8A /\@V` e%=^e}LK󸀪Wq~iTt^_ O򸢇 gJ6 '@ ,UXd}4oA1,.Um/EB@fVJznLB<>?#U(6NQB-2 QP2 xPL\B|(Cz/laQzcLG}"vOG^{ѿg'0u͚֮]Ei-bi'9¹~B4l~g\֪ -kWZQ >?G-x7PQHkT,mŵZֶmu-U6ҺZwԬ/;>ʗ2G|oh2O47~oSPKTeB)G!minimext-0.1.dist-info/EXTENSIONSRPPM(QBjPKTeB`'4minimext-0.1.dist-info/METADATAm0}P"p0GA&ŶU!fKv&G-8g4xY#.Iħcl4H fxA&X1Ի]iq,iԦg-Qp9wfJnvs _h$ѣ4-~PV$dݼo->i9F=/PKTeBײlabdminimext-0.1.dist-info/WHEEL HM K-*ϳR03rOK-J,/RH,.LR033KI-3 /, (-JJY)%r$[)$낈\ݜ̼Ҋ x3PKTeBh>\hminimext-0.1.dist-info/RECORDuIv0нg 4HAXt&[5ȴ!DHwS^(,šC,CoH4_)m{>R%TMG8;i.k PČ@yѼٺmɄC=vVNDmYޛ;=iYzg 3fwĜ¾U4.Yd*wad>e70g3Ehs-=:_"l@@yXPKTeB]D minimext.soPKTeB)G!minimext-0.1.dist-info/EXTENSIONSPKTeB`'4minimext-0.1.dist-info/METADATAPKTeBײlabdminimext-0.1.dist-info/WHEELPKTeBh>\hminimext-0.1.dist-info/RECORDPKjdistlib-0.2.2/tests/good.tar0000664000000000000000000002400012056755442014455 0ustar rootrootfile1.txt0000664000175000017500000000000012056711465011654 0ustar vinayvinaysubdir/0000775000175000017500000000000012056711513011407 5ustar vinayvinaysubdir/subsubdir/0000775000175000017500000000000012056711527013416 5ustar vinayvinaysubdir/subsubdir/file3.txt0000664000175000017500000000000012056711527015147 0ustar vinayvinaysubdir/file2.txt0000664000175000017500000000000012056711504013137 0ustar vinayvinaydistlib-0.2.2/tests/test_shutil.py0000664000000000000000000010645012112513136015731 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # try: import bz2 BZ2_SUPPORTED = True except ImportError: BZ2_SUPPORTED = False from distutils.spawn import find_executable, spawn from functools import wraps import os from os.path import splitdrive import stat import sys import tempfile from compat import unittest from distlib._backport import shutil, tarfile from distlib._backport.shutil import ( _make_tarball, _make_zipfile, make_archive, unpack_archive, register_archive_format, unregister_archive_format, get_archive_formats, register_unpack_format, unregister_unpack_format, get_unpack_formats, Error, RegistryError) from distlib.compat import StringIO import support try: import grp import pwd UID_GID_SUPPORT = True except ImportError: UID_GID_SUPPORT = False try: import zlib except ImportError: zlib = None try: import zipfile ZIP_SUPPORT = True except ImportError: ZIP_SUPPORT = find_executable('zip') def _fake_rename(*args, **kwargs): # Pretend the destination path is on a different filesystem. raise OSError() def mock_rename(func): @wraps(func) def wrap(*args, **kwargs): try: builtin_rename = os.rename os.rename = _fake_rename return func(*args, **kwargs) finally: os.rename = builtin_rename return wrap class TestShutil(unittest.TestCase): def setUp(self): super(TestShutil, self).setUp() self.tempdirs = [] self.TESTFN = '%s-%d' % (self.mkdtemp(), os.getpid()) self.TESTFN2 = '%s-2' % self.TESTFN def tearDown(self): super(TestShutil, self).tearDown() while self.tempdirs: d = self.tempdirs.pop() shutil.rmtree(d, os.name in ('nt', 'cygwin')) def write_file(self, path, content='xxx'): """Writes a file in the given path. path can be a string or a sequence. """ if isinstance(path, (list, tuple)): path = os.path.join(*path) f = open(path, 'w') try: f.write(content) finally: f.close() def mkdtemp(self): """Create a temporary directory that will be cleaned up. Returns the path of the directory. """ d = tempfile.mkdtemp() self.tempdirs.append(d) return d def test_rmtree_errors(self): # filename is guaranteed not to exist filename = tempfile.mktemp() self.assertRaises(OSError, shutil.rmtree, filename) # See bug #1071513 for why we don't run this on cygwin # and bug #1076467 for why we don't run this as root. if (hasattr(os, 'chmod') and sys.platform[:6] != 'cygwin' and not (hasattr(os, 'geteuid') and os.geteuid() == 0)): def test_on_error(self): self.errorState = 0 TESTFN = self.TESTFN os.mkdir(TESTFN) self.childpath = os.path.join(TESTFN, 'a') f = open(self.childpath, 'w') f.close() old_dir_mode = os.stat(TESTFN).st_mode old_child_mode = os.stat(self.childpath).st_mode # Make unwritable. os.chmod(self.childpath, stat.S_IREAD) os.chmod(TESTFN, stat.S_IREAD) shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror) # Test whether onerror has actually been called. self.assertEqual(self.errorState, 2, "Expected call to onerror function did not happen.") # Make writable again. os.chmod(TESTFN, old_dir_mode) os.chmod(self.childpath, old_child_mode) # Clean up. shutil.rmtree(TESTFN) def check_args_to_onerror(self, func, arg, exc): # test_rmtree_errors deliberately runs rmtree # on a directory that is chmod 400, which will fail. # This function is run when shutil.rmtree fails. # 99.9% of the time it initially fails to remove # a file in the directory, so the first time through # func is os.remove. # However, some Linux machines running ZFS on # FUSE experienced a failure earlier in the process # at os.listdir. The first failure may legally # be either. TESTFN = self.TESTFN if self.errorState == 0: if func is os.remove: self.assertEqual(arg, self.childpath) else: self.assertIs(func, os.listdir, "func must be either os.remove or os.listdir") self.assertEqual(arg, TESTFN) self.assertTrue(issubclass(exc[0], OSError)) self.errorState = 1 else: self.assertEqual(func, os.rmdir) self.assertEqual(arg, TESTFN) self.assertTrue(issubclass(exc[0], OSError)) self.errorState = 2 def test_rmtree_dont_delete_file(self): # When called on a file instead of a directory, don't delete it. handle, path = tempfile.mkstemp() os.fdopen(handle).close() self.assertRaises(OSError, shutil.rmtree, path) os.remove(path) def _write_data(self, path, data): f = open(path, "w") f.write(data) f.close() def test_copytree_simple(self): def read_data(path): f = open(path) data = f.read() f.close() return data src_dir = tempfile.mkdtemp() dst_dir = os.path.join(tempfile.mkdtemp(), 'destination') self._write_data(os.path.join(src_dir, 'test.txt'), '123') os.mkdir(os.path.join(src_dir, 'test_dir')) self._write_data(os.path.join(src_dir, 'test_dir', 'test.txt'), '456') try: shutil.copytree(src_dir, dst_dir) self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test.txt'))) self.assertTrue(os.path.isdir(os.path.join(dst_dir, 'test_dir'))) self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test_dir', 'test.txt'))) actual = read_data(os.path.join(dst_dir, 'test.txt')) self.assertEqual(actual, '123') actual = read_data(os.path.join(dst_dir, 'test_dir', 'test.txt')) self.assertEqual(actual, '456') finally: for path in ( os.path.join(src_dir, 'test.txt'), os.path.join(dst_dir, 'test.txt'), os.path.join(src_dir, 'test_dir', 'test.txt'), os.path.join(dst_dir, 'test_dir', 'test.txt'), ): if os.path.exists(path): os.remove(path) for path in (src_dir, os.path.dirname(dst_dir) ): if os.path.exists(path): shutil.rmtree(path) def test_copytree_with_exclude(self): def read_data(path): f = open(path) data = f.read() f.close() return data # creating data join = os.path.join exists = os.path.exists src_dir = tempfile.mkdtemp() try: dst_dir = join(tempfile.mkdtemp(), 'destination') self._write_data(join(src_dir, 'test.txt'), '123') self._write_data(join(src_dir, 'test.tmp'), '123') os.mkdir(join(src_dir, 'test_dir')) self._write_data(join(src_dir, 'test_dir', 'test.txt'), '456') os.mkdir(join(src_dir, 'test_dir2')) self._write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') os.mkdir(join(src_dir, 'test_dir2', 'subdir')) os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) self._write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') self._write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') # testing glob-like patterns try: patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') shutil.copytree(src_dir, dst_dir, ignore=patterns) # checking the result: some elements should not be copied self.assertTrue(exists(join(dst_dir, 'test.txt'))) self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) self.assertTrue(not exists(join(dst_dir, 'test_dir2'))) finally: if os.path.exists(dst_dir): shutil.rmtree(dst_dir) try: patterns = shutil.ignore_patterns('*.tmp', 'subdir*') shutil.copytree(src_dir, dst_dir, ignore=patterns) # checking the result: some elements should not be copied self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) finally: if os.path.exists(dst_dir): shutil.rmtree(dst_dir) # testing callable-style try: def _filter(src, names): res = [] for name in names: path = os.path.join(src, name) if (os.path.isdir(path) and path.split()[-1] == 'subdir'): res.append(name) elif os.path.splitext(path)[-1] in ('.py'): res.append(name) return res shutil.copytree(src_dir, dst_dir, ignore=_filter) # checking the result: some elements should not be copied self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2', 'test.py'))) self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) finally: if os.path.exists(dst_dir): shutil.rmtree(dst_dir) finally: shutil.rmtree(src_dir) shutil.rmtree(os.path.dirname(dst_dir)) @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') def test_dont_copy_file_onto_link_to_itself(self): # Temporarily disable test on Windows. if os.name == 'nt': return # bug 851123. TESTFN = self.TESTFN os.mkdir(TESTFN) src = os.path.join(TESTFN, 'cheese') dst = os.path.join(TESTFN, 'shop') try: f = open(src, 'w') try: f.write('cheddar') finally: f.close() os.link(src, dst) self.assertRaises(shutil.Error, shutil.copyfile, src, dst) f = open(src, 'r') try: self.assertEqual(f.read(), 'cheddar') finally: f.close() os.remove(dst) finally: shutil.rmtree(TESTFN, ignore_errors=True) @support.skip_unless_symlink def test_dont_copy_file_onto_symlink_to_itself(self): # bug 851123. TESTFN = self.TESTFN os.mkdir(TESTFN) src = os.path.join(TESTFN, 'cheese') dst = os.path.join(TESTFN, 'shop') try: f = open(src, 'w') try: f.write('cheddar') finally: f.close() # Using `src` here would mean we end up with a symlink pointing # to TESTFN/TESTFN/cheese, while it should point at # TESTFN/cheese. os.symlink('cheese', dst) self.assertRaises(shutil.Error, shutil.copyfile, src, dst) f = open(src, 'r') try: self.assertEqual(f.read(), 'cheddar') finally: f.close() os.remove(dst) finally: shutil.rmtree(TESTFN, ignore_errors=True) @support.skip_unless_symlink def test_rmtree_on_symlink(self): # bug 1669. TESTFN = self.TESTFN os.mkdir(TESTFN) try: src = os.path.join(TESTFN, 'cheese') dst = os.path.join(TESTFN, 'shop') os.mkdir(src) os.symlink(src, dst) self.assertRaises(OSError, shutil.rmtree, dst) finally: shutil.rmtree(TESTFN, ignore_errors=True) if hasattr(os, "mkfifo"): # Issue #3002: copyfile and copytree block indefinitely on named pipes def test_copyfile_named_pipe(self): TESTFN = self.TESTFN TESTFN2 = self.TESTFN2 os.mkfifo(TESTFN) try: self.assertRaises(shutil.SpecialFileError, shutil.copyfile, TESTFN, TESTFN2) self.assertRaises(shutil.SpecialFileError, shutil.copyfile, __file__, TESTFN) finally: os.remove(TESTFN) @support.skip_unless_symlink def test_copytree_named_pipe(self): TESTFN = self.TESTFN TESTFN2 = self.TESTFN2 os.mkdir(TESTFN) try: subdir = os.path.join(TESTFN, "subdir") os.mkdir(subdir) pipe = os.path.join(subdir, "mypipe") os.mkfifo(pipe) try: shutil.copytree(TESTFN, TESTFN2) except shutil.Error as e: errors = e.args[0] self.assertEqual(len(errors), 1) src, dst, error_msg = errors[0] self.assertEqual("`%s` is a named pipe" % pipe, error_msg) else: self.fail("shutil.Error should have been raised") finally: shutil.rmtree(TESTFN, ignore_errors=True) shutil.rmtree(TESTFN2, ignore_errors=True) def test_copytree_special_func(self): src_dir = self.mkdtemp() dst_dir = os.path.join(self.mkdtemp(), 'destination') self._write_data(os.path.join(src_dir, 'test.txt'), '123') os.mkdir(os.path.join(src_dir, 'test_dir')) self._write_data(os.path.join(src_dir, 'test_dir', 'test.txt'), '456') copied = [] def _copy(src, dst): copied.append((src, dst)) shutil.copytree(src_dir, dst_dir, copy_function=_copy) self.assertEqual(len(copied), 2) @support.skip_unless_symlink def test_copytree_dangling_symlinks(self): # a dangling symlink raises an error at the end src_dir = self.mkdtemp() dst_dir = os.path.join(self.mkdtemp(), 'destination') os.symlink('IDONTEXIST', os.path.join(src_dir, 'test.txt')) os.mkdir(os.path.join(src_dir, 'test_dir')) self._write_data(os.path.join(src_dir, 'test_dir', 'test.txt'), '456') self.assertRaises(Error, shutil.copytree, src_dir, dst_dir) # a dangling symlink is ignored with the proper flag dst_dir = os.path.join(self.mkdtemp(), 'destination2') shutil.copytree(src_dir, dst_dir, ignore_dangling_symlinks=True) self.assertNotIn('test.txt', os.listdir(dst_dir)) # a dangling symlink is copied if symlinks=True dst_dir = os.path.join(self.mkdtemp(), 'destination3') shutil.copytree(src_dir, dst_dir, symlinks=True) self.assertIn('test.txt', os.listdir(dst_dir)) def _copy_file(self, method): fname = 'test.txt' tmpdir = self.mkdtemp() self.write_file([tmpdir, fname]) file1 = os.path.join(tmpdir, fname) tmpdir2 = self.mkdtemp() method(file1, tmpdir2) file2 = os.path.join(tmpdir2, fname) return (file1, file2) @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod') def test_copy(self): # Ensure that the copied file exists and has the same mode bits. file1, file2 = self._copy_file(shutil.copy) self.assertTrue(os.path.exists(file2)) self.assertEqual(os.stat(file1).st_mode, os.stat(file2).st_mode) @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod') @unittest.skipUnless(hasattr(os, 'utime'), 'requires os.utime') def test_copy2(self): # Ensure that the copied file exists and has the same mode and # modification time bits. file1, file2 = self._copy_file(shutil.copy2) self.assertTrue(os.path.exists(file2)) file1_stat = os.stat(file1) file2_stat = os.stat(file2) self.assertEqual(file1_stat.st_mode, file2_stat.st_mode) for attr in 'st_atime', 'st_mtime': # The modification times may be truncated in the new file. self.assertLessEqual(getattr(file1_stat, attr), getattr(file2_stat, attr) + 1) if hasattr(os, 'chflags') and hasattr(file1_stat, 'st_flags'): self.assertEqual(getattr(file1_stat, 'st_flags'), getattr(file2_stat, 'st_flags')) @unittest.skipUnless(zlib, "requires zlib") def test_make_tarball(self): # creating something to tar tmpdir = self.mkdtemp() self.write_file([tmpdir, 'file1'], 'xxx') self.write_file([tmpdir, 'file2'], 'xxx') os.mkdir(os.path.join(tmpdir, 'sub')) self.write_file([tmpdir, 'sub', 'file3'], 'xxx') tmpdir2 = self.mkdtemp() # force shutil to create the directory os.rmdir(tmpdir2) unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0], "source and target should be on same drive") base_name = os.path.join(tmpdir2, 'archive') # working with relative paths to avoid tar warnings old_dir = os.getcwd() os.chdir(tmpdir) try: _make_tarball(splitdrive(base_name)[1], '.') finally: os.chdir(old_dir) # check if the compressed tarball was created tarball = base_name + '.tar.gz' self.assertTrue(os.path.exists(tarball)) # trying an uncompressed one base_name = os.path.join(tmpdir2, 'archive') old_dir = os.getcwd() os.chdir(tmpdir) try: _make_tarball(splitdrive(base_name)[1], '.', compress=None) finally: os.chdir(old_dir) tarball = base_name + '.tar' self.assertTrue(os.path.exists(tarball)) def _tarinfo(self, path): tar = tarfile.open(path) try: names = tar.getnames() names.sort() return tuple(names) finally: tar.close() def _create_files(self): # creating something to tar tmpdir = self.mkdtemp() dist = os.path.join(tmpdir, 'dist') os.mkdir(dist) self.write_file([dist, 'file1'], 'xxx') self.write_file([dist, 'file2'], 'xxx') os.mkdir(os.path.join(dist, 'sub')) self.write_file([dist, 'sub', 'file3'], 'xxx') os.mkdir(os.path.join(dist, 'sub2')) tmpdir2 = self.mkdtemp() base_name = os.path.join(tmpdir2, 'archive') return tmpdir, tmpdir2, base_name @unittest.skipUnless(zlib, "Requires zlib") @unittest.skipUnless(find_executable('tar') and find_executable('gzip'), 'Need the tar command to run') def test_tarfile_vs_tar(self): tmpdir, tmpdir2, base_name = self._create_files() old_dir = os.getcwd() os.chdir(tmpdir) try: _make_tarball(base_name, 'dist') finally: os.chdir(old_dir) # check if the compressed tarball was created tarball = base_name + '.tar.gz' self.assertTrue(os.path.exists(tarball)) # now create another tarball using `tar` tarball2 = os.path.join(tmpdir, 'archive2.tar.gz') tar_cmd = ['tar', '-cf', 'archive2.tar', 'dist'] gzip_cmd = ['gzip', '-f9', 'archive2.tar'] old_dir = os.getcwd() old_stdout = sys.stdout os.chdir(tmpdir) sys.stdout = StringIO() try: spawn(tar_cmd) spawn(gzip_cmd) finally: os.chdir(old_dir) sys.stdout = old_stdout self.assertTrue(os.path.exists(tarball2)) # let's compare both tarballs self.assertEqual(self._tarinfo(tarball), self._tarinfo(tarball2)) # trying an uncompressed one base_name = os.path.join(tmpdir2, 'archive') old_dir = os.getcwd() os.chdir(tmpdir) try: _make_tarball(base_name, 'dist', compress=None) finally: os.chdir(old_dir) tarball = base_name + '.tar' self.assertTrue(os.path.exists(tarball)) # now for a dry_run base_name = os.path.join(tmpdir2, 'archive') old_dir = os.getcwd() os.chdir(tmpdir) try: _make_tarball(base_name, 'dist', compress=None, dry_run=True) finally: os.chdir(old_dir) tarball = base_name + '.tar' self.assertTrue(os.path.exists(tarball)) @unittest.skipUnless(zlib, "Requires zlib") @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') def test_make_zipfile(self): # creating something to tar tmpdir = self.mkdtemp() self.write_file([tmpdir, 'file1'], 'xxx') self.write_file([tmpdir, 'file2'], 'xxx') tmpdir2 = self.mkdtemp() # force shutil to create the directory os.rmdir(tmpdir2) base_name = os.path.join(tmpdir2, 'archive') _make_zipfile(base_name, tmpdir) # check if the compressed tarball was created tarball = base_name + '.zip' self.assertTrue(os.path.exists(tarball)) def test_make_archive(self): tmpdir = self.mkdtemp() base_name = os.path.join(tmpdir, 'archive') self.assertRaises(ValueError, make_archive, base_name, 'xxx') @unittest.skipUnless(zlib, "Requires zlib") def test_make_archive_owner_group(self): # testing make_archive with owner and group, with various combinations # this works even if there's not gid/uid support if UID_GID_SUPPORT: group = grp.getgrgid(0)[0] owner = pwd.getpwuid(0)[0] else: group = owner = 'root' base_dir, root_dir, base_name = self._create_files() base_name = os.path.join(self.mkdtemp() , 'archive') res = make_archive(base_name, 'zip', root_dir, base_dir, owner=owner, group=group) self.assertTrue(os.path.exists(res)) res = make_archive(base_name, 'zip', root_dir, base_dir) self.assertTrue(os.path.exists(res)) res = make_archive(base_name, 'tar', root_dir, base_dir, owner=owner, group=group) self.assertTrue(os.path.exists(res)) res = make_archive(base_name, 'tar', root_dir, base_dir, owner='kjhkjhkjg', group='oihohoh') self.assertTrue(os.path.exists(res)) @unittest.skipUnless(zlib, "Requires zlib") @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") def test_tarfile_root_owner(self): tmpdir, tmpdir2, base_name = self._create_files() old_dir = os.getcwd() os.chdir(tmpdir) group = grp.getgrgid(0)[0] owner = pwd.getpwuid(0)[0] try: archive_name = _make_tarball(base_name, 'dist', compress=None, owner=owner, group=group) finally: os.chdir(old_dir) # check if the compressed tarball was created self.assertTrue(os.path.exists(archive_name)) # now checks the rights archive = tarfile.open(archive_name) try: for member in archive.getmembers(): self.assertEqual(member.uid, 0) self.assertEqual(member.gid, 0) finally: archive.close() def test_make_archive_cwd(self): current_dir = os.getcwd() def _breaks(*args, **kw): raise RuntimeError() register_archive_format('xxx', _breaks, [], 'xxx file') try: try: make_archive('xxx', 'xxx', root_dir=self.mkdtemp()) except Exception: pass self.assertEqual(os.getcwd(), current_dir) finally: unregister_archive_format('xxx') def test_register_archive_format(self): self.assertRaises(TypeError, register_archive_format, 'xxx', 1) self.assertRaises(TypeError, register_archive_format, 'xxx', lambda: x, 1) self.assertRaises(TypeError, register_archive_format, 'xxx', lambda: x, [(1, 2), (1, 2, 3)]) register_archive_format('xxx', lambda: x, [(1, 2)], 'xxx file') formats = [name for name, params in get_archive_formats()] self.assertIn('xxx', formats) unregister_archive_format('xxx') formats = [name for name, params in get_archive_formats()] self.assertNotIn('xxx', formats) def _compare_dirs(self, dir1, dir2): # check that dir1 and dir2 are equivalent, # return the diff diff = [] for root, dirs, files in os.walk(dir1): for file_ in files: path = os.path.join(root, file_) target_path = os.path.join(dir2, os.path.split(path)[-1]) if not os.path.exists(target_path): diff.append(file_) return diff @support.requires_zlib def test_unpack_archive(self): formats = ['tar', 'gztar', 'zip'] if BZ2_SUPPORTED: formats.append('bztar') for format in formats: tmpdir = self.mkdtemp() base_dir, root_dir, base_name = self._create_files() tmpdir2 = self.mkdtemp() filename = make_archive(base_name, format, root_dir, base_dir) # let's try to unpack it now unpack_archive(filename, tmpdir2) diff = self._compare_dirs(tmpdir, tmpdir2) self.assertEqual(diff, []) # and again, this time with the format specified tmpdir3 = self.mkdtemp() unpack_archive(filename, tmpdir3, format=format) diff = self._compare_dirs(tmpdir, tmpdir3) self.assertEqual(diff, []) TESTFN = self.TESTFN self.assertRaises(shutil.ReadError, unpack_archive, TESTFN) self.assertRaises(ValueError, unpack_archive, TESTFN, format='xxx') def test_unpack_registery(self): formats = get_unpack_formats() def _boo(filename, extract_dir, extra): self.assertEqual(extra, 1) self.assertEqual(filename, 'stuff.boo') self.assertEqual(extract_dir, 'xx') register_unpack_format('Boo', ['.boo', '.b2'], _boo, [('extra', 1)]) unpack_archive('stuff.boo', 'xx') # trying to register a .boo unpacker again self.assertRaises(RegistryError, register_unpack_format, 'Boo2', ['.boo'], _boo) # should work now unregister_unpack_format('Boo') register_unpack_format('Boo2', ['.boo'], _boo) self.assertIn(('Boo2', ['.boo'], ''), get_unpack_formats()) self.assertNotIn(('Boo', ['.boo'], ''), get_unpack_formats()) # let's leave a clean state unregister_unpack_format('Boo2') self.assertEqual(get_unpack_formats(), formats) class TestMove(unittest.TestCase): def setUp(self): filename = "foo" self.src_dir = tempfile.mkdtemp() self.dst_dir = tempfile.mkdtemp() self.src_file = os.path.join(self.src_dir, filename) self.dst_file = os.path.join(self.dst_dir, filename) d = tempfile.mkdtemp() self.TESTFN = '%s-%d' % (d, os.getpid()) shutil.rmtree(d) #self.TESTFN2 = '%s-2' % self.TESTFN f = open(self.src_file, "wb") try: f.write(b"spam") finally: f.close() def tearDown(self): for d in (self.src_dir, self.dst_dir): try: if d: shutil.rmtree(d) except: pass def _check_move_file(self, src, dst, real_dst): f = open(src, "rb") try: contents = f.read() finally: f.close() shutil.move(src, dst) f = open(real_dst, "rb") try: self.assertEqual(contents, f.read()) finally: f.close() self.assertFalse(os.path.exists(src)) def _check_move_dir(self, src, dst, real_dst): contents = sorted(os.listdir(src)) shutil.move(src, dst) self.assertEqual(contents, sorted(os.listdir(real_dst))) self.assertFalse(os.path.exists(src)) def test_move_file(self): # Move a file to another location on the same filesystem. self._check_move_file(self.src_file, self.dst_file, self.dst_file) def test_move_file_to_dir(self): # Move a file inside an existing dir on the same filesystem. self._check_move_file(self.src_file, self.dst_dir, self.dst_file) @mock_rename def test_move_file_other_fs(self): # Move a file to an existing dir on another filesystem. self.test_move_file() @mock_rename def test_move_file_to_dir_other_fs(self): # Move a file to another location on another filesystem. self.test_move_file_to_dir() def test_move_dir(self): # Move a dir to another location on the same filesystem. dst_dir = tempfile.mktemp() try: self._check_move_dir(self.src_dir, dst_dir, dst_dir) finally: try: shutil.rmtree(dst_dir) except: pass @mock_rename def test_move_dir_other_fs(self): # Move a dir to another location on another filesystem. self.test_move_dir() def test_move_dir_to_dir(self): # Move a dir inside an existing dir on the same filesystem. self._check_move_dir(self.src_dir, self.dst_dir, os.path.join(self.dst_dir, os.path.basename(self.src_dir))) @mock_rename def test_move_dir_to_dir_other_fs(self): # Move a dir inside an existing dir on another filesystem. self.test_move_dir_to_dir() def test_existing_file_inside_dest_dir(self): # A file with the same name inside the destination dir already exists. f = open(self.dst_file, "wb") try: pass finally: f.close() self.assertRaises(shutil.Error, shutil.move, self.src_file, self.dst_dir) def test_dont_move_dir_in_itself(self): # Moving a dir inside itself raises an Error. dst = os.path.join(self.src_dir, "bar") self.assertRaises(shutil.Error, shutil.move, self.src_dir, dst) def test_destinsrc_false_negative(self): TESTFN = self.TESTFN os.mkdir(TESTFN) try: for src, dst in [('srcdir', 'srcdir/dest')]: src = os.path.join(TESTFN, src) dst = os.path.join(TESTFN, dst) self.assertTrue(shutil._destinsrc(src, dst), msg='_destinsrc() wrongly concluded that ' 'dst (%s) is not in src (%s)' % (dst, src)) finally: shutil.rmtree(TESTFN, ignore_errors=True) def test_destinsrc_false_positive(self): TESTFN = self.TESTFN os.mkdir(TESTFN) try: for src, dst in [('srcdir', 'src/dest'), ('srcdir', 'srcdir.new')]: src = os.path.join(TESTFN, src) dst = os.path.join(TESTFN, dst) self.assertFalse(shutil._destinsrc(src, dst), msg='_destinsrc() wrongly concluded that ' 'dst (%s) is in src (%s)' % (dst, src)) finally: shutil.rmtree(TESTFN, ignore_errors=True) class TestCopyFile(unittest.TestCase): _delete = False class Faux: _entered = False _exited_with = None _raised = False def __init__(self, raise_in_exit=False, suppress_at_exit=True): self._raise_in_exit = raise_in_exit self._suppress_at_exit = suppress_at_exit def read(self, *args): return '' def __enter__(self): self._entered = True def __exit__(self, exc_type, exc_val, exc_tb): self._exited_with = exc_type, exc_val, exc_tb if self._raise_in_exit: self._raised = True raise IOError("Cannot close") return self._suppress_at_exit def tearDown(self): if self._delete: del shutil.open def _set_shutil_open(self, func): shutil.open = func self._delete = True def test_w_source_open_fails(self): def _open(filename, mode='r'): if filename == 'srcfile': raise IOError('Cannot open "srcfile"') assert 0 # shouldn't reach here. self._set_shutil_open(_open) self.assertRaises(IOError, shutil.copyfile, 'srcfile', 'destfile') def test_w_dest_open_fails(self): srcfile = self.Faux() def _open(filename, mode='r'): if filename == 'srcfile': return srcfile if filename == 'destfile': raise IOError('Cannot open "destfile"') assert 0 # shouldn't reach here. self._set_shutil_open(_open) shutil.copyfile('srcfile', 'destfile') self.assertTrue(srcfile._entered) self.assertTrue(srcfile._exited_with[0] is IOError) self.assertEqual(srcfile._exited_with[1].args, ('Cannot open "destfile"',)) def test_w_dest_close_fails(self): srcfile = self.Faux() destfile = self.Faux(True) def _open(filename, mode='r'): if filename == 'srcfile': return srcfile if filename == 'destfile': return destfile assert 0 # shouldn't reach here. self._set_shutil_open(_open) shutil.copyfile('srcfile', 'destfile') self.assertTrue(srcfile._entered) self.assertTrue(destfile._entered) self.assertTrue(destfile._raised) self.assertTrue(srcfile._exited_with[0] is IOError) self.assertEqual(srcfile._exited_with[1].args, ('Cannot close',)) def test_w_source_close_fails(self): srcfile = self.Faux(True) destfile = self.Faux() def _open(filename, mode='r'): if filename == 'srcfile': return srcfile if filename == 'destfile': return destfile assert 0 # shouldn't reach here. self._set_shutil_open(_open) self.assertRaises(IOError, shutil.copyfile, 'srcfile', 'destfile') self.assertTrue(srcfile._entered) self.assertTrue(destfile._entered) self.assertFalse(destfile._raised) self.assertTrue(srcfile._exited_with[0] is None) self.assertTrue(srcfile._raised) def test_move_dir_caseinsensitive(self): # Renames a folder to the same name # but a different case. self.src_dir = tempfile.mkdtemp() dst_dir = os.path.join( os.path.dirname(self.src_dir), os.path.basename(self.src_dir).upper()) self.assertNotEqual(self.src_dir, dst_dir) try: shutil.move(self.src_dir, dst_dir) self.assertTrue(os.path.isdir(dst_dir)) finally: if os.path.exists(dst_dir): os.rmdir(dst_dir) distlib-0.2.2/tests/bad.tar.gz0000664000000000000000000000036712056760160014675 0ustar rootrootęPbad.tarY 0,%+hs{(Z(HݛԁLA8KZhԴ-UyP{N#1A5{Q +m Nkuj˛>=S޴]])pU! JKѿC?fBVb /x 9KUY OQUS{.y5E8)7r3|Wg`(distlib-0.2.2/tests/good.tar.gz0000664000000000000000000000032212056755442015075 0ustar rootrootbPgood.tarY 0@,%+мfZOE Mp h >ZhIxpT9& )ћ|RR ^Ҧ^~;չ=}qomg1Yߙ/i{boaE5LW~7.bl7(distlib-0.2.2/tests/test_scripts.py0000664000000000000000000002521412644723452016124 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # import os import shutil import subprocess import sys import tempfile from compat import unittest from distlib import DistlibException from distlib.compat import fsencode, sysconfig from distlib.scripts import ScriptMaker, _enquote_executable from distlib.util import get_executable HERE = os.path.abspath(os.path.dirname(__file__)) COPIED_SCRIPT = '''#!python # This is a copied script ''' MADE_SCRIPT = 'made = dummy.module:main' class ScriptTestCase(unittest.TestCase): def setUp(self): source_dir = os.path.join(HERE, 'scripts') target_dir = tempfile.mkdtemp() self.maker = ScriptMaker(source_dir, target_dir, add_launchers=False) def tearDown(self): shutil.rmtree(self.maker.target_dir) @unittest.skipIf(sysconfig.is_python_build(), 'Test not appropriate for ' 'Python source builds') def test_shebangs(self): executable = fsencode(get_executable()) for fn in ('foo.py', 'script1.py', 'script2.py', 'script3.py', 'shell.sh'): files = self.maker.make(fn) self.assertEqual(len(files), 1) d, f = os.path.split(files[0]) self.assertEqual(f, fn) self.assertEqual(d, self.maker.target_dir) if fn.endswith('.py') and fn != 'foo.py': # no shebang in foo.py with open(files[0], 'rb') as f: first_line = f.readline() self.assertIn(executable, first_line) def test_shebangs_custom_executable(self): srcdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, srcdir) dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) maker = ScriptMaker(srcdir, dstdir, add_launchers=False) maker.executable = 'this_should_appear_in_the_shebang_line' #let's create the script to be copied. It has a vanilla shebang line. fn = os.path.join(srcdir, 'copied') with open(fn, 'w') as f: f.write(COPIED_SCRIPT) # Let's ask the maker to copy the script, and see what the shebang is # in the copy. filenames = maker.make('copied') with open(filenames[0], 'r') as f: actual = f.readline() self.assertIn(maker.executable, actual) # Now let's make a script from a callable filenames = maker.make(MADE_SCRIPT) with open(filenames[0], 'r') as f: actual = f.readline() self.assertIn(maker.executable, actual) def test_multiple(self): specs = ('foo.py', 'script1.py', 'script2.py', 'script3.py', 'shell.sh', 'uwsgi_part') files = self.maker.make_multiple(specs) self.assertEqual(len(specs), len(files)) expected = set(specs) self.assertEqual(expected, set([os.path.basename(f) for f in files])) ofiles = os.listdir(self.maker.target_dir) self.assertEqual(expected, set(ofiles)) def test_generation(self): self.maker.clobber = True for name in ('main', 'other_main'): for options in (None, {}, {'gui': False}, {'gui': True}): gui = options and options.get('gui', False) spec = 'foo = foo:' + name files = self.maker.make(spec, options) self.assertEqual(len(files), 2) actual = set() for f in files: d, f = os.path.split(f) actual.add(f) if os.name == 'nt': # pragma: no cover if gui: ext = 'pyw' else: ext = 'py' expected = set(['foo.%s' % ext, 'foo-%s.%s' % (sys.version[:3], ext)]) else: expected = set(['foo', 'foo-%s' % sys.version[:3]]) self.assertEqual(actual, expected) self.assertEqual(d, self.maker.target_dir) for fn in files: with open(fn, 'r') as f: text = f.read() self.assertIn("_resolve('foo', '%s')" % name, text) if options and options['gui'] and os.name == 'nt': # pragma: no cover first_line, rest = text.split('\n', 1) self.assertIn('pythonw', first_line) def test_clobber(self): files = self.maker.make('foo = foo:main') saved_files = files self.assertGreaterEqual(len(files), 2) # foo, foo-X.Y files = self.maker.make('foo = foo:main') self.assertFalse(files) self.maker.clobber = True files = self.maker.make('foo = foo:main') self.assertEqual(files, saved_files) @unittest.skipIf(os.name != 'nt', 'Test is Windows-specific') def test_launchers(self): # pragma: no cover tlauncher = self.maker._get_launcher('t') self.maker.add_launchers = True specs = ('foo.py', 'script1.py', 'script2.py', 'script3.py', 'shell.sh') files = self.maker.make_multiple(specs) self.assertEqual(len(specs), len(files)) filenames = set([os.path.basename(f) for f in files]) self.assertEqual(filenames, set(('foo.py', 'script1.exe', 'script2.exe', 'script3.exe', 'shell.sh'))) for fn in files: if not fn.endswith('.exe'): continue with open(fn, 'rb') as f: data = f.read() self.assertTrue(data.startswith(tlauncher)) @unittest.skipIf(os.name != 'nt', 'Test is Windows-specific') def test_windows(self): # pragma: no cover wlauncher = self.maker._get_launcher('w') tlauncher = self.maker._get_launcher('t') self.maker.add_launchers = True executable = os.path.normcase(sys.executable).encode('utf-8') wexecutable = executable.replace(b'python.exe', b'pythonw.exe') files = self.maker.make('script4.py') self.assertEqual(len(files), 1) filenames = set([os.path.basename(f) for f in files]) self.assertEqual(filenames, set(['script4.exe'])) for fn in files: with open(fn, 'rb') as f: data = f.read() self.assertTrue(data.startswith(wlauncher)) self.assertIn(executable, data) # Now test making scripts gui and console files = self.maker.make('foo = foo:main', {'gui': True}) self.assertEqual(len(files), 2) filenames = set([os.path.basename(f) for f in files]) specific = sys.version[:3] self.assertEqual(filenames, set(('foo.exe', 'foo-%s.exe' % specific))) for fn in files: with open(fn, 'rb') as f: data = f.read() self.assertTrue(data.startswith(wlauncher)) self.assertIn(wexecutable, data) files = self.maker.make('foo = foo:main') self.assertEqual(len(files), 2) filenames = set([os.path.basename(f) for f in files]) self.assertEqual(filenames, set(('foo.exe', 'foo-%s.exe' % specific))) for fn in files: with open(fn, 'rb') as f: data = f.read() self.assertTrue(data.startswith(tlauncher)) self.assertIn(executable, data) def test_dry_run(self): self.maker.dry_run = True self.maker.variants = set(['']) specs = ('foo.py', 'bar = foo:main') files = self.maker.make_multiple(specs) self.assertEqual(len(specs), len(files)) if os.name == 'nt': # pragma: no cover bar = 'bar.py' else: bar = 'bar' self.assertEqual(set(('foo.py', bar)), set([os.path.basename(f) for f in files])) ofiles = os.listdir(self.maker.target_dir) self.assertFalse(ofiles) def test_script_run(self): files = self.maker.make('test = cgi:print_directory') self.assertEqual(len(files), 2) p = subprocess.Popen([sys.executable, files[0]], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() self.assertIn(b'

Current Working Directory:

', stdout) self.assertIn(os.getcwd().encode('utf-8'), stdout) @unittest.skipUnless(os.name == 'posix', 'Test only valid for POSIX') def test_mode(self): self.maker.set_mode = False files = self.maker.make('foo = foo:main') self.assertEqual(len(files), 2) for f in files: self.assertIn(os.stat(f).st_mode & 0o7777, (0o644, 0o664)) self.maker.set_mode = True files = self.maker.make('bar = bar:main') self.assertEqual(len(files), 2) for f in files: self.assertIn(os.stat(f).st_mode & 0o7777, (0o755, 0o775)) def test_interpreter_args(self): executable = fsencode(get_executable()) options = { 'interpreter_args': ['-E', '"foo bar"', 'baz frobozz'] } self.maker.variants = set(['']) files = self.maker.make('foo = bar:baz', options=options) self.assertEqual(len(files), 1) with open(files[0], 'rb') as f: shebang_line = f.readline() self.assertIn(executable, shebang_line) self.assertIn(b' -E "foo bar" baz frobozz', shebang_line) def test_args_on_copy(self): self.maker.variants = set(['']) self.maker.executable = 'mypython' files = self.maker.make('script5.py') with open(files[0]) as f: actual = f.readline().strip() self.assertEqual(actual, '#!mypython -mzippy.activate') self.maker.executable = None os.remove(files[0]) files = self.maker.make('script5.py') with open(files[0]) as f: actual = f.readline().strip() expected = '#!%s -mzippy.activate' % get_executable() self.assertEqual(actual, expected) def test_enquote_executable(self): for executable, expected in ( ('/no/spaces', '/no/spaces'), ('/i have/space', '"/i have/space"'), ('"/space prequoted"', '"/space prequoted"'), ('/usr/bin/env nospaces', '/usr/bin/env nospaces'), ('/usr/bin/env with spaces', '/usr/bin/env "with spaces"'), ('/usr/bin/env "pre spaced"', '/usr/bin/env "pre spaced"') ): self.assertEqual(_enquote_executable(executable), expected) if __name__ == '__main__': # pragma: no cover unittest.main() distlib-0.2.2/tests/test_index.py0000664000000000000000000002741512641266166015552 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2013 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # import codecs import json import logging import os import shutil import socket import subprocess import sys import tempfile try: import threading except ImportError: import dummy_threading as threading from compat import unittest, Request from support import HTTPSServerThread from distlib import DistlibException from distlib.compat import urlopen, HTTPError, URLError from distlib.index import PackageIndex from distlib.metadata import Metadata, MetadataMissingError, METADATA_FILENAME from distlib.util import zip_dir, HTTPSHandler logger = logging.getLogger(__name__) HERE = os.path.abspath(os.path.dirname(__file__)) if 'HOME' in os.environ: PYPIRC = os.path.expandvars('$HOME/.pypirc') else: PYPIRC = None class PackageIndexTestCase(unittest.TestCase): run_test_server = True test_server_url = 'http://localhost:8080/' @classmethod def setUpClass(cls): if cls.run_test_server: cls.server = None server_script = os.path.join(HERE, 'pypi-server-standalone.py') if not os.path.exists(server_script): logger.debug('test server not available - some tests ' 'will be skipped.') return pwdfn = os.path.join(HERE, 'passwords') if not os.path.exists(pwdfn): # pragma: no cover with open(pwdfn, 'w') as f: f.write('test:secret\n') pkgdir = os.path.join(HERE, 'packages') if not os.path.isdir(pkgdir): # pragma: no cover os.mkdir(pkgdir) cls.sink = sink = open(os.devnull, 'w') cmd = [sys.executable, 'pypi-server-standalone.py', '-P', 'passwords', 'packages'] cls.server = subprocess.Popen(cmd, stdout=sink, stderr=sink, cwd=HERE) # wait for the server to start up response = None while response is None: try: response = urlopen(cls.test_server_url) except URLError: pass @classmethod def tearDownClass(cls): if cls.run_test_server: if cls.server and cls.server.returncode is None: cls.server.kill() cls.sink.close() def setUp(self): if not self.run_test_server: self.index = PackageIndex() else: self.index = PackageIndex(self.test_server_url) self.index.username = 'test' self.index.password = 'secret' def load_package_metadata(self, path): result = None for bn in (METADATA_FILENAME, 'package.json'): fn = os.path.join(path, bn) if os.path.exists(fn): with codecs.open(fn, 'r', 'utf-8') as jf: result = json.load(jf) break if not result: raise ValueError('neither %s nor package.json ' 'found in %s' % (METADATA_FILENAME, fn)) if bn == 'package.json': result = result.get('index-metadata', {}) if result.get('metadata_version') != '2.0': raise ValueError('Not a valid file: %s' % fn) return result def check_pypi_server_available(self): if self.run_test_server and not self.server: # pragma: no cover raise unittest.SkipTest('test server not available') def check_testdist_available(self): self.index.check_credentials() self.username = self.index.username.replace('-', '_') self.dist_project = '%s_testdist' % self.username self.dist_version = '0.1' self.testdir = '%s-%s' % (self.dist_project, self.dist_version) destdir = os.path.join(HERE, self.testdir) if not os.path.isdir(destdir): # pragma: no cover srcdir = os.path.join(HERE, 'testdist-0.1') shutil.copytree(srcdir, destdir) for fn in os.listdir(destdir): fn = os.path.join(destdir, fn) if os.path.isfile(fn): with codecs.open(fn, 'r', 'utf-8') as f: data = f.read() data = data.format(username=self.username) with codecs.open(fn, 'w', 'utf-8') as f: f.write(data) zip_data = zip_dir(destdir).getvalue() zip_name = destdir + '.zip' with open(zip_name, 'wb') as f: f.write(zip_data) def test_register(self): "Test registration" self.check_pypi_server_available() self.check_testdist_available() d = os.path.join(HERE, self.testdir) data = self.load_package_metadata(d) md = Metadata() self.assertRaises(MetadataMissingError, self.index.register, md) md.name = self.dist_project self.assertRaises(MetadataMissingError, self.index.register, md) md.version = data['version'] md.summary = data['summary'] response = self.index.register(md) self.assertEqual(response.code, 200) def remove_package(self, name, version): """ Remove package. Only works with test server; PyPI would require some scraping to get CSRF tokens into the request. """ d = { ':action': 'remove_pkg', 'name': name, 'version': version, 'submit_remove': 'Remove', 'submit_ok': 'OK', } self.index.check_credentials() request = self.index.encode_request(d.items(), []) try: response = self.index.send_request(request) except HTTPError as e: if e.getcode() != 404: raise def test_upload(self): "Test upload" self.check_pypi_server_available() self.check_testdist_available() if self.run_test_server: self.remove_package(self.dist_project, self.dist_version) d = os.path.join(HERE, self.testdir) data = self.load_package_metadata(d) md = Metadata(mapping=data) self.index.gpg_home = os.path.join(HERE, 'keys') try: zip_name = os.path.join(HERE, '%s.zip' % self.testdir) self.assertRaises(DistlibException, self.index.upload_file, md, 'random-' + zip_name, 'Test User', 'tuser') response = self.index.upload_file(md, zip_name, 'Test User', 'tuser') self.assertEqual(response.code, 200) if self.run_test_server: fn = os.path.join(HERE, 'packages', os.path.basename(zip_name)) self.assertTrue(os.path.exists(fn)) except HTTPError as e: # Treat as success if it already exists if e.getcode() != 400 or 'already exists' not in e.msg: raise def test_upload_documentation(self): "Test upload of documentation" raise unittest.SkipTest('Skipped, as pythonhosted.org is being ' 'de-emphasised and this functionality may ' 'no longer be available') self.check_pypi_server_available() self.check_testdist_available() d = os.path.join(HERE, self.testdir) data = self.load_package_metadata(d) md = Metadata(mapping=data) d = os.path.join(d, 'doc') # Non-existent directory self.assertRaises(DistlibException, self.index.upload_documentation, md, d+'-random') # Directory with no index.html self.assertRaises(DistlibException, self.index.upload_documentation, md, HERE) response = self.index.upload_documentation(md, d) self.assertEqual(response.code, 200) if not self.run_test_server: url = 'http://packages.python.org/%s/' % self.dist_project response = urlopen(url) self.assertEqual(response.code, 200) data = response.read() expected = b'This is dummy documentation' self.assertIn(expected, data) def test_verify_signature(self): if not self.index.gpg: # pragma: no cover raise unittest.SkipTest('gpg not available') sig_file = os.path.join(HERE, 'good.bin.asc') good_file = os.path.join(HERE, 'good.bin') bad_file = os.path.join(HERE, 'bad.bin') gpg = self.index.gpg self.index.gpg = None self.assertRaises(DistlibException, self.index.verify_signature, sig_file, good_file) self.index.gpg = gpg # Not pointing to keycd tests self.assertRaises(DistlibException, self.index.verify_signature, sig_file, good_file) self.index.gpg_home = os.path.join(HERE, 'keys') self.assertTrue(self.index.verify_signature(sig_file, good_file)) self.assertFalse(self.index.verify_signature(sig_file, bad_file)) def test_invalid(self): self.assertRaises(DistlibException, PackageIndex, 'ftp://ftp.python.org/') self.index.username = None self.assertRaises(DistlibException, self.index.check_credentials) @unittest.skipIf(PYPIRC is None or os.path.exists(PYPIRC), 'because $HOME/.pypirc is unavailable for use') def test_save_configuration(self): try: self.index.save_configuration() self.assertTrue(os.path.exists(PYPIRC)) finally: os.remove(PYPIRC) def make_https_server(self, certfile): server = HTTPSServerThread(certfile) flag = threading.Event() server.start(flag) flag.wait() def cleanup(): server.stop() server.join() self.addCleanup(cleanup) return server def test_ssl_verification(self): certfile = os.path.join(HERE, 'keycert.pem') server = self.make_https_server(certfile) url = 'https://localhost:%d/' % server.port req = Request(url) self.index.ssl_verifier = HTTPSHandler(certfile) response = self.index.send_request(req) self.assertEqual(response.code, 200) def test_download(self): digest = '913093474942c5a564c011f232868517' # for testsrc/README.txt certfile = os.path.join(HERE, 'keycert.pem') server = self.make_https_server(certfile) url = 'https://localhost:%d/README.txt' % server.port fd, fn = tempfile.mkstemp() os.close(fd) self.addCleanup(os.remove, fn) with open(os.path.join(HERE, 'testsrc', 'README.txt'), 'rb') as f: data = f.read() self.index.ssl_verifier = HTTPSHandler(certfile) self.index.download_file(url, fn) # no digest with open(fn, 'rb') as f: self.assertEqual(data, f.read()) self.index.download_file(url, fn, digest) with open(fn, 'rb') as f: self.assertEqual(data, f.read()) reporthook = lambda *args: None self.index.download_file(url, fn, ('md5', digest), reporthook) with open(fn, 'rb') as f: self.assertEqual(data, f.read()) # bad digest self.assertRaises(DistlibException, self.index.download_file, url, fn, digest[:-1] + '8') @unittest.skipIf('SKIP_ONLINE' in os.environ, 'Skipping online test') def test_search(self): self.index = PackageIndex() result = self.index.search({'name': 'tatterdema'}) self.assertEqual(len(result), 1) result = self.index.search({'name': 'ragamuff'}) self.assertEqual(len(result), 0) if __name__ == '__main__': # pragma: no cover unittest.main() distlib-0.2.2/tests/bad.tar.bz20000664000000000000000000000037612056760160014752 0ustar rootrootBZh91AY&SY _SU@Ԡw'_`@0hd&j=S)!mDy 24ژ) ^:/-rQtͫ5 Kdm "ׇ A test distribution for distlib This is dummy documentation for a test distribution for distlib. PKpBBWy\PKG-INFOPKpBB5aELICENSEPKpBBG9 testdist.pyPKpBB<v.. README.txtPKpBB3  package.jsonPK{BBc0 doc/index.htmlPKR distlib-0.2.2/tests/support.py0000664000000000000000000002231712300015212015064 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # import codecs import os import logging import logging.handlers import shutil import socket import ssl import sys import tempfile try: import threading except ImportError: import dummy_threading as threading import weakref from compat import (unittest, HTTPServer as BaseHTTPServer, SimpleHTTPRequestHandler, urlparse) from distlib import logger HERE = os.path.dirname(__file__) class _TestHandler(logging.handlers.BufferingHandler, object): # stolen and adapted from test.support def __init__(self): super(_TestHandler, self).__init__(0) self.setLevel(logging.DEBUG) def shouldFlush(self): return False def emit(self, record): self.buffer.append(record) class LoggingCatcher(object): """TestCase-compatible mixin to receive logging calls. Upon setUp, instances of this classes get a BufferingHandler that's configured to record all messages logged to the 'distutils2' logger. Use get_logs to retrieve messages and self.loghandler.flush to discard them. get_logs automatically flushes the logs, unless you pass *flush=False*, for example to make multiple calls to the method with different level arguments. If your test calls some code that generates logging message and then you don't call get_logs, you will need to flush manually before testing other code in the same test_* method, otherwise get_logs in the next lines will see messages from the previous lines. See example in test_command_check. """ def setUp(self): super(LoggingCatcher, self).setUp() self.loghandler = handler = _TestHandler() self._old_level = logger.level logger.addHandler(handler) logger.setLevel(logging.DEBUG) # we want all messages def tearDown(self): handler = self.loghandler # All this is necessary to properly shut down the logging system and # avoid a regrtest complaint. Thanks to Vinay Sajip for the help. handler.close() logger.removeHandler(handler) for ref in weakref.getweakrefs(handler): logging._removeHandlerRef(ref) del self.loghandler logger.setLevel(self._old_level) super(LoggingCatcher, self).tearDown() def get_logs(self, level=logging.WARNING, flush=True): """Return all log messages with given level. *level* defaults to logging.WARNING. For log calls with arguments (i.e. logger.info('bla bla %r', arg)), the messages will be formatted before being returned (e.g. "bla bla 'thing'"). Returns a list. Automatically flushes the loghandler after being called, unless *flush* is False (this is useful to get e.g. all warnings then all info messages). """ messages = [log.getMessage() for log in self.loghandler.buffer if log.levelno == level] if flush: self.loghandler.flush() return messages class TempdirManager(object): """TestCase-compatible mixin to create temporary directories and files. Directories and files created in a test_* method will be removed after it has run. """ def setUp(self): super(TempdirManager, self).setUp() self._olddir = os.getcwd() self._basetempdir = tempfile.mkdtemp() self._files = [] def tearDown(self): for handle, name in self._files: if handle is not None: handle.close() os.remove(name) os.chdir(self._olddir) shutil.rmtree(self._basetempdir) super(TempdirManager, self).tearDown() def temp_filename(self): """Create a read-write temporary file name and return it.""" fd, fn = tempfile.mkstemp(dir=self._basetempdir) os.close(fd) self._files.append((None, fn)) return fn def mktempfile(self): """Create a read-write temporary file and return it.""" fd, fn = tempfile.mkstemp(dir=self._basetempdir) os.close(fd) fp = open(fn, 'w+') self._files.append((fp, fn)) return fp def mkdtemp(self): """Create a temporary directory and return its path.""" d = tempfile.mkdtemp(dir=self._basetempdir) return d def write_file(self, path, content='xxx', encoding=None): """Write a file at the given path. path can be a string, a tuple or a list; if it's a tuple or list, os.path.join will be used to produce a path. """ if isinstance(path, (list, tuple)): path = os.path.join(*path) f = codecs.open(path, 'w', encoding=encoding) try: f.write(content) finally: f.close() def assertIsFile(self, *args): path = os.path.join(*args) dirname = os.path.dirname(path) file = os.path.basename(path) if os.path.isdir(dirname): files = os.listdir(dirname) msg = "%s not found in %s: %s" % (file, dirname, files) assert os.path.isfile(path), msg else: raise AssertionError( '%s not found. %s does not exist' % (file, dirname)) def assertIsNotFile(self, *args): path = os.path.join(*args) self.assertFalse(os.path.isfile(path), "%r exists" % path) class EnvironRestorer(object): """TestCase-compatible mixin to restore or delete environment variables. The variables to restore (or delete if they were not originally present) must be explicitly listed in self.restore_environ. It's better to be aware of what we're modifying instead of saving and restoring the whole environment. """ def setUp(self): super(EnvironRestorer, self).setUp() self._saved = [] self._added = [] for key in self.restore_environ: if key in os.environ: self._saved.append((key, os.environ[key])) else: self._added.append(key) def tearDown(self): for key, value in self._saved: os.environ[key] = value for key in self._added: os.environ.pop(key, None) super(EnvironRestorer, self).tearDown() class HTTPRequestHandler(SimpleHTTPRequestHandler): server_version = "TestHTTPS/1.0" # Avoid hanging when a request gets interrupted by the client timeout = 5 def translate_path(self, path): return os.path.join(HERE, 'testsrc', 'README.txt') def log_message(self, format, *args): pass class HTTPSServer(BaseHTTPServer): # Adapted from the one in Python's test suite. def __init__(self, server_address, handler_class, certfile): BaseHTTPServer.__init__(self, server_address, handler_class) self.certfile = certfile def get_request(self): try: sock, addr = self.socket.accept() if hasattr(ssl, 'SSLContext'): context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context.load_cert_chain(self.certfile) sock = context.wrap_socket(sock, server_side=True) else: sock = ssl.wrap_socket(sock, server_side=True, certfile=self.certfile, keyfile=self.certfile, ssl_version=ssl.PROTOCOL_SSLv23) except socket.error as e: # socket errors are silenced by the caller, print them here sys.stderr.write("Got an error:\n%s\n" % e) raise return sock, addr class HTTPSServerThread(threading.Thread): def __init__(self, certfile): self.flag = None self.server = HTTPSServer(('localhost', 0), HTTPRequestHandler, certfile) self.port = self.server.server_port threading.Thread.__init__(self) self.daemon = True def start(self, flag=None): self.flag = flag threading.Thread.start(self) def run(self): if self.flag: self.flag.set() try: self.server.serve_forever(0.05) finally: self.server.server_close() def stop(self): self.server.shutdown() try: import zlib except ImportError: zlib = None requires_zlib = unittest.skipUnless(zlib, 'requires zlib') _can_symlink = None def can_symlink(): global _can_symlink if _can_symlink is not None: return _can_symlink fd, TESTFN = tempfile.mkstemp() os.close(fd) os.remove(TESTFN) symlink_path = TESTFN + "can_symlink" try: os.symlink(TESTFN, symlink_path) can = True except (OSError, NotImplementedError, AttributeError): can = False else: os.remove(symlink_path) _can_symlink = can return can def skip_unless_symlink(test): """Skip decorator for tests that require functional symlink""" ok = can_symlink() msg = "Requires functional symlink implementation" return test if ok else unittest.skip(msg)(test) def fake_dec(*args, **kw): """Fake decorator""" def _wrap(func): def __wrap(*args, **kw): return func(*args, **kw) return __wrap return _wrap distlib-0.2.2/tests/good.bin.asc0000664000000000000000000000043712103470060015173 0ustar rootrootQ( b`?*?~r^=vAI C?B6Aa Sb 3tCiC,.=Ϟ32$ ZVgm6}ԒBXYgHhO¦b1H&4ÞYNU&|D^WXU!X%4!(dȴeBW,DOdistlib-0.2.2/tests/test_markers.py0000664000000000000000000000665012270276510016075 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # """Tests for distlib.markers.""" import os import sys import platform from compat import unittest from distlib.compat import python_implementation from distlib.markers import interpret from distlib.util import in_venv class MarkersTestCase(unittest.TestCase): def test_interpret(self): sys_platform = sys.platform version = sys.version.split()[0] os_name = os.name platform_version = platform.version() platform_machine = platform.machine() platform_python_implementation = python_implementation() self.assertTrue(interpret("sys_platform == '%s'" % sys_platform)) self.assertTrue(interpret( "sys_platform == '%s' and python_full_version == '%s'" % (sys_platform, version))) self.assertTrue(interpret("'%s' == sys_platform" % sys_platform)) self.assertTrue(interpret('os_name == "%s"' % os_name)) self.assertTrue(interpret( 'platform_version == "%s" and platform_machine == "%s"' % (platform_version, platform_machine))) self.assertTrue(interpret('platform_python_implementation == "%s"' % platform_python_implementation)) self.assertTrue(interpret('platform_in_venv == "%s"' % in_venv())) # stuff that need to raise a syntax error ops = ('os_name == 2', "'2' == '2'", 'okpjonon', '', 'os_name ==', 'python_version == 2.4') for op in ops: self.assertRaises(SyntaxError, interpret, op) # combined operations OP = 'os_name == "%s"' % os_name FALSEOP = 'os_name == "buuuu"' AND = ' and ' OR = ' or ' self.assertTrue(interpret(OP + AND + OP)) self.assertTrue(interpret(OP + AND + OP + AND + OP)) self.assertTrue(interpret(OP + OR + OP)) self.assertTrue(interpret(OP + OR + FALSEOP)) self.assertTrue(interpret(OP + OR + OP + OR + FALSEOP)) self.assertTrue(interpret(OP + OR + FALSEOP + OR + FALSEOP)) self.assertTrue(interpret(FALSEOP + OR + OP)) self.assertFalse(interpret(FALSEOP + AND + FALSEOP)) self.assertFalse(interpret(FALSEOP + OR + FALSEOP)) # other operators self.assertTrue(interpret("os_name != 'buuuu'")) self.assertTrue(interpret("python_version > '1.0'")) self.assertTrue(interpret("python_version < '5.0'")) self.assertTrue(interpret("python_version <= '5.0'")) self.assertTrue(interpret("python_version >= '1.0'")) self.assertTrue(interpret("'%s' in os_name" % os_name)) self.assertTrue(interpret("'buuuu' not in os_name")) self.assertTrue(interpret("'buu' in os_name", {'os_name': 'buuu'})) self.assertTrue(interpret( "'buuuu' not in os_name and '%s' in os_name" % os_name)) # execution context self.assertTrue(interpret('python_version == "0.1"', {'python_version': '0.1'})) # parentheses and extra if sys.platform != 'win32': relop = '!=' else: relop = '==' expression = ("(sys_platform %s 'win32' or python_version == '2.4') " "and extra == 'quux'" % relop) self.assertTrue(interpret(expression, {'extra': 'quux'})) if __name__ == '__main__': # pragma: no cover unittest.main() distlib-0.2.2/tests/test_database.py0000664000000000000000000012237612641335320016176 0ustar rootroot# -*- coding: utf-8 -*- # # Copyright (C) 2012-2013 The Python Software Foundation. # See LICENSE.txt and CONTRIBUTORS.txt. # from __future__ import unicode_literals import base64 import io import os import hashlib import logging import random import re import shutil import sys import tempfile from textwrap import dedent from compat import unittest from distlib import DistlibException from distlib.compat import text_type, file_type, StringIO import distlib.database from distlib.metadata import Metadata, METADATA_FILENAME from distlib.database import (InstalledDistribution, EggInfoDistribution, BaseInstalledDistribution, EXPORTS_FILENAME, DistributionPath, make_graph, get_required_dists, get_dependent_dists) from distlib.util import (get_resources_dests, ExportEntry, CSVReader, read_exports, write_exports) from test_util import GlobTestCaseBase from support import LoggingCatcher, requires_zlib logger = logging.getLogger(__name__) # TODO Add a test for getting a distribution provided by another distribution # TODO Add a test for absolute path RECORD items (e.g. /etc/myapp/config.ini) # TODO Add tests from the former pep376 project (zipped site-packages, etc.) class FakeDistsMixin(object): def setUp(self): super(FakeDistsMixin, self).setUp() # make a copy that we can write into for our fake installed # distributions tmpdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, tmpdir) self.fake_dists_path = os.path.realpath( os.path.join(tmpdir, 'fake_dists')) fake_dists_src = os.path.abspath( os.path.join(os.path.dirname(__file__), 'fake_dists')) shutil.copytree(fake_dists_src, self.fake_dists_path) # XXX ugly workaround: revert copystat calls done by shutil behind our # back (to avoid getting a read-only copy of a read-only file). we # could pass a custom copy_function to change the mode of files, but # shutil gives no control over the mode of directories :( # see http://bugs.python.org/issue1666318 for root, dirs, files in os.walk(self.fake_dists_path): os.chmod(root, 0o755) for f in files: os.chmod(os.path.join(root, f), 0o644) for d in dirs: os.chmod(os.path.join(root, d), 0o755) class CommonDistributionTests(FakeDistsMixin): """Mixin used to test the interface common to InstalledDistribution and EggInfoDistribution classes. Derived classes define cls, sample_dist, dirs and records. These attributes are used in test methods. See source code for details. """ def _get_dist_path(self, distdir): here = os.path.abspath(os.path.dirname(__file__)) return os.path.join(here, 'fake_dists', distdir) def test_instantiation(self): # check that useful attributes are here name, version, distdir = self.sample_dist dist_path = self._get_dist_path(distdir) dist = self.dist = self.cls(dist_path) self.assertEqual(dist.path, dist_path) self.assertEqual(dist.name, name) self.assertEqual(dist.metadata.name, name) self.assertIsInstance(dist.metadata, Metadata) self.assertEqual(dist.version, version) self.assertEqual(dist.metadata.version, version) @requires_zlib def test_repr(self): dist = self.cls(self.dirs[0]) # just check that the class name is in the repr self.assertIn(self.cls.__name__, repr(dist)) @requires_zlib def test_str(self): name, version, distdir = self.sample_dist dist = self.cls(self._get_dist_path(distdir)) self.assertEqual(name, dist.name) # Sanity test: dist.name is unicode, # but str output contains no u prefix. self.assertIsInstance(dist.name, text_type) self.assertEqual(version, dist.version) self.assertEqual(str(dist), self.expected_str_output) @requires_zlib def test_comparison(self): # tests for __eq__ and __hash__ dist = self.cls(self.dirs[0]) dist2 = self.cls(self.dirs[0]) dist3 = self.cls(self.dirs[1]) self.assertIn(dist, {dist: True}) self.assertEqual(dist, dist) self.assertIsNot(dist, dist2) self.assertEqual(dist, dist2) self.assertNotEqual(dist, dist3) self.assertNotEqual(dist, ()) def test_list_installed_files(self): for dir_ in self.dirs: dist = self.cls(dir_) for path, hash, size in dist.list_installed_files(): record_data = self.records[dist.path] self.assertIn(path, record_data) self.assertEqual(hash, record_data[path][0]) self.assertEqual(size, record_data[path][1]) def test_hash(self): datalen = random.randrange(0, 500) data = os.urandom(datalen) for dir_ in self.dirs: dist = self.cls(dir_) for hasher in ('sha1', 'sha224', 'sha384', 'sha256', 'sha512', None): dist.hasher = hasher actual = dist.get_hash(data) if hasher is None: digester = hashlib.md5(data) else: digester = getattr(hashlib, hasher)(data) digest = digester.digest() digest = base64.urlsafe_b64encode(digest).rstrip(b'=') digest = digest.decode('ascii') if hasher is None: expected = digest else: expected = '%s=%s' % (hasher, digest) self.assertEqual(actual, expected) class TestDistribution(CommonDistributionTests, unittest.TestCase): cls = InstalledDistribution sample_dist = 'choxie', '2.0.0.9', 'choxie-2.0.0.9.dist-info' expected_str_output = 'choxie 2.0.0.9' def setUp(self): def get_files(location): for path in ('REQUESTED', 'INSTALLER', 'METADATA', METADATA_FILENAME, EXPORTS_FILENAME): p = os.path.join(location + '.dist-info', path) if os.path.exists(p): yield p for path, dirs, files in os.walk(location): for f in files: yield os.path.join(path, f) super(TestDistribution, self).setUp() self.dirs = [os.path.join(self.fake_dists_path, f) for f in os.listdir(self.fake_dists_path) if f.endswith('.dist-info')] self.records = {} for distinfo_dir in self.dirs: dist_location = distinfo_dir.replace('.dist-info', '') record_file = os.path.join(distinfo_dir, 'RECORD') # Write the files using write_installed_files. # list_installed_files should read and match. dist = self.cls(distinfo_dir) prefix = os.path.dirname(dist_location) dist.write_installed_files(get_files(dist_location), prefix) with CSVReader(path=record_file) as record_reader: record_data = {} for row in record_reader: if row == []: continue path, hash, size = (row[:] + [None for i in range(len(row), 3)]) record_data[path] = hash, size self.records[distinfo_dir] = record_data def test_instantiation(self): super(TestDistribution, self).test_instantiation() self.assertIsInstance(self.dist.requested, bool) def test_get_distinfo_file(self): # Test the retrieval of dist-info file objects. distinfo_name = 'choxie-2.0.0.9' other_distinfo_name = 'grammar-1.0a4' distinfo_dir = os.path.join(self.fake_dists_path, distinfo_name + '.dist-info') dist = InstalledDistribution(distinfo_dir) # Test for known good file matches distinfo_files = [ # Relative paths 'INSTALLER', METADATA_FILENAME, # Absolute paths os.path.join(distinfo_dir, 'RECORD'), os.path.join(distinfo_dir, 'REQUESTED'), ] for distfile in distinfo_files: value = dist.get_distinfo_file(distfile) self.assertTrue(os.path.isfile(value)) self.assertEqual(value, os.path.join(distinfo_dir, distfile)) # Test an absolute path that is part of another distributions dist-info other_distinfo_file = os.path.join( self.fake_dists_path, other_distinfo_name + '.dist-info', 'REQUESTED') self.assertRaises(DistlibException, dist.get_distinfo_file, other_distinfo_file) # Test for a file that should not exist self.assertRaises(DistlibException, dist.get_distinfo_file, 'MAGICFILE') def test_list_distinfo_files(self): distinfo_name = 'towel_stuff-0.1' distinfo_dir = os.path.join(self.fake_dists_path, distinfo_name + '.dist-info') dist = InstalledDistribution(distinfo_dir) # Test for the iteration of the raw path distinfo_files = [os.path.join(distinfo_dir, filename) for filename in os.listdir(distinfo_dir)] found = list(dist.list_distinfo_files()) base = self.fake_dists_path for i, p in enumerate(found): if not os.path.isabs(p): found[i] = os.path.join(base, p) self.assertEqual(sorted(found), sorted(distinfo_files)) # Test for the iteration of local absolute paths distinfo_files = [os.path.join(sys.prefix, distinfo_dir, path) for path in distinfo_files] found = sorted(dist.list_distinfo_files()) if os.sep != '/': self.assertNotIn('/', found[0]) self.assertIn(os.sep, found[0]) self.assertEqual(found, sorted(distinfo_files)) def test_get_resources_path(self): distinfo_name = 'babar-0.1' distinfo_dir = os.path.join(self.fake_dists_path, distinfo_name + '.dist-info') dist = InstalledDistribution(distinfo_dir) resource_path = dist.get_resource_path('babar.png') self.assertEqual(resource_path, 'babar.png') self.assertRaises(KeyError, dist.get_resource_path, 'notexist') def test_check_installed_files(self): for dir_ in self.dirs: dist = self.cls(dir_) mismatches = dist.check_installed_files() self.assertEqual(mismatches, []) # pick a non-empty file at random and change its contents # but not its size. Check the failure returned, # then restore the file. files = [f for f in dist.list_installed_files() if f[-1] not in ('', '0')] bad_file = random.choice(files) bad_file_name = bad_file[0] if not os.path.isabs(bad_file_name): base = os.path.dirname(dir_) bad_file_name = os.path.join(base, bad_file_name) with open(bad_file_name, 'rb') as f: data = f.read() bad_data = bytes(bytearray(reversed(data))) bad_hash = dist.get_hash(bad_data) with open(bad_file_name, 'wb') as f: f.write(bad_data) mismatches = dist.check_installed_files() self.assertEqual(mismatches, [(bad_file_name, 'hash', bad_file[1], bad_hash)]) # now truncate the file by one byte and see what's returned with open(bad_file_name, 'wb') as f: f.write(bad_data[:-1]) bad_size = str(len(bad_data) - 1) mismatches = dist.check_installed_files() self.assertEqual(mismatches, [(bad_file_name, 'size', bad_file[2], bad_size)]) # now remove the file and see what's returned os.remove(bad_file_name) mismatches = dist.check_installed_files() self.assertEqual(mismatches, [(bad_file_name, 'exists', True, False)]) # restore the file with open(bad_file_name, 'wb') as f: f.write(data) class TestEggInfoDistribution(CommonDistributionTests, LoggingCatcher, unittest.TestCase): cls = EggInfoDistribution sample_dist = 'bacon', '0.1', 'bacon-0.1.egg-info' expected_str_output = 'bacon 0.1' def setUp(self): super(TestEggInfoDistribution, self).setUp() self.dirs = [os.path.join(self.fake_dists_path, f) for f in os.listdir(self.fake_dists_path) if f.endswith('.egg') or f.endswith('.egg-info')] self.records = {} for egginfo_dir in self.dirs: dist_location = egginfo_dir.replace('.egg-info', '') record_file = os.path.join(egginfo_dir, 'installed-files.txt') dist = self.cls(egginfo_dir) #prefix = os.path.dirname(dist_location) #dist.write_installed_files(get_files(dist_location), prefix) record_data = {} if os.path.exists(record_file): with open(record_file) as fp: for line in fp: line = line.strip() if line == './': break record_data[line] = None, None self.records[egginfo_dir] = record_data @unittest.skip('not implemented yet') def test_list_installed_files(self): # EggInfoDistribution defines list_installed_files but there is no # test for it yet; someone needs to add a file with the list of # installed files for one of the egg fake dists and write the support # code to populate self.records (and then delete this method) pass class TestDatabase(LoggingCatcher, FakeDistsMixin, unittest.TestCase): def setUp(self): super(TestDatabase, self).setUp() sys.path.insert(0, self.fake_dists_path) self.addCleanup(sys.path.remove, self.fake_dists_path) def test_caches(self): # sanity check for internal caches d = DistributionPath() for name in ('_cache', '_cache_egg'): self.assertEqual(getattr(d, name).name, {}) self.assertEqual(getattr(d, name).path, {}) def test_distinfo_dirname(self): # Given a name and a version, we expect the distinfo_dirname function # to return a standard distribution information directory name. items = [ # (name, version, standard_dirname) # Test for a very simple single word name and decimal version # number ('docutils', '0.5', 'docutils-0.5.dist-info'), # Test for another except this time with a '-' in the name, which # needs to be transformed during the name lookup ('python-ldap', '2.5', 'python_ldap-2.5.dist-info'), # Test for both '-' in the name and a funky version number ('python-ldap', '2.5 a---5', 'python_ldap-2.5 a---5.dist-info'), ] # Loop through the items to validate the results for name, version, standard_dirname in items: dirname = DistributionPath.distinfo_dirname(name, version) self.assertEqual(dirname, standard_dirname) @requires_zlib def test_get_distributions(self): # Lookup all distributions found in the ``sys.path``. # This test could potentially pick up other installed distributions non_egg_dists = [('grammar', '1.0a4'), ('choxie', '2.0.0.9'), ('towel-stuff', '0.1'), ('babar', '0.1')] egg_dists = [('bacon', '0.1'), ('cheese', '2.0.2'), ('coconuts-aster', '10.3'), ('banana', '0.4'), ('strawberry', '0.6'), ('truffles', '5.0'), ('nut', 'funkyversion')] all_dists = non_egg_dists + egg_dists d = DistributionPath() ed = DistributionPath(include_egg=True) cases = ((d, non_egg_dists, InstalledDistribution), (ed, all_dists, BaseInstalledDistribution)) fake_dists_path = self.fake_dists_path for enabled in (True, False): if not enabled: d.cache_enabled = False ed.cache_enabled = False d.clear_cache() ed.clear_cache() for distset, fake_dists, allowed_class in cases: found_dists = [] # Verify the fake dists have been found. dists = list(distset.get_distributions()) for dist in dists: self.assertIsInstance(dist, allowed_class) if (dist.name in dict(fake_dists) and dist.path.startswith(fake_dists_path)): found_dists.append((dist.name, dist.version)) else: # check that it doesn't find anything more than this self.assertFalse(dist.path.startswith(fake_dists_path)) # otherwise we don't care what other dists are found # Finally, test that we found all that we were looking for self.assertEqual(sorted(found_dists), sorted(fake_dists)) @requires_zlib def test_get_distribution(self): # Test for looking up a distribution by name. # Test the lookup of the towel-stuff distribution name = 'towel-stuff' # Note: This is different from the directory name d = DistributionPath() ed = DistributionPath(include_egg=True) # Lookup the distribution dist = d.get_distribution(name) self.assertIsInstance(dist, InstalledDistribution) self.assertEqual(dist.name, name) # Verify that an unknown distribution returns None self.assertIsNone(d.get_distribution('bogus')) # Verify partial name matching doesn't work self.assertIsNone(d.get_distribution('towel')) # Verify that it does not find egg-info distributions, when not # instructed to self.assertIsNone(d.get_distribution('bacon')) self.assertIsNone(d.get_distribution('cheese')) self.assertIsNone(d.get_distribution('strawberry')) self.assertIsNone(d.get_distribution('banana')) # Now check that it works well in both situations, when egg-info # is a file and directory respectively. for name in ('cheese', 'bacon', 'banana', 'strawberry'): dist = ed.get_distribution(name) self.assertIsInstance(dist, EggInfoDistribution) self.assertEqual(dist.name, name) @requires_zlib def test_provides(self): # Test for looking up distributions by what they provide checkLists = lambda x, y: self.assertEqual(sorted(x), sorted(y)) d = DistributionPath() ed = DistributionPath(include_egg=True) l = [dist.name for dist in d.provides_distribution('truffles')] checkLists(l, ['choxie', 'towel-stuff']) l = [dist.name for dist in d.provides_distribution('truffles', '1.0')] checkLists(l, ['choxie', 'towel-stuff']) l = [dist.name for dist in ed.provides_distribution('truffles', '1.0')] checkLists(l, ['choxie', 'cheese', 'towel-stuff']) l = [dist.name for dist in d.provides_distribution('truffles', '1.1.2')] checkLists(l, ['towel-stuff']) l = [dist.name for dist in d.provides_distribution('truffles', '1.1')] checkLists(l, ['towel-stuff']) l = [dist.name for dist in d.provides_distribution('truffles', '!=1.1,<=2.0')] checkLists(l, ['choxie', 'towel-stuff']) l = [dist.name for dist in ed.provides_distribution('truffles', '!=1.1,<=2.0')] checkLists(l, ['choxie', 'bacon', 'cheese', 'towel-stuff']) l = [dist.name for dist in d.provides_distribution('truffles', '>1.0')] checkLists(l, ['towel-stuff']) l = [dist.name for dist in d.provides_distribution('truffles', '>1.5')] checkLists(l, []) l = [dist.name for dist in ed.provides_distribution('truffles', '>1.5')] checkLists(l, ['bacon', 'truffles']) l = [dist.name for dist in d.provides_distribution('truffles', '>=1.0')] checkLists(l, ['choxie', 'towel-stuff']) l = [dist.name for dist in ed.provides_distribution('strawberry', '0.6')] checkLists(l, ['coconuts-aster', 'strawberry']) l = [dist.name for dist in ed.provides_distribution('strawberry', '>=0.5')] checkLists(l, ['coconuts-aster', 'strawberry']) l = [dist.name for dist in ed.provides_distribution('strawberry', '>0.6')] checkLists(l, []) l = [dist.name for dist in ed.provides_distribution('banana', '0.4')] checkLists(l, ['banana', 'coconuts-aster']) l = [dist.name for dist in ed.provides_distribution('banana', '>=0.3')] checkLists(l, ['banana', 'coconuts-aster']) l = [dist.name for dist in ed.provides_distribution('banana', '!=0.4')] checkLists(l, []) @requires_zlib def test_yield_distribution(self): # tests the internal function _yield_distributions checkLists = lambda x, y: self.assertEqual(sorted(x), sorted(y)) eggs = [('bacon', '0.1'), ('banana', '0.4'), ('strawberry', '0.6'), ('truffles', '5.0'), ('cheese', '2.0.2'), ('coconuts-aster', '10.3'), ('nut', 'funkyversion')] dists = [('choxie', '2.0.0.9'), ('grammar', '1.0a4'), ('towel-stuff', '0.1'), ('babar', '0.1')] d = DistributionPath(include_egg=False) d._include_dist = False checkLists([], d._yield_distributions()) d = DistributionPath(include_egg=True) d._include_dist = False found = [(dist.name, dist.version) for dist in d._yield_distributions() if dist.path.startswith(self.fake_dists_path)] checkLists(eggs, found) d = DistributionPath() found = [(dist.name, dist.version) for dist in d._yield_distributions() if dist.path.startswith(self.fake_dists_path)] checkLists(dists, found) d = DistributionPath(include_egg=True) found = [(dist.name, dist.version) for dist in d._yield_distributions() if dist.path.startswith(self.fake_dists_path)] checkLists(dists + eggs, found) def check_entry(self, entry, name, prefix, suffix, flags): self.assertEqual(entry.name, name) self.assertEqual(entry.prefix, prefix) self.assertEqual(entry.suffix, suffix) self.assertEqual(entry.flags, flags) def test_read_exports(self): d = DistributionPath().get_distribution('babar') r = d.exports self.assertIn('foo', r) d = r['foo'] self.assertIn('bar', d) self.check_entry(d['bar'], 'bar', 'baz', 'barbaz', ['a=10', 'b']) self.assertIn('bar.baz', r) d = r['bar.baz'] self.assertIn('foofoo', d) self.check_entry(d['foofoo'], 'foofoo', 'baz.foo', 'bazbar', []) self.assertIn('real', d) e = d['real'] self.check_entry(e, 'real', 'cgi', 'print_directory', []) import cgi self.assertIs(e.value, cgi.print_directory) # See issue #78. Test reading an entry_points.txt with leading spaces TEST_EXPORTS = b""" [paste.server_runner] main = waitress:serve_paste [console_scripts] waitress-serve = waitress.runner:run """ with io.BytesIO(TEST_EXPORTS) as f: exports = read_exports(f) self.assertEqual(set(exports.keys()), set(['paste.server_runner', 'console_scripts'])) def test_exports_iteration(self): d = DistributionPath() expected = set(( ('bar', 'baz', 'barbaz', ('a=10', 'b')), ('bar', 'crunchie', None, ()), ('bar', 'towel', 'towel', ()), ('baz', 'towel', 'beach_towel', ()), )) entries = list(d.get_exported_entries('foo')) for e in entries: t = e.name, e.prefix, e.suffix, tuple(e.flags) self.assertIn(t, expected) expected.remove(t) self.assertFalse(expected) # nothing left expected = set(( ('bar', 'baz', 'barbaz', ('a=10', 'b')), ('bar', 'crunchie', None, ()), ('bar', 'towel', 'towel', ()), )) entries = list(d.get_exported_entries('foo', 'bar')) for e in entries: t = e.name, e.prefix, e.suffix, tuple(e.flags) self.assertIn(t, expected) expected.remove(t) self.assertFalse(expected) # nothing left expected = set(( ('foofoo', 'baz.foo', 'bazbar', ()), ('real', 'cgi', 'print_directory', ()), ('foofoo', 'ferrero', 'rocher', ()), ('foobar', 'hoopy', 'frood', ('dent',)), )) entries = list(d.get_exported_entries('bar.baz')) for e in entries: t = e.name, e.prefix, e.suffix, tuple(e.flags) self.assertIn(t, expected) expected.remove(t) self.assertFalse(expected) # nothing left class DataFilesTestCase(GlobTestCaseBase): def assertRulesMatch(self, rules, spec): tempdir = self.build_files_tree(spec) expected = self.clean_tree(spec) result = get_resources_dests(tempdir, rules) self.assertEqual(expected, result) def clean_tree(self, spec): files = {} for path, value in spec.items(): if value is not None: files[path] = value return files def test_simple_glob(self): rules = [('', '*.tpl', '{data}')] spec = {'coucou.tpl': '{data}/coucou.tpl', 'Donotwant': None} self.assertRulesMatch(rules, spec) def test_multiple_match(self): rules = [('scripts', '*.bin', '{appdata}'), ('scripts', '*', '{appscript}')] spec = {'scripts/script.bin': '{appscript}/script.bin', 'Babarlikestrawberry': None} self.assertRulesMatch(rules, spec) def test_set_match(self): rules = [('scripts', '*.{bin,sh}', '{appscript}')] spec = {'scripts/script.bin': '{appscript}/script.bin', 'scripts/babar.sh': '{appscript}/babar.sh', 'Babarlikestrawberry': None} self.assertRulesMatch(rules, spec) def test_set_match_multiple(self): rules = [('scripts', 'script{s,}.{bin,sh}', '{appscript}')] spec = {'scripts/scripts.bin': '{appscript}/scripts.bin', 'scripts/script.sh': '{appscript}/script.sh', 'Babarlikestrawberry': None} self.assertRulesMatch(rules, spec) def test_set_match_exclude(self): rules = [('scripts', '*', '{appscript}'), ('', os.path.join('**', '*.sh'), None)] spec = {'scripts/scripts.bin': '{appscript}/scripts.bin', 'scripts/script.sh': None, 'Babarlikestrawberry': None} self.assertRulesMatch(rules, spec) def test_glob_in_base(self): rules = [('scrip*', '*.bin', '{appscript}')] spec = {'scripts/scripts.bin': '{appscript}/scripts.bin', 'scripouille/babar.bin': '{appscript}/babar.bin', 'scriptortu/lotus.bin': '{appscript}/lotus.bin', 'Babarlikestrawberry': None} self.assertRulesMatch(rules, spec) def test_recursive_glob(self): rules = [('', os.path.join('**', '*.bin'), '{binary}')] spec = {'binary0.bin': '{binary}/binary0.bin', 'scripts/binary1.bin': '{binary}/scripts/binary1.bin', 'scripts/bin/binary2.bin': '{binary}/scripts/bin/binary2.bin', 'you/kill/pandabear.guy': None} self.assertRulesMatch(rules, spec) def test_final_exemple_glob(self): rules = [ ('mailman/database/schemas/', '*', '{appdata}/schemas'), ('', os.path.join('**', '*.tpl'), '{appdata}/templates'), ('', os.path.join('developer-docs', '**', '*.txt'), '{doc}'), ('', 'README', '{doc}'), ('mailman/etc/', '*', '{config}'), ('mailman/foo/', os.path.join('**', 'bar', '*.cfg'), '{config}/baz'), ('mailman/foo/', os.path.join('**', '*.cfg'), '{config}/hmm'), ('', 'some-new-semantic.sns', '{funky-crazy-category}'), ] spec = { 'README': '{doc}/README', 'some.tpl': '{appdata}/templates/some.tpl', 'some-new-semantic.sns': '{funky-crazy-category}/some-new-semantic.sns', 'mailman/database/mailman.db': None, 'mailman/database/schemas/blah.schema': '{appdata}/schemas/blah.schema', 'mailman/etc/my.cnf': '{config}/my.cnf', 'mailman/foo/some/path/bar/my.cfg': '{config}/hmm/some/path/bar/my.cfg', 'mailman/foo/some/path/other.cfg': '{config}/hmm/some/path/other.cfg', 'developer-docs/index.txt': '{doc}/developer-docs/index.txt', 'developer-docs/api/toc.txt': '{doc}/developer-docs/api/toc.txt', } self.maxDiff = None self.assertRulesMatch(rules, spec) def test_get_file(self): # Create a fake dist temp_site_packages = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, temp_site_packages) dist_name = 'test' dist_info = os.path.join(temp_site_packages, 'test-0.1.dist-info') os.mkdir(dist_info) metadata_path = os.path.join(dist_info, 'pydist.json') resources_path = os.path.join(dist_info, 'RESOURCES') md = Metadata() md.name = 'test' md.version = '0.1' md.summary = 'test' md.write(path=metadata_path) test_path = 'test.cfg' fd, test_resource_path = tempfile.mkstemp() os.close(fd) self.addCleanup(os.remove, test_resource_path) fp = open(test_resource_path, 'w') try: fp.write('Config') finally: fp.close() fp = open(resources_path, 'w') try: fp.write('%s,%s' % (test_path, test_resource_path)) finally: fp.close() # Add fake site-packages to sys.path to retrieve fake dist self.addCleanup(sys.path.remove, temp_site_packages) sys.path.insert(0, temp_site_packages) # Try to retrieve resources paths and files d = DistributionPath() self.assertEqual(d.get_file_path(dist_name, test_path), test_resource_path) self.assertRaises(KeyError, d.get_file_path, dist_name, 'i-dont-exist') class DepGraphTestCase(LoggingCatcher, unittest.TestCase): DISTROS_DIST = ('choxie', 'grammar', 'towel-stuff') DISTROS_EGG = ('bacon', 'banana', 'strawberry', 'cheese') BAD_EGGS = ('nut',) EDGE = re.compile( r'"(?P.*)" -> "(?P.*)" \[label="(?P