~jbaker/storm/nose_plugin

« back to all changes in this revision

Viewing changes to tests/conftest.py

  • Committer: Jamu Kakar
  • Date: 2009-11-24 18:34:34 UTC
  • mfrom: (340 storm.trunk)
  • mto: This revision was merged to the branch mainline in revision 341.
  • Revision ID: jkakar@kakar.ca-20091124183434-ambkvw9tp2byvjnc
- Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#
2
 
# Copyright (c) 2006, 2007 Canonical
3
 
#
4
 
# Written by Gustavo Niemeyer <gustavo@niemeyer.net>
5
 
#
6
 
# This file is part of Storm Object Relational Mapper.
7
 
#
8
 
# Storm is free software; you can redistribute it and/or modify
9
 
# it under the terms of the GNU Lesser General Public License as
10
 
# published by the Free Software Foundation; either version 2.1 of
11
 
# the License, or (at your option) any later version.
12
 
#
13
 
# Storm is distributed in the hope that it will be useful,
14
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
# GNU Lesser General Public License for more details.
17
 
#
18
 
# You should have received a copy of the GNU Lesser General Public License
19
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 
#
21
 
"""
22
 
Machinery to make py.test interpret standard unittest.TestCase classes.
23
 
"""
24
 
from unittest import TestCase, TestResult
25
 
import doctest
26
 
import sys
27
 
 
28
 
import py.test.collect
29
 
import py.test.compat
30
 
import py.test
31
 
 
32
 
 
33
 
class PyTestResult(TestResult):
34
 
    def addFailure(self, test, exc_info):
35
 
        traceback = exc_info[2]
36
 
        while traceback.tb_next:
37
 
            traceback = traceback.tb_next
38
 
        locals = traceback.tb_frame.f_locals
39
 
        if "msg" in locals or "excClass" in locals:
40
 
            locals["__tracebackhide__"] = True
41
 
        msg = str(exc_info[1])
42
 
        if not msg:
43
 
            if "expr" in locals and "msg" in locals:
44
 
                msg = repr(locals["expr"])
45
 
            else:
46
 
                msg = "!?"
47
 
        raise py.test.Item.Failed, py.test.Item.Failed(msg=msg), exc_info[2]
48
 
    addError = addFailure
49
 
 
50
 
class PyTestCase(TestCase):
51
 
    def __init__(self, methodName="setUp"):
52
 
        super(PyTestCase, self).__init__(methodName)
53
 
 
54
 
    class Function(py.test.Function):
55
 
        def execute(self, target, *args):
56
 
            __tracebackhide__ = True
57
 
            self = target.im_self
58
 
            self.__init__(target.__name__)
59
 
            self.run(PyTestResult())
60
 
 
61
 
class PyDocTest(py.test.collect.Module):
62
 
    def __init__(self, fspath, parent=None):
63
 
        super(PyDocTest, self).__init__(fspath.basename, parent)
64
 
        self.fspath = fspath
65
 
        self._obj = None
66
 
 
67
 
    def run(self):
68
 
        return [self.name]
69
 
 
70
 
    def join(self, name):
71
 
        return self.Function(name, parent=self, obj=self.fspath)
72
 
 
73
 
    class Function(py.test.Function):
74
 
        def getpathlineno(self):
75
 
            code = py.code.Code(self.failed)
76
 
            return code.path, code.firstlineno
77
 
 
78
 
        def failed(self, msg):
79
 
            raise self.Failed(msg)
80
 
 
81
 
        def execute(self, fspath):
82
 
            failures, total = doctest.testfile(str(fspath),
83
 
                                               module_relative=False,
84
 
                                               optionflags=doctest.ELLIPSIS)
85
 
            if failures:
86
 
                __tracebackhide__ = True
87
 
                self.failed("%d doctest cases" % failures)
88
 
 
89
 
class UnitTestModule(py.test.collect.Module):
90
 
    def buildname2items(self):
91
 
        d = {}
92
 
        for name in dir(self.obj):
93
 
            testclass = None
94
 
            obj = getattr(self.obj, name)
95
 
 
96
 
            try:
97
 
                if issubclass(obj, (TestCase, PyTestCase)):
98
 
                    testclass = obj
99
 
            except TypeError:
100
 
                pass
101
 
 
102
 
            if testclass:
103
 
                d[name] = self.Class(name, parent=self)
104
 
                if not issubclass(testclass, PyTestCase):
105
 
                    queue = [testclass]
106
 
                    while queue:
107
 
                        testclass = queue.pop(0)
108
 
                        if TestCase in testclass.__bases__:
109
 
                            bases = list(testclass.__bases__)
110
 
                            bases[bases.index(TestCase)] = PyTestCase
111
 
                            testclass.__bases__ = tuple(bases)
112
 
                            break
113
 
                        queue.extend(testclass.__bases__)
114
 
        return d
115
 
 
116
 
class UnitTestDirectory(py.test.collect.Directory):
117
 
    def __init__(self, *args, **kwargs):
118
 
        if getattr(self.__class__, "__first_run__", True):
119
 
            self.__class__.__first_run__ = False
120
 
        super(UnitTestDirectory, self).__init__(*args, **kwargs)
121
 
 
122
 
    def filefilter(self, path):
123
 
        return path.check(fnmatch="*.py") and path.basename != "conftest.py"
124
 
 
125
 
    def makeitem(self, basename, filefilter=None, recfilter=None):
126
 
        path = self.fspath.join(basename)
127
 
        if path.check(fnmatch="*.txt"):
128
 
            return PyDocTest(path, parent=self)
129
 
        return super(UnitTestDirectory, self).makeitem(basename,
130
 
                                                       filefilter, recfilter)
131
 
 
132
 
Module = UnitTestModule
133
 
Directory = UnitTestDirectory