Auto-enabled system contacts for all contacts
[theonering] / tests / test_utils.py
1 #!/usr/bin/env python
2
3
4 from __future__ import with_statement
5
6 import inspect
7 import contextlib
8 import functools
9
10
11 def TODO(func):
12         """
13         unittest test method decorator that ignores
14         exceptions raised by test
15
16         Used to annotate test methods for code that may
17         not be written yet.  Ignores failures in the
18         annotated test method; fails if the text
19         unexpectedly succeeds.
20         !author http://kbyanc.blogspot.com/2007/06/pythons-unittest-module-aint-that-bad.html
21
22         Example:
23         >>> import unittest
24         >>> class ExampleTestCase(unittest.TestCase):
25         ...     @TODO
26         ...     def testToDo(self):
27         ...             MyModule.DoesNotExistYet('boo')
28         ...
29         """
30
31         @functools.wraps(func)
32         def wrapper(*args, **kw):
33                 try:
34                         func(*args, **kw)
35                         succeeded = True
36                 except:
37                         succeeded = False
38                 assert succeeded is False, \
39                         "%s marked TODO but passed" % func.__name__
40         return wrapper
41
42
43 def PlatformSpecific(platformList):
44         """
45         unittest test method decorator that only
46         runs test method if os.name is in the
47         given list of platforms
48         !author http://kbyanc.blogspot.com/2007/06/pythons-unittest-module-aint-that-bad.html
49         Example:
50         >>> import unittest
51         >>> class ExampleTestCase(unittest.TestCase):
52         ...     @PlatformSpecific(('mac', ))
53         ...     def testMacOnly(self):
54         ...             MyModule.SomeMacSpecificFunction()
55         ...
56         """
57
58         def decorator(func):
59                 import os
60
61                 @functools.wraps(func)
62                 def wrapper(*args, **kw):
63                         if os.name in platformList:
64                                 return func(*args, **kw)
65                 return wrapper
66         return decorator
67
68
69 def CheckReferences(func):
70         """
71         !author http://kbyanc.blogspot.com/2007/06/pythons-unittest-module-aint-that-bad.html
72         """
73
74         @functools.wraps(func)
75         def wrapper(*args, **kw):
76                 refCounts = []
77                 for i in range(5):
78                         func(*args, **kw)
79                         refCounts.append(XXXGetRefCount())
80                 assert min(refCounts) != max(refCounts), "Reference counts changed - %r" % refCounts
81
82         return wrapper
83
84
85 @contextlib.contextmanager
86 def expected(exception):
87         """
88         >>> with expected2(ZeroDivisionError):
89         ...     1 / 0
90         >>> with expected2(AssertionError("expected ZeroDivisionError to have been thrown")):
91         ...     with expected(ZeroDivisionError):
92         ...             1 / 2
93         Traceback (most recent call last):
94                 File "/usr/lib/python2.5/doctest.py", line 1228, in __run
95                         compileflags, 1) in test.globs
96                 File "<doctest libraries.recipes.context.expected[1]>", line 3, in <module>
97                         1 / 2
98                 File "/media/data/Personal/Development/bzr/Recollection-trunk/src/libraries/recipes/context.py", line 139, in __exit__
99                         assert t is not None, ("expected {0:%s} to have been thrown" % (self._t.__name__))
100         AssertionError: expected {0:ZeroDivisionError} to have been thrown
101         >>> with expected2(Exception("foo")):
102         ...     raise Exception("foo")
103         >>> with expected2(Exception("bar")):
104         ...     with expected(Exception("foo")): # this won't catch it
105         ...             raise Exception("bar")
106         ...     assert False, "should not see me"
107         >>> with expected2(Exception("can specify")):
108         ...     raise Exception("can specify prefixes")
109         >>> with expected2(Exception("Base class fun")):
110         True
111         >>> True
112         False
113         """
114         if isinstance(exception, Exception):
115                 excType, excValue = type(exception), str(exception)
116         elif isinstance(exception, type):
117                 excType, excValue = exception, ""
118
119         try:
120                 yield
121         except Exception, e:
122                 if not (excType in inspect.getmro(type(e)) and str(e).startswith(excValue)):
123                         raise
124         else:
125                 raise AssertionError("expected {0:%s} to have been thrown" % excType.__name__)
126
127
128 if __name__ == "__main__":
129         import doctest
130         doctest.testmod()