]> Repositories - Adafruit_Blinka-hackapet.git/blob - python/unittest.py
Agnostic and wrapper-specific classes now under adafruit_blinka
[Adafruit_Blinka-hackapet.git] / python / unittest.py
1 """Based on https://raw.githubusercontent.com/micropython/micropython-lib/cfa1b9cce0c93a3115bbff3886c9bbcddd9e8047/unittest/unittest.py """
2 import sys
3 class SkipTest(Exception):
4     pass
5
6 raiseException = False
7 raiseBaseException = True
8
9 class AssertRaisesContext:
10
11     def __init__(self, exc):
12         self.expected = exc
13
14     def __enter__(self):
15         return self
16
17     def __exit__(self, exc_type, exc_value, tb):
18         if exc_type is None:
19             assert False, "%r not raised" % self.expected
20         if issubclass(exc_type, self.expected):
21             return True
22         return False
23
24
25 class TestCase:
26
27     def fail(self, msg=''):
28         assert False, msg
29
30     def assertEqual(self, x, y, msg=''):
31         if not msg:
32             msg = "%r vs (expected) %r" % (x, y)
33         assert x == y, msg
34
35     def assertNotEqual(self, x, y, msg=''):
36         if not msg:
37             msg = "%r not expected to be equal %r" % (x, y)
38         assert x != y, msg
39
40     def assertAlmostEqual(self, x, y, places=None, msg='', delta=None):
41         if x == y:
42             return
43         if delta is not None and places is not None:
44             raise TypeError("specify delta or places not both")
45
46         if delta is not None:
47             if abs(x - y) <= delta:
48                 return
49             if not msg:
50                 msg = '%r != %r within %r delta' % (x, y, delta)
51         else:
52             if places is None:
53                 places = 7
54             if round(abs(y-x), places) == 0:
55                 return
56             if not msg:
57                 msg = '%r != %r within %r places' % (x, y, places)
58
59         assert False, msg
60
61     def assertNotAlmostEqual(self, x, y, places=None, msg='', delta=None):
62         if delta is not None and places is not None:
63             raise TypeError("specify delta or places not both")
64
65         if delta is not None:
66             if not (x == y) and abs(x - y) > delta:
67                 return
68             if not msg:
69                 msg = '%r == %r within %r delta' % (x, y, delta)
70         else:
71             if places is None:
72                 places = 7
73             if not (x == y) and round(abs(y-x), places) != 0:
74                 return
75             if not msg:
76                 msg = '%r == %r within %r places' % (x, y, places)
77
78         assert False, msg
79
80     def assertIs(self, x, y, msg=''):
81         if not msg:
82             msg = "%r is not %r" % (x, y)
83         assert x is y, msg
84
85     def assertIsNot(self, x, y, msg=''):
86         if not msg:
87             msg = "%r is %r" % (x, y)
88         assert x is not y, msg
89
90     def assertIsNone(self, x, msg=''):
91         if not msg:
92             msg = "%r is not None" % x
93         assert x is None, msg
94
95     def assertIsNotNone(self, x, msg=''):
96         if not msg:
97             msg = "%r is None" % x
98         assert x is not None, msg
99
100     def assertTrue(self, x, msg=''):
101         if not msg:
102             msg = "Expected %r to be True" % x
103         assert x, msg
104
105     def assertFalse(self, x, msg=''):
106         if not msg:
107             msg = "Expected %r to be False" % x
108         assert not x, msg
109
110     def assertIn(self, x, y, msg=''):
111         if not msg:
112             msg = "Expected %r to be in %r" % (x, y)
113         assert x in y, msg
114
115     def assertIsInstance(self, x, y, msg=''):
116         assert isinstance(x, y), msg
117
118     def assertRaises(self, exc, func=None, *args, **kwargs):
119         if func is None:
120             return AssertRaisesContext(exc)
121
122         try:
123             func(*args, **kwargs)
124             assert False, "%r not raised" % exc
125         except Exception as e:
126             if isinstance(e, exc):
127                 return
128             raise
129
130
131
132 def skip(msg):
133     def _decor(fun):
134         # We just replace original fun with _inner
135         def _inner(self):
136             raise SkipTest(msg)
137         return _inner
138     return _decor
139
140 def skipIf(cond, msg):
141     if not cond:
142         return lambda x: x
143     return skip(msg)
144
145 def skipUnless(cond, msg):
146     if cond:
147         return lambda x: x
148     return skip(msg)
149
150
151 class TestSuite:
152     def __init__(self):
153         self.tests = []
154     def addTest(self, cls):
155         self.tests.append(cls)
156
157 class TestRunner:
158     def run(self, suite):
159         res = TestResult()
160         for c in suite.tests:
161             run_class(c, res)
162
163         print("Ran %d tests\n" % res.testsRun)
164         if res.failuresNum > 0 or res.errorsNum > 0:
165             print("FAILED (failures=%d, errors=%d)" % (res.failuresNum, res.errorsNum))
166         else:
167             msg = "OK"
168             if res.skippedNum > 0:
169                 msg += " (%d skipped)" % res.skippedNum
170             print(msg)
171
172         return res
173
174 class TestResult:
175     def __init__(self):
176         self.errorsNum = 0
177         self.failuresNum = 0
178         self.skippedNum = 0
179         self.testsRun = 0
180
181     def wasSuccessful(self):
182         return self.errorsNum == 0 and self.failuresNum == 0
183
184 # TODO: Uncompliant
185 def run_class(c, test_result):
186     o = c()
187     set_up = getattr(o, "setUp", lambda: None)
188     tear_down = getattr(o, "tearDown", lambda: None)
189     for name in dir(o):
190         if name.startswith("test"):
191             print("%s (%s) ..." % (name, c.__qualname__), end="")
192             m = getattr(o, name)
193             set_up()
194             try:
195                 test_result.testsRun += 1
196                 m()
197                 print(" ok")
198             except SkipTest as e:
199                 print(" skipped:", e.args[0])
200                 test_result.skippedNum += 1
201             except Exception as e: # user exception
202                 print(" FAIL")
203                 if raiseException:
204                     raise
205                 else:
206                     print(e)
207                     test_result.failuresNum += 1
208                     continue
209             except BaseException as e: # system exception
210                 print(" FAIL")
211                 if raiseBaseException:
212                     raise
213                 else:
214                     print(e)
215                     test_result.failuresNum += 1
216                     continue
217             finally:
218                 tear_down()
219
220
221 def main(module="__main__"):
222     def test_cases(m):
223         for tn in dir(m):
224             c = getattr(m, tn)
225             if isinstance(c, object) and isinstance(c, type) and issubclass(c, TestCase):
226                 yield c
227
228     m = __import__(module) # changed to permit non-top-level testing modules
229     suite = TestSuite()
230     for c in test_cases(m):
231         suite.addTest(c)
232     runner = TestRunner()
233     result = runner.run(suite)