Merge lp:~gz/testtools/fix_json_py3k_tests into lp:~testtools-committers/testtools/trunk

Proposed by Martin Packman
Status: Merged
Approved by: Jonathan Lange
Approved revision: 269
Merged at revision: 278
Proposed branch: lp:~gz/testtools/fix_json_py3k_tests
Merge into: lp:~testtools-committers/testtools/trunk
Diff against target: 87 lines (+15/-8)
5 files modified
testtools/content.py (+6/-2)
testtools/tests/test_content.py (+1/-1)
testtools/tests/test_content_type.py (+2/-2)
testtools/tests/test_testcase.py (+3/-2)
testtools/tests/test_testresult.py (+3/-1)
To merge this branch: bzr merge lp:~gz/testtools/fix_json_py3k_tests
Reviewer Review Type Date Requested Status
Jonathan Lange Approve
Review via email: mp+117117@code.launchpad.net

Commit message

Testing. Please ignore.

Description of the change

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.

To post a comment you must log in.
Revision history for this message
Jonathan Lange (jml) wrote :

LGTM. I'll file a bug for SameMembers and hopefully fix. Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'testtools/content.py'
2--- testtools/content.py 2012-07-13 16:21:45 +0000
3+++ testtools/content.py 2012-07-27 19:03:19 +0000
4@@ -190,9 +190,13 @@
5 return length
6
7
8-def json_content(data):
9+def json_content(json_data):
10 """Create a JSON `Content` object from JSON-encodeable data."""
11- return Content(JSON, lambda: [json.dumps(data)])
12+ data = json.dumps(json_data)
13+ if str_is_unicode:
14+ # The json module perversely returns native str not bytes
15+ data = data.encode('utf8')
16+ return Content(JSON, lambda: [data])
17
18
19 def text_content(text):
20
21=== modified file 'testtools/tests/test_content.py'
22--- testtools/tests/test_content.py 2012-07-13 16:21:45 +0000
23+++ testtools/tests/test_content.py 2012-07-27 19:03:19 +0000
24@@ -155,7 +155,7 @@
25
26 def test_json_content(self):
27 data = {'foo': 'bar'}
28- expected = Content(JSON, lambda: [json.dumps(data)])
29+ expected = Content(JSON, lambda: [_b('{"foo": "bar"}')])
30 self.assertEqual(expected, json_content(data))
31
32
33
34=== modified file 'testtools/tests/test_content_type.py'
35--- testtools/tests/test_content_type.py 2012-07-13 16:21:45 +0000
36+++ testtools/tests/test_content_type.py 2012-07-27 19:03:19 +0000
37@@ -55,10 +55,10 @@
38 self.assertThat(UTF8_TEXT.parameters, Equals({'charset': 'utf8'}))
39
40 def test_json_content(self):
41- # The JSON content type represents UTF-8 encoded application/json.
42+ # The JSON content type represents implictly UTF-8 application/json.
43 self.assertThat(JSON.type, Equals('application'))
44 self.assertThat(JSON.subtype, Equals('json'))
45- self.assertThat(JSON.parameters, Equals({'charset': 'utf8'}))
46+ self.assertThat(JSON.parameters, Equals({}))
47
48
49 def test_suite():
50
51=== modified file 'testtools/tests/test_testcase.py'
52--- testtools/tests/test_testcase.py 2012-04-03 07:47:54 +0000
53+++ testtools/tests/test_testcase.py 2012-07-27 19:03:19 +0000
54@@ -263,7 +263,8 @@
55 # assertRaises raises self.failureException when it's passed a
56 # callable that raises no error.
57 ret = ('orange', 42)
58- self.assertFails("<function <lambda> at ...> returned ('orange', 42)",
59+ self.assertFails(
60+ "<function ...<lambda> at ...> returned ('orange', 42)",
61 self.assertRaises, RuntimeError, lambda: ret)
62
63 def test_assertRaises_fails_when_different_error_raised(self):
64@@ -309,7 +310,7 @@
65 self.assertRaises(
66 self.failureException,
67 self.assertRaises, expectedExceptions, lambda: None)
68- self.assertFails('<function <lambda> at ...> returned None',
69+ self.assertFails('<function ...<lambda> at ...> returned None',
70 self.assertRaises, expectedExceptions, lambda: None)
71
72 def test_assertRaises_function_repr_in_exception(self):
73
74=== modified file 'testtools/tests/test_testresult.py'
75--- testtools/tests/test_testresult.py 2012-05-07 02:51:19 +0000
76+++ testtools/tests/test_testresult.py 2012-07-27 19:03:19 +0000
77@@ -1579,7 +1579,9 @@
78 textoutput = self._test_external_case(
79 modulelevel="import os",
80 testline="os.mkdir('/')")
81- if os.name != "nt" or sys.version_info < (2, 5):
82+ if sys.version_info > (3, 3):
83+ self.assertIn(self._as_output("PermissionError: "), textoutput)
84+ elif os.name != "nt" or sys.version_info < (2, 5):
85 self.assertIn(self._as_output("OSError: "), textoutput)
86 else:
87 self.assertIn(self._as_output("WindowsError: "), textoutput)

Subscribers

People subscribed via source and target branches