1import datetime
2import warnings
3import weakref
4import unittest
5from test.support import gc_collect
6from itertools import product
7
8
9class Test_Assertions(unittest.TestCase):
10    def test_AlmostEqual(self):
11        self.assertAlmostEqual(1.00000001, 1.0)
12        self.assertNotAlmostEqual(1.0000001, 1.0)
13        self.assertRaises(self.failureException,
14                          self.assertAlmostEqual, 1.0000001, 1.0)
15        self.assertRaises(self.failureException,
16                          self.assertNotAlmostEqual, 1.00000001, 1.0)
17
18        self.assertAlmostEqual(1.1, 1.0, places=0)
19        self.assertRaises(self.failureException,
20                          self.assertAlmostEqual, 1.1, 1.0, places=1)
21
22        self.assertAlmostEqual(0, .1+.1j, places=0)
23        self.assertNotAlmostEqual(0, .1+.1j, places=1)
24        self.assertRaises(self.failureException,
25                          self.assertAlmostEqual, 0, .1+.1j, places=1)
26        self.assertRaises(self.failureException,
27                          self.assertNotAlmostEqual, 0, .1+.1j, places=0)
28
29        self.assertAlmostEqual(float('inf'), float('inf'))
30        self.assertRaises(self.failureException, self.assertNotAlmostEqual,
31                          float('inf'), float('inf'))
32
33    def test_AmostEqualWithDelta(self):
34        self.assertAlmostEqual(1.1, 1.0, delta=0.5)
35        self.assertAlmostEqual(1.0, 1.1, delta=0.5)
36        self.assertNotAlmostEqual(1.1, 1.0, delta=0.05)
37        self.assertNotAlmostEqual(1.0, 1.1, delta=0.05)
38
39        self.assertAlmostEqual(1.0, 1.0, delta=0.5)
40        self.assertRaises(self.failureException, self.assertNotAlmostEqual,
41                          1.0, 1.0, delta=0.5)
42
43        self.assertRaises(self.failureException, self.assertAlmostEqual,
44                          1.1, 1.0, delta=0.05)
45        self.assertRaises(self.failureException, self.assertNotAlmostEqual,
46                          1.1, 1.0, delta=0.5)
47
48        self.assertRaises(TypeError, self.assertAlmostEqual,
49                          1.1, 1.0, places=2, delta=2)
50        self.assertRaises(TypeError, self.assertNotAlmostEqual,
51                          1.1, 1.0, places=2, delta=2)
52
53        first = datetime.datetime.now()
54        second = first + datetime.timedelta(seconds=10)
55        self.assertAlmostEqual(first, second,
56                               delta=datetime.timedelta(seconds=20))
57        self.assertNotAlmostEqual(first, second,
58                                  delta=datetime.timedelta(seconds=5))
59
60    def test_assertRaises(self):
61        def _raise(e):
62            raise e
63        self.assertRaises(KeyError, _raise, KeyError)
64        self.assertRaises(KeyError, _raise, KeyError("key"))
65        try:
66            self.assertRaises(KeyError, lambda: None)
67        except self.failureException as e:
68            self.assertIn("KeyError not raised", str(e))
69        else:
70            self.fail("assertRaises() didn't fail")
71        try:
72            self.assertRaises(KeyError, _raise, ValueError)
73        except ValueError:
74            pass
75        else:
76            self.fail("assertRaises() didn't let exception pass through")
77        with self.assertRaises(KeyError) as cm:
78            try:
79                raise KeyError
80            except Exception as e:
81                exc = e
82                raise
83        self.assertIs(cm.exception, exc)
84
85        with self.assertRaises(KeyError):
86            raise KeyError("key")
87        try:
88            with self.assertRaises(KeyError):
89                pass
90        except self.failureException as e:
91            self.assertIn("KeyError not raised", str(e))
92        else:
93            self.fail("assertRaises() didn't fail")
94        try:
95            with self.assertRaises(KeyError):
96                raise ValueError
97        except ValueError:
98            pass
99        else:
100            self.fail("assertRaises() didn't let exception pass through")
101
102    def test_assertRaises_frames_survival(self):
103        # Issue #9815: assertRaises should avoid keeping local variables
104        # in a traceback alive.
105        class A:
106            pass
107        wr = None
108
109        class Foo(unittest.TestCase):
110
111            def foo(self):
112                nonlocal wr
113                a = A()
114                wr = weakref.ref(a)
115                try:
116                    raise OSError
117                except OSError:
118                    raise ValueError
119
120            def test_functional(self):
121                self.assertRaises(ValueError, self.foo)
122
123            def test_with(self):
124                with self.assertRaises(ValueError):
125                    self.foo()
126
127        Foo("test_functional").run()
128        gc_collect()  # For PyPy or other GCs.
129        self.assertIsNone(wr())
130        Foo("test_with").run()
131        gc_collect()  # For PyPy or other GCs.
132        self.assertIsNone(wr())
133
134    def testAssertNotRegex(self):
135        self.assertNotRegex('Ala ma kota', r'r+')
136        try:
137            self.assertNotRegex('Ala ma kota', r'k.t', 'Message')
138        except self.failureException as e:
139            self.assertIn('Message', e.args[0])
140        else:
141            self.fail('assertNotRegex should have failed.')
142
143
144class TestLongMessage(unittest.TestCase):
145    """Test that the individual asserts honour longMessage.
146    This actually tests all the message behaviour for
147    asserts that use longMessage."""
148
149    def setUp(self):
150        class TestableTestFalse(unittest.TestCase):
151            longMessage = False
152            failureException = self.failureException
153
154            def testTest(self):
155                pass
156
157        class TestableTestTrue(unittest.TestCase):
158            longMessage = True
159            failureException = self.failureException
160
161            def testTest(self):
162                pass
163
164        self.testableTrue = TestableTestTrue('testTest')
165        self.testableFalse = TestableTestFalse('testTest')
166
167    def testDefault(self):
168        self.assertTrue(unittest.TestCase.longMessage)
169
170    def test_formatMsg(self):
171        self.assertEqual(self.testableFalse._formatMessage(None, "foo"), "foo")
172        self.assertEqual(self.testableFalse._formatMessage("foo", "bar"), "foo")
173
174        self.assertEqual(self.testableTrue._formatMessage(None, "foo"), "foo")
175        self.assertEqual(self.testableTrue._formatMessage("foo", "bar"), "bar : foo")
176
177        # This blows up if _formatMessage uses string concatenation
178        self.testableTrue._formatMessage(object(), 'foo')
179
180    def test_formatMessage_unicode_error(self):
181        one = ''.join(chr(i) for i in range(255))
182        # this used to cause a UnicodeDecodeError constructing msg
183        self.testableTrue._formatMessage(one, '\uFFFD')
184
185    def assertMessages(self, methodName, args, errors):
186        """
187        Check that methodName(*args) raises the correct error messages.
188        errors should be a list of 4 regex that match the error when:
189          1) longMessage = False and no msg passed;
190          2) longMessage = False and msg passed;
191          3) longMessage = True and no msg passed;
192          4) longMessage = True and msg passed;
193        """
194        def getMethod(i):
195            useTestableFalse  = i < 2
196            if useTestableFalse:
197                test = self.testableFalse
198            else:
199                test = self.testableTrue
200            return getattr(test, methodName)
201
202        for i, expected_regex in enumerate(errors):
203            testMethod = getMethod(i)
204            kwargs = {}
205            withMsg = i % 2
206            if withMsg:
207                kwargs = {"msg": "oops"}
208
209            with self.assertRaisesRegex(self.failureException,
210                                        expected_regex=expected_regex):
211                testMethod(*args, **kwargs)
212
213    def testAssertTrue(self):
214        self.assertMessages('assertTrue', (False,),
215                            ["^False is not true$", "^oops$", "^False is not true$",
216                             "^False is not true : oops$"])
217
218    def testAssertFalse(self):
219        self.assertMessages('assertFalse', (True,),
220                            ["^True is not false$", "^oops$", "^True is not false$",
221                             "^True is not false : oops$"])
222
223    def testNotEqual(self):
224        self.assertMessages('assertNotEqual', (1, 1),
225                            ["^1 == 1$", "^oops$", "^1 == 1$",
226                             "^1 == 1 : oops$"])
227
228    def testAlmostEqual(self):
229        self.assertMessages(
230            'assertAlmostEqual', (1, 2),
231            [r"^1 != 2 within 7 places \(1 difference\)$", "^oops$",
232             r"^1 != 2 within 7 places \(1 difference\)$",
233             r"^1 != 2 within 7 places \(1 difference\) : oops$"])
234
235    def testNotAlmostEqual(self):
236        self.assertMessages('assertNotAlmostEqual', (1, 1),
237                            ["^1 == 1 within 7 places$", "^oops$",
238                             "^1 == 1 within 7 places$", "^1 == 1 within 7 places : oops$"])
239
240    def test_baseAssertEqual(self):
241        self.assertMessages('_baseAssertEqual', (1, 2),
242                            ["^1 != 2$", "^oops$", "^1 != 2$", "^1 != 2 : oops$"])
243
244    def testAssertSequenceEqual(self):
245        # Error messages are multiline so not testing on full message
246        # assertTupleEqual and assertListEqual delegate to this method
247        self.assertMessages('assertSequenceEqual', ([], [None]),
248                            [r"\+ \[None\]$", "^oops$", r"\+ \[None\]$",
249                             r"\+ \[None\] : oops$"])
250
251    def testAssertSetEqual(self):
252        self.assertMessages('assertSetEqual', (set(), set([None])),
253                            ["None$", "^oops$", "None$",
254                             "None : oops$"])
255
256    def testAssertIn(self):
257        self.assertMessages('assertIn', (None, []),
258                            [r'^None not found in \[\]$', "^oops$",
259                             r'^None not found in \[\]$',
260                             r'^None not found in \[\] : oops$'])
261
262    def testAssertNotIn(self):
263        self.assertMessages('assertNotIn', (None, [None]),
264                            [r'^None unexpectedly found in \[None\]$', "^oops$",
265                             r'^None unexpectedly found in \[None\]$',
266                             r'^None unexpectedly found in \[None\] : oops$'])
267
268    def testAssertDictEqual(self):
269        self.assertMessages('assertDictEqual', ({}, {'key': 'value'}),
270                            [r"\+ \{'key': 'value'\}$", "^oops$",
271                             r"\+ \{'key': 'value'\}$",
272                             r"\+ \{'key': 'value'\} : oops$"])
273
274    def testAssertMultiLineEqual(self):
275        self.assertMessages('assertMultiLineEqual', ("", "foo"),
276                            [r"\+ foo$", "^oops$",
277                             r"\+ foo$",
278                             r"\+ foo : oops$"])
279
280    def testAssertLess(self):
281        self.assertMessages('assertLess', (2, 1),
282                            ["^2 not less than 1$", "^oops$",
283                             "^2 not less than 1$", "^2 not less than 1 : oops$"])
284
285    def testAssertLessEqual(self):
286        self.assertMessages('assertLessEqual', (2, 1),
287                            ["^2 not less than or equal to 1$", "^oops$",
288                             "^2 not less than or equal to 1$",
289                             "^2 not less than or equal to 1 : oops$"])
290
291    def testAssertGreater(self):
292        self.assertMessages('assertGreater', (1, 2),
293                            ["^1 not greater than 2$", "^oops$",
294                             "^1 not greater than 2$",
295                             "^1 not greater than 2 : oops$"])
296
297    def testAssertGreaterEqual(self):
298        self.assertMessages('assertGreaterEqual', (1, 2),
299                            ["^1 not greater than or equal to 2$", "^oops$",
300                             "^1 not greater than or equal to 2$",
301                             "^1 not greater than or equal to 2 : oops$"])
302
303    def testAssertIsNone(self):
304        self.assertMessages('assertIsNone', ('not None',),
305                            ["^'not None' is not None$", "^oops$",
306                             "^'not None' is not None$",
307                             "^'not None' is not None : oops$"])
308
309    def testAssertIsNotNone(self):
310        self.assertMessages('assertIsNotNone', (None,),
311                            ["^unexpectedly None$", "^oops$",
312                             "^unexpectedly None$",
313                             "^unexpectedly None : oops$"])
314
315    def testAssertIs(self):
316        self.assertMessages('assertIs', (None, 'foo'),
317                            ["^None is not 'foo'$", "^oops$",
318                             "^None is not 'foo'$",
319                             "^None is not 'foo' : oops$"])
320
321    def testAssertIsNot(self):
322        self.assertMessages('assertIsNot', (None, None),
323                            ["^unexpectedly identical: None$", "^oops$",
324                             "^unexpectedly identical: None$",
325                             "^unexpectedly identical: None : oops$"])
326
327    def testAssertRegex(self):
328        self.assertMessages('assertRegex', ('foo', 'bar'),
329                            ["^Regex didn't match:",
330                             "^oops$",
331                             "^Regex didn't match:",
332                             "^Regex didn't match: (.*) : oops$"])
333
334    def testAssertNotRegex(self):
335        self.assertMessages('assertNotRegex', ('foo', 'foo'),
336                            ["^Regex matched:",
337                             "^oops$",
338                             "^Regex matched:",
339                             "^Regex matched: (.*) : oops$"])
340
341
342    def assertMessagesCM(self, methodName, args, func, errors):
343        """
344        Check that the correct error messages are raised while executing:
345          with method(*args):
346              func()
347        *errors* should be a list of 4 regex that match the error when:
348          1) longMessage = False and no msg passed;
349          2) longMessage = False and msg passed;
350          3) longMessage = True and no msg passed;
351          4) longMessage = True and msg passed;
352        """
353        p = product((self.testableFalse, self.testableTrue),
354                    ({}, {"msg": "oops"}))
355        for (cls, kwargs), err in zip(p, errors):
356            method = getattr(cls, methodName)
357            with self.assertRaisesRegex(cls.failureException, err):
358                with method(*args, **kwargs) as cm:
359                    func()
360
361    def testAssertRaises(self):
362        self.assertMessagesCM('assertRaises', (TypeError,), lambda: None,
363                              ['^TypeError not raised$', '^oops$',
364                               '^TypeError not raised$',
365                               '^TypeError not raised : oops$'])
366
367    def testAssertRaisesRegex(self):
368        # test error not raised
369        self.assertMessagesCM('assertRaisesRegex', (TypeError, 'unused regex'),
370                              lambda: None,
371                              ['^TypeError not raised$', '^oops$',
372                               '^TypeError not raised$',
373                               '^TypeError not raised : oops$'])
374        # test error raised but with wrong message
375        def raise_wrong_message():
376            raise TypeError('foo')
377        self.assertMessagesCM('assertRaisesRegex', (TypeError, 'regex'),
378                              raise_wrong_message,
379                              ['^"regex" does not match "foo"$', '^oops$',
380                               '^"regex" does not match "foo"$',
381                               '^"regex" does not match "foo" : oops$'])
382
383    def testAssertWarns(self):
384        self.assertMessagesCM('assertWarns', (UserWarning,), lambda: None,
385                              ['^UserWarning not triggered$', '^oops$',
386                               '^UserWarning not triggered$',
387                               '^UserWarning not triggered : oops$'])
388
389    def testAssertWarnsRegex(self):
390        # test error not raised
391        self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'unused regex'),
392                              lambda: None,
393                              ['^UserWarning not triggered$', '^oops$',
394                               '^UserWarning not triggered$',
395                               '^UserWarning not triggered : oops$'])
396        # test warning raised but with wrong message
397        def raise_wrong_message():
398            warnings.warn('foo')
399        self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'regex'),
400                              raise_wrong_message,
401                              ['^"regex" does not match "foo"$', '^oops$',
402                               '^"regex" does not match "foo"$',
403                               '^"regex" does not match "foo" : oops$'])
404
405
406if __name__ == "__main__":
407    unittest.main()
408