PageRenderTime 63ms CodeModel.GetById 30ms app.highlight 19ms RepoModel.GetById 11ms app.codeStats 0ms

/Lib/test/test_pyclbr.py

http://unladen-swallow.googlecode.com/
Python | 193 lines | 133 code | 31 blank | 29 comment | 55 complexity | 116f338b897b4830bf765bf383397298 MD5 | raw file
  1'''
  2   Test cases for pyclbr.py
  3   Nick Mathewson
  4'''
  5from test.test_support import run_unittest
  6import sys
  7from types import ClassType, FunctionType, MethodType, BuiltinFunctionType
  8import pyclbr
  9from unittest import TestCase
 10
 11StaticMethodType = type(staticmethod(lambda: None))
 12ClassMethodType = type(classmethod(lambda c: None))
 13
 14# This next line triggers an error on old versions of pyclbr.
 15
 16from commands import getstatus
 17
 18# Here we test the python class browser code.
 19#
 20# The main function in this suite, 'testModule', compares the output
 21# of pyclbr with the introspected members of a module.  Because pyclbr
 22# is imperfect (as designed), testModule is called with a set of
 23# members to ignore.
 24
 25class PyclbrTest(TestCase):
 26
 27    def assertListEq(self, l1, l2, ignore):
 28        ''' succeed iff {l1} - {ignore} == {l2} - {ignore} '''
 29        missing = (set(l1) ^ set(l2)) - set(ignore)
 30        if missing:
 31            print >>sys.stderr, "l1=%r\nl2=%r\nignore=%r" % (l1, l2, ignore)
 32            self.fail("%r missing" % missing.pop())
 33
 34    def assertHasattr(self, obj, attr, ignore):
 35        ''' succeed iff hasattr(obj,attr) or attr in ignore. '''
 36        if attr in ignore: return
 37        if not hasattr(obj, attr): print "???", attr
 38        self.failUnless(hasattr(obj, attr),
 39                        'expected hasattr(%r, %r)' % (obj, attr))
 40
 41
 42    def assertHaskey(self, obj, key, ignore):
 43        ''' succeed iff obj.has_key(key) or key in ignore. '''
 44        if key in ignore: return
 45        if not obj.has_key(key):
 46            print >>sys.stderr, "***",key
 47        self.failUnless(obj.has_key(key))
 48
 49    def assertEqualsOrIgnored(self, a, b, ignore):
 50        ''' succeed iff a == b or a in ignore or b in ignore '''
 51        if a not in ignore and b not in ignore:
 52            self.assertEquals(a, b)
 53
 54    def checkModule(self, moduleName, module=None, ignore=()):
 55        ''' succeed iff pyclbr.readmodule_ex(modulename) corresponds
 56            to the actual module object, module.  Any identifiers in
 57            ignore are ignored.   If no module is provided, the appropriate
 58            module is loaded with __import__.'''
 59
 60        if module is None:
 61            # Import it.
 62            # ('<silly>' is to work around an API silliness in __import__)
 63            module = __import__(moduleName, globals(), {}, ['<silly>'])
 64
 65        dict = pyclbr.readmodule_ex(moduleName)
 66
 67        def ismethod(oclass, obj, name):
 68            classdict = oclass.__dict__
 69            if isinstance(obj, FunctionType):
 70                if not isinstance(classdict[name], StaticMethodType):
 71                    return False
 72            else:
 73                if not  isinstance(obj, MethodType):
 74                    return False
 75                if obj.im_self is not None:
 76                    if (not isinstance(classdict[name], ClassMethodType) or
 77                        obj.im_self is not oclass):
 78                        return False
 79                else:
 80                    if not isinstance(classdict[name], FunctionType):
 81                        return False
 82
 83            objname = obj.__name__
 84            if objname.startswith("__") and not objname.endswith("__"):
 85                objname = "_%s%s" % (obj.im_class.__name__, objname)
 86            return objname == name
 87
 88        # Make sure the toplevel functions and classes are the same.
 89        for name, value in dict.items():
 90            if name in ignore:
 91                continue
 92            self.assertHasattr(module, name, ignore)
 93            py_item = getattr(module, name)
 94            if isinstance(value, pyclbr.Function):
 95                self.assert_(isinstance(py_item, (FunctionType, BuiltinFunctionType)))
 96                if py_item.__module__ != moduleName:
 97                    continue   # skip functions that came from somewhere else
 98                self.assertEquals(py_item.__module__, value.module)
 99            else:
100                self.failUnless(isinstance(py_item, (ClassType, type)))
101                if py_item.__module__ != moduleName:
102                    continue   # skip classes that came from somewhere else
103
104                real_bases = [base.__name__ for base in py_item.__bases__]
105                pyclbr_bases = [ getattr(base, 'name', base)
106                                 for base in value.super ]
107
108                try:
109                    self.assertListEq(real_bases, pyclbr_bases, ignore)
110                except:
111                    print >>sys.stderr, "class=%s" % py_item
112                    raise
113
114                actualMethods = []
115                for m in py_item.__dict__.keys():
116                    if ismethod(py_item, getattr(py_item, m), m):
117                        actualMethods.append(m)
118                foundMethods = []
119                for m in value.methods.keys():
120                    if m[:2] == '__' and m[-2:] != '__':
121                        foundMethods.append('_'+name+m)
122                    else:
123                        foundMethods.append(m)
124
125                try:
126                    self.assertListEq(foundMethods, actualMethods, ignore)
127                    self.assertEquals(py_item.__module__, value.module)
128
129                    self.assertEqualsOrIgnored(py_item.__name__, value.name,
130                                               ignore)
131                    # can't check file or lineno
132                except:
133                    print >>sys.stderr, "class=%s" % py_item
134                    raise
135
136        # Now check for missing stuff.
137        def defined_in(item, module):
138            if isinstance(item, ClassType):
139                return item.__module__ == module.__name__
140            if isinstance(item, FunctionType):
141                return item.func_globals is module.__dict__
142            return False
143        for name in dir(module):
144            item = getattr(module, name)
145            if isinstance(item,  (ClassType, FunctionType)):
146                if defined_in(item, module):
147                    self.assertHaskey(dict, name, ignore)
148
149    def test_easy(self):
150        self.checkModule('pyclbr')
151        self.checkModule('doctest')
152        self.checkModule('rfc822')
153        self.checkModule('difflib')
154
155    def test_decorators(self):
156        # XXX: See comment in pyclbr_input.py for a test that would fail
157        #      if it were not commented out.
158        #
159        self.checkModule('test.pyclbr_input')
160
161    def test_others(self):
162        cm = self.checkModule
163
164        # These were once about the 10 longest modules
165        cm('random', ignore=('Random',))  # from _random import Random as CoreGenerator
166        cm('cgi', ignore=('log',))      # set with = in module
167        cm('urllib', ignore=('_CFNumberToInt32',
168                             '_CStringFromCFString',
169                             '_CFSetup',
170                             'getproxies_registry',
171                             'proxy_bypass_registry',
172                             'proxy_bypass_macosx_sysconf',
173                             'open_https',
174                             'getproxies_macosx_sysconf',
175                             'getproxies_internetconfig',)) # not on all platforms
176        cm('pickle')
177        cm('aifc', ignore=('openfp',))  # set with = in module
178        cm('Cookie')
179        cm('sre_parse', ignore=('dump',)) # from sre_constants import *
180        cm('pdb')
181        cm('pydoc')
182
183        # Tests for modules inside packages
184        cm('email.parser')
185        cm('test.test_pyclbr')
186
187
188def test_main():
189    run_unittest(PyclbrTest)
190
191
192if __name__ == "__main__":
193    test_main()