Merge lp:~jml/testtools/basic-mismatch into lp:~testtools-committers/testtools/trunk

Proposed by Jonathan Lange
Status: Merged
Merged at revision: 94
Proposed branch: lp:~jml/testtools/basic-mismatch
Merge into: lp:~testtools-committers/testtools/trunk
Diff against target: 98 lines (+37/-3)
3 files modified
NEWS (+4/-1)
testtools/matchers.py (+19/-2)
testtools/tests/test_matchers.py (+14/-0)
To merge this branch: bzr merge lp:~jml/testtools/basic-mismatch
Reviewer Review Type Date Requested Status
Māris Fogels (community) Approve
testtools developers Pending
Review via email: mp+32872@code.launchpad.net

Description of the change

This branch changes the base "Mismatch" so that it takes optional description and details parameters.

I wanted to do this because for a lot of Matchers I don't really want to make my own Mismatch subclass and I shouldn't need to.

As for implementation, I've preserved the old API, but am not particularly happy with the gymnastics required to do so. I could have my arm twisted to move the changes out of the base class and into a new class like SimpleMismatch. The reason I didn't is that I think Mismatch("description") is a less surprising API for users than a second class.

Māris points out that with this change, many of the Mismatch classes in testtools.matchers could disappear, along with their nice names.

To post a comment you must log in.
Revision history for this message
Māris Fogels (mars) wrote :

Not a developer, but why did you use getatter() in Mismatch.get_details()? It looks like the constructor guarantees that the object always has a valid ._details attribute.

I think the changes look good.

Maris

review: Approve
Revision history for this message
Jonathan Lange (jml) wrote :

On Tue, Aug 17, 2010 at 3:41 PM, Māris Fogels <email address hidden> wrote:
> Review: Approve
> Not a developer, but why did you use getatter() in Mismatch.get_details()?  It looks like the constructor guarantees that the object always has a valid ._details attribute.

Not all subclasses upcall. I could change the subclasses in
testtools.matchers, but I can't change the subclasses that other
people have made elsewhere.

Revision history for this message
Robert Collins (lifeless) wrote :

So the whole point of mismatch is to be lazy, to allow calculating the
difference once and showing it later; i agree that much of the time
this is simple and won't be deferred; keeping the ability to do so is
extremely important, and we shouldn't make it hard for folk that do
need custom mismatch classes.

That said, sure, I've no problem with the base class being more helpful.

Deleting stuff will be tricky, we've some users that have used some of
our mismatchers directly.

-Rob

Revision history for this message
Jonathan Lange (jml) wrote :

The base patch keeps the ability to defer, which I agree is important, and pretty much guaranteed by the interface.

Not planning on deleting mismatches that we have.

You OK for me to merge this?

Revision history for this message
Robert Collins (lifeless) wrote :

sure, you have a +1 from maris ;)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'NEWS'
--- NEWS 2010-08-05 10:19:28 +0000
+++ NEWS 2010-08-17 13:15:56 +0000
@@ -7,6 +7,9 @@
7Improvements7Improvements
8------------8------------
99
10 * 'Mismatch' now takes optional description and details parameters, so
11 custom Matchers aren't compelled to make their own subclass.
12
10 * jml added a built-in UTF8_TEXT ContentType to make it slightly easier to13 * jml added a built-in UTF8_TEXT ContentType to make it slightly easier to
11 add details to test results.14 add details to test results.
1215
@@ -16,7 +19,7 @@
16 * New 'Is' matcher, which lets you assert that a thing is identical to19 * New 'Is' matcher, which lets you assert that a thing is identical to
17 another thing.20 another thing.
1821
19 * New 'LessThan' matcher which lets you assert that a thing is less than 22 * New 'LessThan' matcher which lets you assert that a thing is less than
20 another thing.23 another thing.
2124
22 * TestCase now has a 'patch()' method to make it easier to monkey-patching25 * TestCase now has a 'patch()' method to make it easier to monkey-patching
2326
=== modified file 'testtools/matchers.py'
--- testtools/matchers.py 2010-08-05 06:20:48 +0000
+++ testtools/matchers.py 2010-08-17 13:15:56 +0000
@@ -58,12 +58,29 @@
58class Mismatch(object):58class Mismatch(object):
59 """An object describing a mismatch detected by a Matcher."""59 """An object describing a mismatch detected by a Matcher."""
6060
61 def __init__(self, description=None, details=None):
62 """Construct a `Mismatch`.
63
64 :param description: A description to use. If not provided,
65 `Mismatch.describe` must be implemented.
66 :param details: Extra details about the mismatch. Defaults
67 to the empty dict.
68 """
69 if description:
70 self._description = description
71 if details is None:
72 details = {}
73 self._details = details
74
61 def describe(self):75 def describe(self):
62 """Describe the mismatch.76 """Describe the mismatch.
6377
64 This should be either a human-readable string or castable to a string.78 This should be either a human-readable string or castable to a string.
65 """79 """
66 raise NotImplementedError(self.describe_difference)80 try:
81 return self._description
82 except AttributeError:
83 raise NotImplementedError(self.describe)
6784
68 def get_details(self):85 def get_details(self):
69 """Get extra details about the mismatch.86 """Get extra details about the mismatch.
@@ -81,7 +98,7 @@
81 to the result. For more information see the API to which items from98 to the result. For more information see the API to which items from
82 this dict are passed testtools.TestCase.addDetail.99 this dict are passed testtools.TestCase.addDetail.
83 """100 """
84 return {}101 return getattr(self, '_details', {})
85102
86103
87class DocTestMatches(object):104class DocTestMatches(object):
88105
=== modified file 'testtools/tests/test_matchers.py'
--- testtools/tests/test_matchers.py 2010-08-05 06:20:48 +0000
+++ testtools/tests/test_matchers.py 2010-08-17 13:15:56 +0000
@@ -16,6 +16,7 @@
16 LessThan,16 LessThan,
17 MatchesAny,17 MatchesAny,
18 MatchesAll,18 MatchesAll,
19 Mismatch,
19 Not,20 Not,
20 NotEquals,21 NotEquals,
21 )22 )
@@ -24,6 +25,19 @@
24Matcher25Matcher
2526
2627
28class TestMismatch(TestCase):
29
30 def test_constructor_arguments(self):
31 mismatch = Mismatch("some description", {'detail': "things"})
32 self.assertEqual("some description", mismatch.describe())
33 self.assertEqual({'detail': "things"}, mismatch.get_details())
34
35 def test_constructor_no_arguments(self):
36 mismatch = Mismatch()
37 self.assertRaises(NotImplementedError, mismatch.describe)
38 self.assertEqual({}, mismatch.get_details())
39
40
27class TestMatchersInterface(object):41class TestMatchersInterface(object):
2842
29 def test_matches_match(self):43 def test_matches_match(self):

Subscribers

People subscribed via source and target branches