src/reportlab/lib/testutils.py
author robin
Tue, 19 Nov 2013 13:50:34 +0000
branchpy33
changeset 3794 398ea04239b5
parent 3721 0c93dd8ff567
child 3862 272e650eecf5
permissions -rw-r--r--
string module usage minimization
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3617
ae5744e97c42 reportlab: copyright date changes
robin
parents: 3328
diff changeset
     1
#Copyright ReportLab Europe Ltd. 2000-2012
2986
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
3794
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
    12
import sys, os, fnmatch, copy, re
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
    13
from configparser import ConfigParser
2986
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
3328
4d7f836cd947 reportlab: fix 2to3 warnings
rgbecker
parents: 3326
diff changeset
    46
        for d in D: sys.argv.remove(d)
2986
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:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
    88
            print('Logs and output files written to folder "%s"' % outDir)
2986
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
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   110
    # If CVS subfolder doesn't exist return empty list.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   111
    try:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   112
        f = open(join(folder, 'CVS', 'Entries'))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   113
    except IOError:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   114
        return []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   115
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   116
    # Return names of files and/or folders in CVS/Entries files.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   117
    allEntries = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   118
    for line in f.readlines():
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   119
        if folders and line[0] == 'D' \
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   120
           or files and line[0] != 'D':
3794
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
   121
            entry = line.split('/')[1]
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   122
            if entry:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   123
                allEntries.append(join(folder, entry))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   124
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   125
    return allEntries
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   126
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   127
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   128
# Still experimental class extending ConfigParser's behaviour.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   129
class ExtConfigParser(ConfigParser):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   130
    "A slightly extended version to return lists of strings."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   131
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   132
    pat = re.compile('\s*\[.*\]\s*')
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   133
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   134
    def getstringlist(self, section, option):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   135
        "Coerce option to a list of strings or return unchanged if that fails."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   136
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3076
diff changeset
   137
        value = ConfigParser.get(self, section, option)
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   138
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   139
        # This seems to allow for newlines inside values
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   140
        # of the config file, but be careful!!
3794
398ea04239b5 string module usage minimization
robin
parents: 3721
diff changeset
   141
        val = value.replace('\n', '')
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   142
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   143
        if self.pat.match(val):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   144
            return eval(val)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   145
        else:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   146
            return value
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   147
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   148
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   149
# This class as suggested by /F with an additional hook
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   150
# to be able to filter filenames.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   151
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   152
class GlobDirectoryWalker:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   153
    "A forward iterator that traverses files in a directory tree."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   154
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   155
    def __init__(self, directory, pattern='*'):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   156
        self.index = 0
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   157
        self.pattern = pattern
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   158
        directory.replace('/',os.sep)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   159
        if os.path.isdir(directory):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   160
            self.stack = [directory]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   161
            self.files = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   162
        else:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   163
            from reportlab.lib.utils import isCompactDistro, __loader__, rl_isdir
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   164
            if not isCompactDistro() or not __loader__ or not rl_isdir(directory):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   165
                raise ValueError('"%s" is not a directory' % directory)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   166
            self.directory = directory[len(__loader__.archive)+len(os.sep):]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   167
            pfx = self.directory+os.sep
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   168
            n = len(pfx)
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   169
            self.files = list(map(lambda x, n=n: x[n:],list(filter(lambda x,pfx=pfx: x.startswith(pfx),list(__loader__._files.keys())))))
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   170
            self.stack = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   171
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   172
    def __getitem__(self, index):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   173
        while 1:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   174
            try:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   175
                file = self.files[self.index]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   176
                self.index = self.index + 1
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   177
            except IndexError:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   178
                # pop next directory from stack
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   179
                self.directory = self.stack.pop()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   180
                self.files = os.listdir(self.directory)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   181
                # now call the hook
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   182
                self.files = self.filterFiles(self.directory, self.files)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   183
                self.index = 0
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   184
            else:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   185
                # got a filename
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   186
                fullname = os.path.join(self.directory, file)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   187
                if os.path.isdir(fullname) and not os.path.islink(fullname):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   188
                    self.stack.append(fullname)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   189
                if fnmatch.fnmatch(file, self.pattern):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   190
                    return fullname
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   191
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   192
    def filterFiles(self, folder, files):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   193
        "Filter hook, overwrite in subclasses as needed."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   194
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   195
        return files
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   196
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   197
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   198
class RestrictedGlobDirectoryWalker(GlobDirectoryWalker):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   199
    "An restricted directory tree iterator."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   200
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   201
    def __init__(self, directory, pattern='*', ignore=None):
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3076
diff changeset
   202
        GlobDirectoryWalker.__init__(self, directory, pattern)
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   203
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   204
        if ignore == None:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   205
            ignore = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   206
        self.ignoredPatterns = []
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   207
        if type(ignore) == type([]):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   208
            for p in ignore:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   209
                self.ignoredPatterns.append(p)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   210
        elif type(ignore) == type(''):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   211
            self.ignoredPatterns.append(ignore)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   212
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   213
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   214
    def filterFiles(self, folder, files):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   215
        "Filters all items from files matching patterns to ignore."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   216
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   217
        indicesToDelete = []
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   218
        for i in range(len(files)):
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   219
            f = files[i]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   220
            for p in self.ignoredPatterns:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   221
                if fnmatch.fnmatch(f, p):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   222
                    indicesToDelete.append(i)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   223
        indicesToDelete.reverse()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   224
        for i in indicesToDelete:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   225
            del files[i]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   226
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   227
        return files
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   228
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   229
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   230
class CVSGlobDirectoryWalker(GlobDirectoryWalker):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   231
    "An directory tree iterator that checks for CVS data."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   232
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   233
    def filterFiles(self, folder, files):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   234
        """Filters files not listed in CVS subfolder.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   235
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   236
        This will look in the CVS subfolder of 'folder' for
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   237
        a file named 'Entries' and filter all elements from
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   238
        the 'files' list that are not listed in 'Entries'.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   239
        """
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   240
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   241
        join = os.path.join
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   242
        cvsFiles = getCVSEntries(folder)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   243
        if cvsFiles:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   244
            indicesToDelete = []
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   245
            for i in range(len(files)):
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   246
                f = files[i]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   247
                if join(folder, f) not in cvsFiles:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   248
                    indicesToDelete.append(i)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   249
            indicesToDelete.reverse()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   250
            for i in indicesToDelete:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   251
                del files[i]
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   252
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   253
        return files
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   254
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   255
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   256
# An experimental untested base class with additional 'security'.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   257
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   258
class SecureTestCase(unittest.TestCase):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   259
    """Secure testing base class with additional pre- and postconditions.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   260
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   261
    We try to ensure that each test leaves the environment it has
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   262
    found unchanged after the test is performed, successful or not.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   263
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   264
    Currently we restore sys.path and the working directory, but more
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   265
    of this could be added easily, like removing temporary files or
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   266
    similar things.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   267
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   268
    Use this as a base class replacing unittest.TestCase and call
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   269
    these methods in subclassed versions before doing your own
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   270
    business!
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   271
    """
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   272
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   273
    def setUp(self):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   274
        "Remember sys.path and current working directory."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   275
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   276
        self._initialPath = copy.copy(sys.path)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   277
        self._initialWorkDir = os.getcwd()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   278
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   279
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   280
    def tearDown(self):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   281
        "Restore previous sys.path and working directory."
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   282
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   283
        sys.path = self._initialPath
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   284
        os.chdir(self._initialWorkDir)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   285
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   286
class NearTestCase(unittest.TestCase):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   287
    def assertNear(a,b,accuracy=1e-5):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   288
        if isinstance(a,(float,int)):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   289
            if abs(a-b)>accuracy:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   290
                raise AssertionError("%s not near %s" % (a, b))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   291
        else:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   292
            for ae,be in zip(a,b):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   293
                if abs(ae-be)>accuracy:
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   294
                    raise AssertionError("%s not near %s" % (a, b))
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   295
    assertNear = staticmethod(assertNear)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   296
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   297
class ScriptThatMakesFileTest(unittest.TestCase):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   298
    """Runs a Python script at OS level, expecting it to produce a file.
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   299
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   300
    It CDs to the working directory to run the script."""
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   301
    def __init__(self, scriptDir, scriptName, outFileName, verbose=0):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   302
        self.scriptDir = scriptDir
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   303
        self.scriptName = scriptName
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   304
        self.outFileName = outFileName
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   305
        self.verbose = verbose
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   306
        # normally, each instance is told which method to run)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   307
        unittest.TestCase.__init__(self)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   308
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   309
    def setUp(self):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   310
        self.cwd = os.getcwd()
3055
af8146d7cf65 Fixed wrong import - tests.utils does not exist anymore.
jonas
parents: 3029
diff changeset
   311
        global testsFolder
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   312
        scriptDir=self.scriptDir
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   313
        if not os.path.isabs(scriptDir):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   314
            scriptDir=os.path.join(testsFolder,scriptDir)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   315
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   316
        os.chdir(scriptDir)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   317
        assert os.path.isfile(self.scriptName), "Script %s not found!" % self.scriptName
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   318
        if os.path.isfile(self.outFileName):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   319
            os.remove(self.outFileName)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   320
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   321
    def tearDown(self):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   322
        os.chdir(self.cwd)
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   323
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   324
    def runTest(self):
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   325
        fmt = sys.platform=='win32' and '"%s" %s' or '%s %s'
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   326
        p = os.popen(fmt % (sys.executable,self.scriptName),'r')
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   327
        out = p.read()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   328
        if self.verbose:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   329
            print(out)
2986
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   330
        status = p.close()
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   331
        assert os.path.isfile(self.outFileName), "File %s not created!" % self.outFileName
89edcdd280a7 tests.utils --> reportlab.lib.testutils
rgbecker
parents:
diff changeset
   332