[Python-checkins] cpython: #11282: add back the fail* methods and assertDictContainsSubset.

ezio.melotti python-checkins at python.org
Sun Apr 3 17:03:36 CEST 2011


http://hg.python.org/cpython/rev/aa658836e090
changeset:   69111:aa658836e090
user:        Ezio Melotti
date:        Sun Apr 03 18:02:13 2011 +0300
summary:
  #11282: add back the fail* methods and assertDictContainsSubset.

files:
  Lib/unittest/case.py                 |  41 ++++++++++-
  Lib/unittest/test/_test_warnings.py  |   7 +-
  Lib/unittest/test/test_assertions.py |   9 ++
  Lib/unittest/test/test_case.py       |  53 ++++++++++++++++
  Lib/unittest/test/test_runner.py     |  10 ++-
  Misc/NEWS                            |   2 +
  6 files changed, 113 insertions(+), 9 deletions(-)


diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py
--- a/Lib/unittest/case.py
+++ b/Lib/unittest/case.py
@@ -938,6 +938,35 @@
             standardMsg = self._truncateMessage(standardMsg, diff)
             self.fail(self._formatMessage(msg, standardMsg))
 
+    def assertDictContainsSubset(self, subset, dictionary, msg=None):
+        """Checks whether dictionary is a superset of subset."""
+        warnings.warn('assertDictContainsSubset is deprecated',
+                      DeprecationWarning)
+        missing = []
+        mismatched = []
+        for key, value in subset.items():
+            if key not in dictionary:
+                missing.append(key)
+            elif value != dictionary[key]:
+                mismatched.append('%s, expected: %s, actual: %s' %
+                                  (safe_repr(key), safe_repr(value),
+                                   safe_repr(dictionary[key])))
+
+        if not (missing or mismatched):
+            return
+
+        standardMsg = ''
+        if missing:
+            standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
+                                                    missing)
+        if mismatched:
+            if standardMsg:
+                standardMsg += '; '
+            standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
+
+        self.fail(self._formatMessage(msg, standardMsg))
+
+
     def assertCountEqual(self, first, second, msg=None):
         """An unordered sequence comparison asserting that the same elements,
         regardless of order.  If the same element occurs more than once,
@@ -1111,11 +1140,13 @@
         return deprecated_func
 
     # see #9424
-    assertEquals = _deprecate(assertEqual)
-    assertNotEquals = _deprecate(assertNotEqual)
-    assertAlmostEquals = _deprecate(assertAlmostEqual)
-    assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
-    assert_ = _deprecate(assertTrue)
+    failUnlessEqual = assertEquals = _deprecate(assertEqual)
+    failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
+    failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
+    failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
+    failUnless = assert_ = _deprecate(assertTrue)
+    failUnlessRaises = _deprecate(assertRaises)
+    failIf = _deprecate(assertFalse)
     assertRaisesRegexp = _deprecate(assertRaisesRegex)
     assertRegexpMatches = _deprecate(assertRegex)
 
diff --git a/Lib/unittest/test/_test_warnings.py b/Lib/unittest/test/_test_warnings.py
--- a/Lib/unittest/test/_test_warnings.py
+++ b/Lib/unittest/test/_test_warnings.py
@@ -19,12 +19,17 @@
     warnings.warn('rw', RuntimeWarning)
 
 class TestWarnings(unittest.TestCase):
-    # unittest warnings will be printed at most once per type
+    # unittest warnings will be printed at most once per type (max one message
+    # for the fail* methods, and one for the assert* methods)
     def test_assert(self):
         self.assertEquals(2+2, 4)
         self.assertEquals(2*2, 4)
         self.assertEquals(2**2, 4)
 
+    def test_fail(self):
+        self.failUnless(1)
+        self.failUnless(True)
+
     def test_other_unittest(self):
         self.assertAlmostEqual(2+2, 4)
         self.assertNotAlmostEqual(4+4, 2)
diff --git a/Lib/unittest/test/test_assertions.py b/Lib/unittest/test/test_assertions.py
--- a/Lib/unittest/test/test_assertions.py
+++ b/Lib/unittest/test/test_assertions.py
@@ -223,6 +223,15 @@
                              "\+ \{'key': 'value'\}$",
                              "\+ \{'key': 'value'\} : oops$"])
 
+    def testAssertDictContainsSubset(self):
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore", DeprecationWarning)
+
+            self.assertMessages('assertDictContainsSubset', ({'key': 'value'}, {}),
+                                ["^Missing: 'key'$", "^oops$",
+                                 "^Missing: 'key'$",
+                                 "^Missing: 'key' : oops$"])
+
     def testAssertMultiLineEqual(self):
         self.assertMessages('assertMultiLineEqual', ("", "foo"),
                             [r"\+ foo$", "^oops$",
diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py
--- a/Lib/unittest/test/test_case.py
+++ b/Lib/unittest/test/test_case.py
@@ -523,6 +523,36 @@
         self.assertRaises(self.failureException, self.assertNotIn, 'cow',
                           animals)
 
+    def testAssertDictContainsSubset(self):
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore", DeprecationWarning)
+
+            self.assertDictContainsSubset({}, {})
+            self.assertDictContainsSubset({}, {'a': 1})
+            self.assertDictContainsSubset({'a': 1}, {'a': 1})
+            self.assertDictContainsSubset({'a': 1}, {'a': 1, 'b': 2})
+            self.assertDictContainsSubset({'a': 1, 'b': 2}, {'a': 1, 'b': 2})
+
+            with self.assertRaises(self.failureException):
+                self.assertDictContainsSubset({1: "one"}, {})
+
+            with self.assertRaises(self.failureException):
+                self.assertDictContainsSubset({'a': 2}, {'a': 1})
+
+            with self.assertRaises(self.failureException):
+                self.assertDictContainsSubset({'c': 1}, {'a': 1})
+
+            with self.assertRaises(self.failureException):
+                self.assertDictContainsSubset({'a': 1, 'c': 1}, {'a': 1})
+
+            with self.assertRaises(self.failureException):
+                self.assertDictContainsSubset({'a': 1, 'c': 1}, {'a': 1})
+
+            one = ''.join(chr(i) for i in range(255))
+            # this used to cause a UnicodeDecodeError constructing the failure msg
+            with self.assertRaises(self.failureException):
+                self.assertDictContainsSubset({'foo': one}, {'foo': '\uFFFD'})
+
     def testAssertEqual(self):
         equal_pairs = [
                 ((), ()),
@@ -1097,11 +1127,19 @@
         Test that the deprecated methods raise a DeprecationWarning. See #9424.
         """
         old = (
+            (self.failIfEqual, (3, 5)),
             (self.assertNotEquals, (3, 5)),
+            (self.failUnlessEqual, (3, 3)),
             (self.assertEquals, (3, 3)),
+            (self.failUnlessAlmostEqual, (2.0, 2.0)),
             (self.assertAlmostEquals, (2.0, 2.0)),
+            (self.failIfAlmostEqual, (3.0, 5.0)),
             (self.assertNotAlmostEquals, (3.0, 5.0)),
+            (self.failUnless, (True,)),
             (self.assert_, (True,)),
+            (self.failUnlessRaises, (TypeError, lambda _: 3.14 + 'spam')),
+            (self.failIf, (False,)),
+            (self.assertDictContainsSubset, (dict(a=1, b=2), dict(a=1, b=2, c=3))),
             (self.assertRaisesRegexp, (KeyError, 'foo', lambda: {}['foo'])),
             (self.assertRegexpMatches, ('bar', 'bar')),
         )
@@ -1109,6 +1147,21 @@
             with self.assertWarns(DeprecationWarning):
                 meth(*args)
 
+    # disable this test for now. When the version where the fail* methods will
+    # be removed is decided, re-enable it and update the version
+    def _testDeprecatedFailMethods(self):
+        """Test that the deprecated fail* methods get removed in 3.x"""
+        if sys.version_info[:2] < (3, 3):
+            return
+        deprecated_names = [
+            'failIfEqual', 'failUnlessEqual', 'failUnlessAlmostEqual',
+            'failIfAlmostEqual', 'failUnless', 'failUnlessRaises', 'failIf',
+            'assertDictContainsSubset',
+        ]
+        for deprecated_name in deprecated_names:
+            with self.assertRaises(AttributeError):
+                getattr(self, deprecated_name)  # remove these in 3.x
+
     def testDeepcopy(self):
         # Issue: 5660
         class TestableTest(unittest.TestCase):
diff --git a/Lib/unittest/test/test_runner.py b/Lib/unittest/test/test_runner.py
--- a/Lib/unittest/test/test_runner.py
+++ b/Lib/unittest/test/test_runner.py
@@ -257,17 +257,19 @@
             return [b.splitlines() for b in p.communicate()]
         opts = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                     cwd=os.path.dirname(__file__))
+        ae_msg = b'Please use assertEqual instead.'
+        at_msg = b'Please use assertTrue instead.'
 
         # no args -> all the warnings are printed, unittest warnings only once
         p = subprocess.Popen([sys.executable, '_test_warnings.py'], **opts)
         out, err = get_parse_out_err(p)
         self.assertIn(b'OK', err)
         # check that the total number of warnings in the output is correct
-        self.assertEqual(len(out), 11)
+        self.assertEqual(len(out), 12)
         # check that the numbers of the different kind of warnings is correct
         for msg in [b'dw', b'iw', b'uw']:
             self.assertEqual(out.count(msg), 3)
-        for msg in [b'rw']:
+        for msg in [ae_msg, at_msg, b'rw']:
             self.assertEqual(out.count(msg), 1)
 
         args_list = (
@@ -292,9 +294,11 @@
                              **opts)
         out, err = get_parse_out_err(p)
         self.assertIn(b'OK', err)
-        self.assertEqual(len(out), 13)
+        self.assertEqual(len(out), 14)
         for msg in [b'dw', b'iw', b'uw', b'rw']:
             self.assertEqual(out.count(msg), 3)
+        for msg in [ae_msg, at_msg]:
+            self.assertEqual(out.count(msg), 1)
 
     def testStdErrLookedUpAtInstantiationTime(self):
         # see issue 10786
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -87,6 +87,8 @@
 Library
 -------
 
+- unittest.TestCase.assertSameElements has been removed.
+
 - sys.getfilesystemencoding() raises a RuntimeError if initfsencoding() was not
   called yet: detect bootstrap (startup) issues earlier.
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list