tests/test_docstrings.py
author robin
Tue, 19 Nov 2013 13:50:34 +0000
branchpy33
changeset 3794 398ea04239b5
parent 3721 0c93dd8ff567
child 3804 79c6b1df0eca
permissions -rw-r--r--
string module usage minimization
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
3617
ae5744e97c42 reportlab: copyright date changes
robin
parents: 3326
diff changeset
     2
#Copyright ReportLab Europe Ltd. 2000-2012
2963
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__)
3794
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
    14
import os, sys, glob, 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
    objects = []
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    21
    lookup = {}
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    22
    for file in GlobDirectoryWalker(folder, pattern):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    23
        folder = os.path.dirname(file)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    24
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    25
        if os.path.basename(file) == '__init__.py':
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    26
            continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    27
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    28
##        if os.path.exists(os.path.join(folder, '__init__.py')):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    29
####            print 'skipping', os.path.join(folder, '__init__.py')
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    30
##            continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    31
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    32
        sys.path.insert(0, folder)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    33
        cwd = os.getcwd()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    34
        os.chdir(folder)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    35
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    36
        modName = os.path.splitext(os.path.basename(file))[0]
3794
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
    37
        prefix = folder[folder.find(rootName):]
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
    38
        prefix = prefix.replace(os.sep,'.')
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    39
        mName = prefix + '.' + modName
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    40
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    41
        try:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    42
            module = __import__(mName)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    43
        except ImportError:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    44
            # Restore sys.path and working directory.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    45
            os.chdir(cwd)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    46
            del sys.path[0]
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    47
            continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    48
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    49
        # Get the 'real' (leaf) module
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    50
        # (__import__ loads only the top-level one).
3794
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
    51
        if mName.find('.') != -1:
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
    52
            for part in mName.split('.')[1:]:
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    53
                module = getattr(module, part)
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
            # Find the objects in the module's content.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    56
            modContentNames = dir(module)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    57
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    58
            # Handle modules.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    59
            if typ == ModuleType:
3794
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
    60
                if module.__name__.find('reportlab') > -1:
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    61
                    objects.append((mName, module))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    62
                    continue
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
            for n in modContentNames:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    65
                obj = eval(mName + '.' + n)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    66
                # Handle functions and classes.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    67
                if typ in (FunctionType, ClassType):
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3075
diff changeset
    68
                    if type(obj) == typ and obj not in lookup:
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    69
                        if typ == ClassType:
3794
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
    70
                            if obj.__module__.find(rootName) != 0:
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    71
                                continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    72
                        objects.append((mName, obj))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    73
                        lookup[obj] = 1
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    74
                # Handle methods.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    75
                elif typ == MethodType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    76
                    if type(obj) == ClassType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    77
                        for m in dir(obj):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    78
                            a = getattr(obj, m)
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3075
diff changeset
    79
                            if type(a) == typ and a not in lookup:
3794
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
    80
                                if a.__self__.__class__.__module__.find(rootName) != 0:
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    81
                                    continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    82
                                cName = obj.__name__
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    83
                                objects.append((mName, a))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    84
                                lookup[a] = 1
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    85
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    86
        # Restore sys.path and working directory.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    87
        os.chdir(cwd)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    88
        del sys.path[0]
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    89
    return objects
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    90
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    91
class DocstringTestCase(SecureTestCase):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    92
    "Testing if objects in the ReportLab package have docstrings."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    93
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    94
    def _writeLogFile(self, objType):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    95
        "Write log file for different kind of documentable 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
        cwd = os.getcwd()
3075
5175c093a0dd tests: fix RL_HOME reference problems
rgbecker
parents: 2984
diff changeset
    98
        from reportlab.lib.testutils import RL_HOME
2963
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
    99
        objects = getModuleObjects(RL_HOME, 'reportlab', objType)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   100
        objects.sort()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   101
        os.chdir(cwd)
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
        expl = {FunctionType:'functions',
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   104
                ClassType:'classes',
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   105
                MethodType:'methods',
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   106
                ModuleType:'modules'}[objType]
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   107
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   108
        path = outputfile("test_docstrings-%s.log" % expl)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   109
        file = open(path, 'w')
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   110
        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
   111
        p = re.compile('__.+__')
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   112
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   113
        lines = []
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   114
        for name, obj in objects:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   115
            if objType == MethodType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   116
                n = obj.__name__
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   117
                # Skip names with leading and trailing double underscores.
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   118
                if p.match(n):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   119
                    continue
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   120
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   121
            if objType == FunctionType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   122
                if not obj.__doc__ or len(obj.__doc__) == 0:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   123
                    lines.append("%s.%s\n" % (name, obj.__name__))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   124
            else:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   125
                if not obj.__doc__ or len(obj.__doc__) == 0:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   126
                    if objType == ClassType:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   127
                        lines.append("%s.%s\n" % (obj.__module__, obj.__name__))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   128
                    elif objType == MethodType:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   129
                        lines.append("%s.%s\n" % (obj.__self__.__class__, obj.__name__))
2963
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
                        lines.append("%s\n" % (obj.__name__))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   132
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   133
        lines.sort()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   134
        for line in lines:
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   135
            file.write(line)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   136
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   137
        file.close()
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
    def test0(self):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   140
        "Test if functions have a doc string."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   141
        self._writeLogFile(FunctionType)
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
    def test1(self):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   144
        "Test if classes have a doc string."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   145
        self._writeLogFile(ClassType)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   146
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   147
    def test2(self):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   148
        "Test if methods have a doc string."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   149
        self._writeLogFile(MethodType)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   150
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   151
    def test3(self):
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   152
        "Test if modules have a doc string."
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   153
        self._writeLogFile(ModuleType)
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   154
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   155
def makeSuite():
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   156
    suite = unittest.TestSuite()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   157
    loader = unittest.TestLoader()
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   158
    if sys.platform[:4] != 'java': suite.addTest(loader.loadTestsFromTestCase(DocstringTestCase))
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   159
    return suite
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
#noruntests
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   162
if __name__ == "__main__":
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   163
    unittest.TextTestRunner().run(makeSuite())
c414c0ab69e7 reportlab-2.2: first stage of major re-org
rgbecker
parents:
diff changeset
   164
    printLocation()