← Back to team overview

testtools-dev team mailing list archive

[Merge] lp:~jml/testtools/structure-from-dict into lp:testtools

 

Jonathan Lange has proposed merging lp:~jml/testtools/structure-from-dict into lp:testtools.

Requested reviews:
  testtools developers (testtools-dev)

For more details, see:
https://code.launchpad.net/~jml/testtools/structure-from-dict/+merge/68409

Inspired by a post to the launchpad-dev mailing list, this adds a new factory for MatchesStructure that takes the kwargs and assumes that we want to match the values by equality.

-- 
https://code.launchpad.net/~jml/testtools/structure-from-dict/+merge/68409
Your team testtools developers is requested to review the proposed merge of lp:~jml/testtools/structure-from-dict into lp:testtools.
=== modified file 'NEWS'
--- NEWS	2011-07-06 23:09:46 +0000
+++ NEWS	2011-07-19 15:38:31 +0000
@@ -19,6 +19,9 @@
 * Less boilerplate displayed in test failures and errors.
   (Jonathan Lange, #660852)
 
+* ``MatchesStructure.byEquality`` added to make the common case of matching
+  many attributes by equality much easier.  (Jonathan Lange)
+
 * New convenience assertions, ``assertIsNone`` and ``assertIsNotNone``.
   (Christian Kampka)
 

=== modified file 'doc/for-test-authors.rst'
--- doc/for-test-authors.rst	2011-06-30 17:01:10 +0000
+++ doc/for-test-authors.rst	2011-07-19 15:38:31 +0000
@@ -584,6 +584,16 @@
       matcher = MatchesStructure(a=Equals(1), b=Equals(2))
       self.assertThat(foo, matcher)
 
+Since all of the matchers used were ``Equals``, we could also write this using
+the ``byEquality`` helper::
+
+  def test_matches_structure_example(self):
+      foo = Foo()
+      foo.a = 1
+      foo.b = 2
+      matcher = MatchesStructure.byEquality(a=1, b=2)
+      self.assertThat(foo, matcher)
+
 ``MatchesStructure.from_example`` takes an object and a list of attributes and
 creates a ``MatchesStructure`` matcher where each attribute of the matched
 object must equal each attribute of the example object.  For example::

=== modified file 'testtools/matchers.py'
--- testtools/matchers.py	2011-07-18 20:29:08 +0000
+++ testtools/matchers.py	2011-07-19 15:38:31 +0000
@@ -642,6 +642,10 @@
 
     `fromExample` allows the creation of a matcher from a prototype object and
     then modified versions can be created with `update`.
+
+    `byEquality` creates a matcher in much the same way as the constructor,
+    except that the matcher for each of the attributes is assumed to be
+    `Equals`.
     """
 
     def __init__(self, **kwargs):
@@ -652,6 +656,15 @@
         self.kws = kwargs
 
     @classmethod
+    def byEquality(cls, **kwargs):
+        """Matches an object where the attributes equal the keyword values.
+
+        Similar to the constructor, except that the matcher is assumed to be
+        Equals.
+        """
+        return cls(**dict((name, Equals(value)) for name, value in kwargs.items()))
+
+    @classmethod
     def fromExample(cls, example, *attributes):
         kwargs = {}
         for attr in attributes:

=== modified file 'testtools/tests/test_matchers.py'
--- testtools/tests/test_matchers.py	2011-07-11 10:26:05 +0000
+++ testtools/tests/test_matchers.py	2011-07-19 15:38:31 +0000
@@ -583,6 +583,11 @@
             self.SimpleClass(1, 2),
             MatchesStructure.fromExample(self.SimpleClass(1, 3), 'x'))
 
+    def test_byEquality(self):
+        self.assertThat(
+            self.SimpleClass(1, 2),
+            MatchesStructure.byEquality(x=1))
+
     def test_update(self):
         self.assertThat(
             self.SimpleClass(1, 2),


Follow ups