src/reportlab/lib/testutils.py
author rgbecker
Thu, 22 Jan 2009 16:53:05 +0000
changeset 3076 6a959200100d
parent 3074 b7270812af81
child 3326 ce725978d11c
child 3467 4f25b3a34c5f
permissions -rw-r--r--
testutils.py: make setOutDir put testsFolder parent on path
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
     1
#Copyright ReportLab Europe Ltd. 2000-2008
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
     2
#see license.txt for license details
3029
eded59f94021 adding docstrings to lib
andy
parents: 2988
diff changeset
     3
__version__='''$Id$'''
eded59f94021 adding docstrings to lib
andy
parents: 2988
diff changeset
     4
__doc__="""Provides support for the test suite.
eded59f94021 adding docstrings to lib
andy
parents: 2988
diff changeset
     5
eded59f94021 adding docstrings to lib
andy
parents: 2988
diff changeset
     6
The test suite as a whole, and individual tests, need to share
eded59f94021 adding docstrings to lib
andy
parents: 2988
diff changeset
     7
certain support functions.  We have to put these in here so they
eded59f94021 adding docstrings to lib
andy
parents: 2988
diff changeset
     8
can always be imported, and so that individual tests need to import
eded59f94021 adding docstrings to lib
andy
parents: 2988
diff changeset
     9
nothing more than "reportlab.whatever..."
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    10
"""
3029
eded59f94021 adding docstrings to lib
andy
parents: 2988
diff changeset
    11
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    12
import sys, os, string, fnmatch, copy, re
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    13
from ConfigParser import ConfigParser
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    14
import unittest
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    15
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    16
# Helper functions.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    17
def isWritable(D):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    18
    try:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    19
        fn = '00DELETE.ME'
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    20
        f = open(fn, 'w')
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    21
        f.write('test of writability - can be deleted')
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    22
        f.close()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    23
        if os.path.isfile(fn):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    24
            os.remove(fn)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    25
            return 1
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    26
    except:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    27
        return 0
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    28
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    29
_OUTDIR = None
2988
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    30
RL_HOME = None
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    31
testsFolder = None
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    32
def setOutDir(name):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    33
    """Is it a writable file system distro being invoked within
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    34
    test directory?  If so, can write test output here.  If not,
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    35
    it had better go in a temp directory.  Only do this once per
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    36
    process"""
2988
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    37
    global _OUTDIR, RL_HOME, testsFolder
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    38
    if _OUTDIR: return _OUTDIR
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    39
    D = [d[9:] for d in sys.argv if d.startswith('--outdir=')]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    40
    if D:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    41
        _OUTDIR = D[-1]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    42
        try:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    43
            os.makedirs(_OUTDIR)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    44
        except:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    45
            pass
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    46
        map(sys.argv.remove,D)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    47
    else:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    48
        assert name=='__main__',"setOutDir should only be called in the main script"
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    49
        scriptDir=os.path.dirname(sys.argv[0])
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    50
        if not scriptDir: scriptDir=os.getcwd()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    51
        _OUTDIR = scriptDir
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    52
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    53
    if not isWritable(_OUTDIR):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    54
        _OUTDIR = get_rl_tempdir('reportlab_test')
2988
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    55
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    56
    import reportlab
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    57
    RL_HOME=reportlab.__path__[0]
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    58
    if not os.path.isabs(RL_HOME): RL_HOME=os.path.normpath(os.path.abspath(RL_HOME))
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    59
    topDir = os.path.dirname(RL_HOME)
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    60
    testsFolder = os.path.join(topDir,'tests')
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    61
    if not os.path.isdir(testsFolder):
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    62
        testsFolder = os.path.join(os.path.dirname(topDir),'tests')
1540a4be3b99 reportlab: fixes to lib\testutils.py for testsFolder creation
rgbecker
parents: 2986
diff changeset
    63
    if not os.path.isdir(testsFolder):
3074
b7270812af81 reportlab: another attempt at fixing testsFolder
rgbecker
parents: 3055
diff changeset
    64
        if name=='__main__':
b7270812af81 reportlab: another attempt at fixing testsFolder
rgbecker
parents: 3055
diff changeset
    65
            scriptDir=os.path.dirname(sys.argv[0])
b7270812af81 reportlab: another attempt at fixing testsFolder
rgbecker
parents: 3055
diff changeset
    66
            if not scriptDir: scriptDir=os.getcwd()
b7270812af81 reportlab: another attempt at fixing testsFolder
rgbecker
parents: 3055
diff changeset
    67
            testsFolder = os.path.abspath(scriptDir)
b7270812af81 reportlab: another attempt at fixing testsFolder
rgbecker
parents: 3055
diff changeset
    68
        else:
b7270812af81 reportlab: another attempt at fixing testsFolder
rgbecker
parents: 3055
diff changeset
    69
            testsFolder = None
3076
6a959200100d testutils.py: make setOutDir put testsFolder parent on path
rgbecker
parents: 3074
diff changeset
    70
    if testsFolder:
6a959200100d testutils.py: make setOutDir put testsFolder parent on path
rgbecker
parents: 3074
diff changeset
    71
        sys.path.insert(0,os.path.dirname(testsFolder))
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    72
    return _OUTDIR
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    73
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    74
def outputfile(fn):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    75
    """This works out where to write test output.  If running
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    76
    code in a locked down file system, this will be a
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    77
    temp directory; otherwise, the output of 'test_foo.py' will
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    78
    normally be a file called 'test_foo.pdf', next door.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    79
    """
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    80
    D = setOutDir(__name__)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    81
    if fn: D = os.path.join(D,fn)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    82
    return D
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    83
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    84
def printLocation(depth=1):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    85
    if sys._getframe(depth).f_locals.get('__name__')=='__main__':
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    86
        outDir = outputfile('')
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    87
        if outDir!=_OUTDIR:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    88
            print 'Logs and output files written to folder "%s"' % outDir
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    89
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    90
def makeSuiteForClasses(*classes):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    91
    "Return a test suite with tests loaded from provided classes."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    92
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    93
    suite = unittest.TestSuite()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    94
    loader = unittest.TestLoader()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    95
    for C in classes:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    96
        suite.addTest(loader.loadTestsFromTestCase(C))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    97
    return suite
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    98
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
    99
def getCVSEntries(folder, files=1, folders=0):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   100
    """Returns a list of filenames as listed in the CVS/Entries file.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   101
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   102
    'folder' is the folder that should contain the CVS subfolder.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   103
    If there is no such subfolder an empty list is returned.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   104
    'files' is a boolean; 1 and 0 means to return files or not.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   105
    'folders' is a boolean; 1 and 0 means to return folders or not.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   106
    """
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   107
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   108
    join = os.path.join
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   109
    split = string.split
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   110
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   111
    # If CVS subfolder doesn't exist return empty list.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   112
    try:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   113
        f = open(join(folder, 'CVS', 'Entries'))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   114
    except IOError:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   115
        return []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   116
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   117
    # Return names of files and/or folders in CVS/Entries files.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   118
    allEntries = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   119
    for line in f.readlines():
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   120
        if folders and line[0] == 'D' \
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   121
           or files and line[0] != 'D':
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   122
            entry = split(line, '/')[1]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   123
            if entry:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   124
                allEntries.append(join(folder, entry))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   125
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   126
    return allEntries
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   127
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   128
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   129
# Still experimental class extending ConfigParser's behaviour.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   130
class ExtConfigParser(ConfigParser):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   131
    "A slightly extended version to return lists of strings."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   132
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   133
    pat = re.compile('\s*\[.*\]\s*')
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   134
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   135
    def getstringlist(self, section, option):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   136
        "Coerce option to a list of strings or return unchanged if that fails."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   137
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   138
        value = apply(ConfigParser.get, (self, section, option))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   139
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   140
        # This seems to allow for newlines inside values
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   141
        # of the config file, but be careful!!
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   142
        val = string.replace(value, '\n', '')
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   143
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   144
        if self.pat.match(val):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   145
            return eval(val)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   146
        else:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   147
            return value
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   148
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   149
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   150
# This class as suggested by /F with an additional hook
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   151
# to be able to filter filenames.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   152
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   153
class GlobDirectoryWalker:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   154
    "A forward iterator that traverses files in a directory tree."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   155
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   156
    def __init__(self, directory, pattern='*'):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   157
        self.index = 0
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   158
        self.pattern = pattern
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   159
        directory.replace('/',os.sep)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   160
        if os.path.isdir(directory):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   161
            self.stack = [directory]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   162
            self.files = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   163
        else:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   164
            from reportlab.lib.utils import isCompactDistro, __loader__, rl_isdir
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   165
            if not isCompactDistro() or not __loader__ or not rl_isdir(directory):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   166
                raise ValueError('"%s" is not a directory' % directory)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   167
            self.directory = directory[len(__loader__.archive)+len(os.sep):]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   168
            pfx = self.directory+os.sep
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   169
            n = len(pfx)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   170
            self.files = map(lambda x, n=n: x[n:],filter(lambda x,pfx=pfx: x.startswith(pfx),__loader__._files.keys()))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   171
            self.stack = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   172
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   173
    def __getitem__(self, index):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   174
        while 1:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   175
            try:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   176
                file = self.files[self.index]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   177
                self.index = self.index + 1
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   178
            except IndexError:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   179
                # pop next directory from stack
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   180
                self.directory = self.stack.pop()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   181
                self.files = os.listdir(self.directory)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   182
                # now call the hook
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   183
                self.files = self.filterFiles(self.directory, self.files)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   184
                self.index = 0
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   185
            else:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   186
                # got a filename
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   187
                fullname = os.path.join(self.directory, file)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   188
                if os.path.isdir(fullname) and not os.path.islink(fullname):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   189
                    self.stack.append(fullname)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   190
                if fnmatch.fnmatch(file, self.pattern):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   191
                    return fullname
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   192
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   193
    def filterFiles(self, folder, files):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   194
        "Filter hook, overwrite in subclasses as needed."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   195
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   196
        return files
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   197
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   198
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   199
class RestrictedGlobDirectoryWalker(GlobDirectoryWalker):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   200
    "An restricted directory tree iterator."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   201
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   202
    def __init__(self, directory, pattern='*', ignore=None):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   203
        apply(GlobDirectoryWalker.__init__, (self, directory, pattern))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   204
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   205
        if ignore == None:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   206
            ignore = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   207
        self.ignoredPatterns = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   208
        if type(ignore) == type([]):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   209
            for p in ignore:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   210
                self.ignoredPatterns.append(p)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   211
        elif type(ignore) == type(''):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   212
            self.ignoredPatterns.append(ignore)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   213
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   214
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   215
    def filterFiles(self, folder, files):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   216
        "Filters all items from files matching patterns to ignore."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   217
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   218
        indicesToDelete = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   219
        for i in xrange(len(files)):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   220
            f = files[i]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   221
            for p in self.ignoredPatterns:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   222
                if fnmatch.fnmatch(f, p):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   223
                    indicesToDelete.append(i)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   224
        indicesToDelete.reverse()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   225
        for i in indicesToDelete:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   226
            del files[i]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   227
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   228
        return files
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   229
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   230
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   231
class CVSGlobDirectoryWalker(GlobDirectoryWalker):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   232
    "An directory tree iterator that checks for CVS data."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   233
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   234
    def filterFiles(self, folder, files):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   235
        """Filters files not listed in CVS subfolder.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   236
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   237
        This will look in the CVS subfolder of 'folder' for
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   238
        a file named 'Entries' and filter all elements from
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   239
        the 'files' list that are not listed in 'Entries'.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   240
        """
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   241
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   242
        join = os.path.join
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   243
        cvsFiles = getCVSEntries(folder)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   244
        if cvsFiles:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   245
            indicesToDelete = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   246
            for i in xrange(len(files)):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   247
                f = files[i]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   248
                if join(folder, f) not in cvsFiles:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   249
                    indicesToDelete.append(i)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   250
            indicesToDelete.reverse()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   251
            for i in indicesToDelete:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   252
                del files[i]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   253
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   254
        return files
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   255
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   256
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   257
# An experimental untested base class with additional 'security'.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   258
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   259
class SecureTestCase(unittest.TestCase):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   260
    """Secure testing base class with additional pre- and postconditions.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   261
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   262
    We try to ensure that each test leaves the environment it has
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   263
    found unchanged after the test is performed, successful or not.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   264
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   265
    Currently we restore sys.path and the working directory, but more
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   266
    of this could be added easily, like removing temporary files or
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   267
    similar things.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   268
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   269
    Use this as a base class replacing unittest.TestCase and call
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   270
    these methods in subclassed versions before doing your own
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   271
    business!
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   272
    """
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   273
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   274
    def setUp(self):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   275
        "Remember sys.path and current working directory."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   276
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   277
        self._initialPath = copy.copy(sys.path)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   278
        self._initialWorkDir = os.getcwd()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   279
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   280
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   281
    def tearDown(self):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   282
        "Restore previous sys.path and working directory."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   283
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   284
        sys.path = self._initialPath
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   285
        os.chdir(self._initialWorkDir)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   286
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   287
class NearTestCase(unittest.TestCase):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   288
    def assertNear(a,b,accuracy=1e-5):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   289
        if isinstance(a,(float,int)):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   290
            if abs(a-b)>accuracy:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   291
                raise AssertionError("%s not near %s" % (a, b))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   292
        else:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   293
            for ae,be in zip(a,b):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   294
                if abs(ae-be)>accuracy:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   295
                    raise AssertionError("%s not near %s" % (a, b))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   296
    assertNear = staticmethod(assertNear)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   297
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   298
class ScriptThatMakesFileTest(unittest.TestCase):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   299
    """Runs a Python script at OS level, expecting it to produce a file.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   300
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   301
    It CDs to the working directory to run the script."""
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   302
    def __init__(self, scriptDir, scriptName, outFileName, verbose=0):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   303
        self.scriptDir = scriptDir
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   304
        self.scriptName = scriptName
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   305
        self.outFileName = outFileName
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   306
        self.verbose = verbose
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   307
        # normally, each instance is told which method to run)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   308
        unittest.TestCase.__init__(self)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   309
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   310
    def setUp(self):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   311
        self.cwd = os.getcwd()
3055
af8146d7cf65 Fixed wrong import - tests.utils does not exist anymore.
jonas
parents: 3029
diff changeset
   312
        global testsFolder
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   313
        scriptDir=self.scriptDir
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   314
        if not os.path.isabs(scriptDir):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   315
            scriptDir=os.path.join(testsFolder,scriptDir)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   316
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   317
        os.chdir(scriptDir)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   318
        assert os.path.isfile(self.scriptName), "Script %s not found!" % self.scriptName
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   319
        if os.path.isfile(self.outFileName):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   320
            os.remove(self.outFileName)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   321
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   322
    def tearDown(self):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   323
        os.chdir(self.cwd)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   324
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   325
    def runTest(self):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   326
        fmt = sys.platform=='win32' and '"%s" %s' or '%s %s'
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   327
        p = os.popen(fmt % (sys.executable,self.scriptName),'r')
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   328
        out = p.read()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   329
        if self.verbose:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   330
            print out
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   331
        status = p.close()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   332
        assert os.path.isfile(self.outFileName), "File %s not created!" % self.outFileName
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   333