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