Merge branch 'master' of ssh://git.samba.org/data/git/samba
[nivanova/samba-autobuild/.git] / lib / subunit / python / tests / TestUtil.py
1 # Copyright (c) 2004 Canonical Limited
2 #       Author: Robert Collins <robert.collins@canonical.com>
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 #
18
19 import sys
20 import logging
21 import unittest
22
23
24 class LogCollector(logging.Handler):
25     def __init__(self):
26         logging.Handler.__init__(self)
27         self.records=[]
28     def emit(self, record):
29         self.records.append(record.getMessage())
30
31
32 def makeCollectingLogger():
33     """I make a logger instance that collects its logs for programmatic analysis
34     -> (logger, collector)"""
35     logger=logging.Logger("collector")
36     handler=LogCollector()
37     handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
38     logger.addHandler(handler)
39     return logger, handler
40
41
42 def visitTests(suite, visitor):
43     """A foreign method for visiting the tests in a test suite."""
44     for test in suite._tests:
45         #Abusing types to avoid monkey patching unittest.TestCase.
46         # Maybe that would be better?
47         try:
48             test.visit(visitor)
49         except AttributeError:
50             if isinstance(test, unittest.TestCase):
51                 visitor.visitCase(test)
52             elif isinstance(test, unittest.TestSuite):
53                 visitor.visitSuite(test)
54                 visitTests(test, visitor)
55             else:
56                 print "unvisitable non-unittest.TestCase element %r (%r)" % (test, test.__class__)
57
58
59 class TestSuite(unittest.TestSuite):
60     """I am an extended TestSuite with a visitor interface.
61     This is primarily to allow filtering of tests - and suites or
62     more in the future. An iterator of just tests wouldn't scale..."""
63
64     def visit(self, visitor):
65         """visit the composite. Visiting is depth-first.
66         current callbacks are visitSuite and visitCase."""
67         visitor.visitSuite(self)
68         visitTests(self, visitor)
69
70
71 class TestLoader(unittest.TestLoader):
72     """Custome TestLoader to set the right TestSuite class."""
73     suiteClass = TestSuite
74
75 class TestVisitor(object):
76     """A visitor for Tests"""
77     def visitSuite(self, aTestSuite):
78         pass
79     def visitCase(self, aTestCase):
80         pass