← Back to team overview

testtools-dev team mailing list archive

[Merge] lp:~gz/testtools/fix_json_py3k_tests into lp:testtools

 

Martin Packman has proposed merging lp:~gz/testtools/fix_json_py3k_tests into lp:testtools.

Requested reviews:
  testtools committers (testtools-committers)

For more details, see:
https://code.launchpad.net/~gz/testtools/fix_json_py3k_tests/+merge/117117

Makes the current status of testtools a little greener.

There was a small amount of fallout from the json content type branch, most notably the helper does the wrong thing on Python 3 as json.dumps returns str, not bytes.

Also some other trivial fixes for tests on Python 3, but there's one failure I've not resolved:

======================================================================
ERROR: testtools.tests.test_matchers.TestSameMembers.test_matches_match
----------------------------------------------------------------------
Traceback (most recent call last):
  File "testtools\tests\test_matchers.py", line 218, in test_matches_match
    self.assertEqual(None, matcher.match(candidate))
  File "testtools\matchers.py", line 1295, in match
    expected = sorted(self.expected)
TypeError: unorderable types: dict() < int()

The SameMembers implementation just doesn't make sense given that Python 3 refuses to assign order to unrelated types.

Something dumb like this makes the tests pass, but only because they're not very comprehensive:

=== modified file 'testtools/matchers.py'
--- testtools/matchers.py       2012-06-07 18:17:07 +0000
+++ testtools/matchers.py       2012-07-27 18:58:38 +0000
@@ -1291,9 +1294,13 @@
     def __str__(self):
         return '%s(%r)' % (self.__class__.__name__, self.expected)

+    @staticmethod
+    def _by_type_and_obj(obj):
+        return type(obj).__name__, obj
+
     def match(self, observed):
-        expected = sorted(self.expected)
-        observed = sorted(observed)
+        expected = sorted(self.expected, key=self._by_type_and_obj)
+        observed = sorted(observed, key=self._by_type_and_obj)
         if expected == observed:
             return
         return _BinaryMismatch(expected, "elements differ", observed)

That falls down if, for instance, you're expecting [1] and [1.0] to compare equal. Either there's a better way, or this matcher is just a bad idea.
-- 
https://code.launchpad.net/~gz/testtools/fix_json_py3k_tests/+merge/117117
Your team testtools developers is subscribed to branch lp:testtools.
=== modified file 'testtools/content.py'
--- testtools/content.py	2012-07-13 16:21:45 +0000
+++ testtools/content.py	2012-07-27 19:03:19 +0000
@@ -190,9 +190,13 @@
         return length
 
 
-def json_content(data):
+def json_content(json_data):
     """Create a JSON `Content` object from JSON-encodeable data."""
-    return Content(JSON, lambda: [json.dumps(data)])
+    data = json.dumps(json_data)
+    if str_is_unicode:
+        # The json module perversely returns native str not bytes
+        data = data.encode('utf8')
+    return Content(JSON, lambda: [data])
 
 
 def text_content(text):

=== modified file 'testtools/tests/test_content.py'
--- testtools/tests/test_content.py	2012-07-13 16:21:45 +0000
+++ testtools/tests/test_content.py	2012-07-27 19:03:19 +0000
@@ -155,7 +155,7 @@
 
     def test_json_content(self):
         data = {'foo': 'bar'}
-        expected = Content(JSON, lambda: [json.dumps(data)])
+        expected = Content(JSON, lambda: [_b('{"foo": "bar"}')])
         self.assertEqual(expected, json_content(data))
 
 

=== modified file 'testtools/tests/test_content_type.py'
--- testtools/tests/test_content_type.py	2012-07-13 16:21:45 +0000
+++ testtools/tests/test_content_type.py	2012-07-27 19:03:19 +0000
@@ -55,10 +55,10 @@
         self.assertThat(UTF8_TEXT.parameters, Equals({'charset': 'utf8'}))
 
     def test_json_content(self):
-        # The JSON content type represents UTF-8 encoded application/json.
+        # The JSON content type represents implictly UTF-8 application/json.
         self.assertThat(JSON.type, Equals('application'))
         self.assertThat(JSON.subtype, Equals('json'))
-        self.assertThat(JSON.parameters, Equals({'charset': 'utf8'}))
+        self.assertThat(JSON.parameters, Equals({}))
 
 
 def test_suite():

=== modified file 'testtools/tests/test_testcase.py'
--- testtools/tests/test_testcase.py	2012-04-03 07:47:54 +0000
+++ testtools/tests/test_testcase.py	2012-07-27 19:03:19 +0000
@@ -263,7 +263,8 @@
         # assertRaises raises self.failureException when it's passed a
         # callable that raises no error.
         ret = ('orange', 42)
-        self.assertFails("<function <lambda> at ...> returned ('orange', 42)",
+        self.assertFails(
+            "<function ...<lambda> at ...> returned ('orange', 42)",
             self.assertRaises, RuntimeError, lambda: ret)
 
     def test_assertRaises_fails_when_different_error_raised(self):
@@ -309,7 +310,7 @@
         self.assertRaises(
             self.failureException,
             self.assertRaises, expectedExceptions, lambda: None)
-        self.assertFails('<function <lambda> at ...> returned None',
+        self.assertFails('<function ...<lambda> at ...> returned None',
             self.assertRaises, expectedExceptions, lambda: None)
 
     def test_assertRaises_function_repr_in_exception(self):

=== modified file 'testtools/tests/test_testresult.py'
--- testtools/tests/test_testresult.py	2012-05-07 02:51:19 +0000
+++ testtools/tests/test_testresult.py	2012-07-27 19:03:19 +0000
@@ -1579,7 +1579,9 @@
         textoutput = self._test_external_case(
             modulelevel="import os",
             testline="os.mkdir('/')")
-        if os.name != "nt" or sys.version_info < (2, 5):
+        if sys.version_info > (3, 3):
+            self.assertIn(self._as_output("PermissionError: "), textoutput)
+        elif os.name != "nt" or sys.version_info < (2, 5):
             self.assertIn(self._as_output("OSError: "), textoutput)
         else:
             self.assertIn(self._as_output("WindowsError: "), textoutput)


Follow ups