tests/test_docstrings.py
author damian
Mon, 08 Feb 2010 18:17:33 +0000
changeset 3326 ce725978d11c
parent 3075 5175c093a0dd
child 3617 ae5744e97c42
permissions -rw-r--r--
Initial Python3 compatibility fixes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     1
#!/usr/bin/env python
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     2
#Copyright ReportLab Europe Ltd. 2000-2004
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     3
#see license.txt for license details
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     4
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     5
"""This is a test on a package level that find all modules,
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     6
classes, methods and functions that do not have a doc string
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     7
and lists them in individual log files.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     8
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
     9
Currently, methods with leading and trailing double underscores
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    10
are skipped.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    11
"""
3075
5175c093a0dd tests: fix RL_HOME reference problems
rgbecker
parents: 2984
diff changeset
    12
from reportlab.lib.testutils import setOutDir,SecureTestCase, GlobDirectoryWalker, outputfile, printLocation
2984
c63f149d55aa tests.utils --> reportlab.lib.testutils
rgbecker
parents: 2966
diff changeset
    13
setOutDir(__name__)
2966
c9df63ccabdf reportlab-2.2: major changes to make tests run
rgbecker
parents: 2963
diff changeset
    14
import os, sys, glob, string, re, unittest
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    15
from types import ModuleType, ClassType, MethodType, FunctionType
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    16
import reportlab
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    17
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    18
def getModuleObjects(folder, rootName, typ, pattern='*.py'):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    19
    "Get a list of all objects defined *somewhere* in a package."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    20
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    21
    # Define some abbreviations.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    22
    find = string.find
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    23
    split = string.split
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    24
    replace = string.replace
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    25
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    26
    objects = []
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    27
    lookup = {}
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    28
    for file in GlobDirectoryWalker(folder, pattern):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    29
        folder = os.path.dirname(file)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    30
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    31
        if os.path.basename(file) == '__init__.py':
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    32
            continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    33
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    34
##        if os.path.exists(os.path.join(folder, '__init__.py')):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    35
####            print 'skipping', os.path.join(folder, '__init__.py')
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    36
##            continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    37
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    38
        sys.path.insert(0, folder)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    39
        cwd = os.getcwd()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    40
        os.chdir(folder)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    41
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    42
        modName = os.path.splitext(os.path.basename(file))[0]
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    43
        prefix = folder[find(folder, rootName):]
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    44
        prefix = replace(prefix, os.sep, '.')
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    45
        mName = prefix + '.' + modName
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    46
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    47
        try:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    48
            module = __import__(mName)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    49
        except ImportError:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    50
            # Restore sys.path and working directory.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    51
            os.chdir(cwd)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    52
            del sys.path[0]
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    53
            continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    54
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    55
        # Get the 'real' (leaf) module
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    56
        # (__import__ loads only the top-level one).
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    57
        if find(mName, '.') != -1:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    58
            for part in split(mName, '.')[1:]:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    59
                module = getattr(module, part)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    60
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    61
            # Find the objects in the module's content.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    62
            modContentNames = dir(module)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    63
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    64
            # Handle modules.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    65
            if typ == ModuleType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    66
                if find(module.__name__, 'reportlab') > -1:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    67
                    objects.append((mName, module))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    68
                    continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    69
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    70
            for n in modContentNames:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    71
                obj = eval(mName + '.' + n)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    72
                # Handle functions and classes.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    73
                if typ in (FunctionType, ClassType):
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3075
diff changeset
    74
                    if type(obj) == typ and obj not in lookup:
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    75
                        if typ == ClassType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    76
                            if find(obj.__module__, rootName) != 0:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    77
                                continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    78
                        objects.append((mName, obj))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    79
                        lookup[obj] = 1
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    80
                # Handle methods.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    81
                elif typ == MethodType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    82
                    if type(obj) == ClassType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    83
                        for m in dir(obj):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    84
                            a = getattr(obj, m)
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3075
diff changeset
    85
                            if type(a) == typ and a not in lookup:
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    86
                                if find(a.im_class.__module__, rootName) != 0:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    87
                                    continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    88
                                cName = obj.__name__
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    89
                                objects.append((mName, a))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    90
                                lookup[a] = 1
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    91
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    92
        # Restore sys.path and working directory.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    93
        os.chdir(cwd)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    94
        del sys.path[0]
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    95
    return objects
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    96
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    97
class DocstringTestCase(SecureTestCase):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    98
    "Testing if objects in the ReportLab package have docstrings."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    99
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   100
    def _writeLogFile(self, objType):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   101
        "Write log file for different kind of documentable objects."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   102
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   103
        cwd = os.getcwd()
3075
5175c093a0dd tests: fix RL_HOME reference problems
rgbecker
parents: 2984
diff changeset
   104
        from reportlab.lib.testutils import RL_HOME
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   105
        objects = getModuleObjects(RL_HOME, 'reportlab', objType)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   106
        objects.sort()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   107
        os.chdir(cwd)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   108
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   109
        expl = {FunctionType:'functions',
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   110
                ClassType:'classes',
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   111
                MethodType:'methods',
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   112
                ModuleType:'modules'}[objType]
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   113
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   114
        path = outputfile("test_docstrings-%s.log" % expl)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   115
        file = open(path, 'w')
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   116
        file.write('No doc strings found for the following %s below.\n\n' % expl)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   117
        p = re.compile('__.+__')
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   118
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   119
        lines = []
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   120
        for name, obj in objects:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   121
            if objType == MethodType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   122
                n = obj.__name__
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   123
                # Skip names with leading and trailing double underscores.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   124
                if p.match(n):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   125
                    continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   126
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   127
            if objType == FunctionType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   128
                if not obj.__doc__ or len(obj.__doc__) == 0:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   129
                    lines.append("%s.%s\n" % (name, obj.__name__))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   130
            else:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   131
                if not obj.__doc__ or len(obj.__doc__) == 0:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   132
                    if objType == ClassType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   133
                        lines.append("%s.%s\n" % (obj.__module__, obj.__name__))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   134
                    elif objType == MethodType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   135
                        lines.append("%s.%s\n" % (obj.im_class, obj.__name__))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   136
                    else:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   137
                        lines.append("%s\n" % (obj.__name__))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   138
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   139
        lines.sort()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   140
        for line in lines:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   141
            file.write(line)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   142
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   143
        file.close()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   144
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   145
    def test0(self):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   146
        "Test if functions have a doc string."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   147
        self._writeLogFile(FunctionType)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   148
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   149
    def test1(self):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   150
        "Test if classes have a doc string."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   151
        self._writeLogFile(ClassType)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   152
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   153
    def test2(self):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   154
        "Test if methods have a doc string."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   155
        self._writeLogFile(MethodType)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   156
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   157
    def test3(self):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   158
        "Test if modules have a doc string."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   159
        self._writeLogFile(ModuleType)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   160
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   161
def makeSuite():
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   162
    suite = unittest.TestSuite()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   163
    loader = unittest.TestLoader()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   164
    if sys.platform[:4] != 'java': suite.addTest(loader.loadTestsFromTestCase(DocstringTestCase))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   165
    return suite
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   166
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   167
#noruntests
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   168
if __name__ == "__main__":
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   169
    unittest.TextTestRunner().run(makeSuite())
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   170
    printLocation()