← Back to team overview

testtools-dev team mailing list archive

[Merge] lp:~jml/testtools/mismatch-724691 into lp:testtools

 

Jonathan Lange has proposed merging lp:~jml/testtools/mismatch-724691 into lp:testtools.

Requested reviews:
  testtools developers (testtools-dev)
Related bugs:
  Bug #724691 in testtools: "AnnotatedMismatch hides get_details"
  https://bugs.launchpad.net/testtools/+bug/724691

For more details, see:
https://code.launchpad.net/~jml/testtools/mismatch-724691/+merge/55938

This branch fixes bug 724691 in the manner described on the bug.
-- 
https://code.launchpad.net/~jml/testtools/mismatch-724691/+merge/55938
Your team testtools developers is requested to review the proposed merge of lp:~jml/testtools/mismatch-724691 into lp:testtools.
=== modified file 'testtools/matchers.py'
--- testtools/matchers.py	2011-03-22 13:55:39 +0000
+++ testtools/matchers.py	2011-04-01 14:11:40 +0000
@@ -117,6 +117,31 @@
             id(self), self.__dict__)
 
 
+class MismatchDecorator(object):
+    """Decorate a ``Mismatch``.
+
+    Forwards all messages to the original mismatch object.  Probably the best
+    way to use this is inherit from this class and then provide your own
+    custom decoration logic.
+    """
+
+    def __init__(self, original):
+        """Construct a `MismatchDecorator`.
+
+        :param original: A `Mismatch` object to decorate.
+        """
+        self.original = original
+
+    def __repr__(self):
+        return '<testtools.matchers.MismatchDecorator(%r)>' % (self.original,)
+
+    def describe(self):
+        return self.original.describe()
+
+    def get_details(self):
+        return self.original.get_details()
+
+
 class DocTestMatches(object):
     """See if a string matches a doctest example."""
 
@@ -480,15 +505,16 @@
             return AnnotatedMismatch(self.annotation, mismatch)
 
 
-class AnnotatedMismatch(Mismatch):
+class AnnotatedMismatch(MismatchDecorator):
     """A mismatch annotated with a descriptive string."""
 
     def __init__(self, annotation, mismatch):
+        super(AnnotatedMismatch, self).__init__(mismatch)
         self.annotation = annotation
         self.mismatch = mismatch
 
     def describe(self):
-        return '%s: %s' % (self.mismatch.describe(), self.annotation)
+        return '%s: %s' % (self.original.describe(), self.annotation)
 
 
 class Raises(Matcher):

=== modified file 'testtools/tests/test_matchers.py'
--- testtools/tests/test_matchers.py	2011-01-22 17:56:00 +0000
+++ testtools/tests/test_matchers.py	2011-04-01 14:11:40 +0000
@@ -14,6 +14,7 @@
 from testtools.matchers import (
     AfterPreproccessing,
     Annotate,
+    AnnotatedMismatch,
     Equals,
     DocTestMatches,
     DoesNotEndWith,
@@ -30,6 +31,7 @@
     MatchesSetwise,
     MatchesStructure,
     Mismatch,
+    MismatchDecorator,
     Not,
     NotEquals,
     Raises,
@@ -330,6 +332,14 @@
     describe_examples = [("1 != 2: foo", 2, Annotate('foo', Equals(1)))]
 
 
+class TestAnnotatedMismatch(TestCase):
+
+    def test_forwards_details(self):
+        x = Mismatch('description', {'foo': 'bar'})
+        annotated = AnnotatedMismatch("annotation", x)
+        self.assertEqual(x.get_details(), annotated.get_details())
+
+
 class TestRaisesInterface(TestCase, TestMatchersInterface):
 
     matches_matcher = Raises()
@@ -660,6 +670,26 @@
         ]
 
 
+class TestMismatchDecorator(TestCase):
+
+    def test_forwards_description(self):
+        x = Mismatch("description", {'foo': 'bar'})
+        decorated = MismatchDecorator(x)
+        self.assertEqual(x.describe(), decorated.describe())
+
+    def test_forwards_details(self):
+        x = Mismatch("description", {'foo': 'bar'})
+        decorated = MismatchDecorator(x)
+        self.assertEqual(x.get_details(), decorated.get_details())
+
+    def test_repr(self):
+        x = Mismatch("description", {'foo': 'bar'})
+        decorated = MismatchDecorator(x)
+        self.assertEqual(
+            '<testtools.matchers.MismatchDecorator(%r)>' % (x,),
+            repr(decorated))
+
+
 def test_suite():
     from unittest import TestLoader
     return TestLoader().loadTestsFromName(__name__)


Follow ups