← Back to team overview

testtools-dev team mailing list archive

[Merge] lp:~jml/testtools/any-match into lp:testtools

 

Jonathan Lange has proposed merging lp:~jml/testtools/any-match into lp:testtools.

Commit message:
Add new matcher, AnyMatch

Requested reviews:
  testtools committers (testtools-committers)

For more details, see:
https://code.launchpad.net/~jml/testtools/any-match/+merge/139720

Deep in the yak stack I go.

This adds a new matcher, AnyMatch. It's a lot like AllMatch, but where AllMatch
guarantees that all items in a collection match a given matcher, this checks that
just one of them do.

Contains(x) is equivalent to AnyMatch(Equals(x)).

Feels a lot like we're dancing around a deeper issue in Python.
-- 
https://code.launchpad.net/~jml/testtools/any-match/+merge/139720
Your team testtools developers is subscribed to branch lp:testtools.
=== modified file 'NEWS'
--- NEWS	2012-12-10 23:48:16 +0000
+++ NEWS	2012-12-13 15:10:43 +0000
@@ -6,6 +6,13 @@
 NEXT
 ~~~~
 
+Improvements
+------------
+
+* ``AnyMatch`` added, a new matcher that matches when any item in a collection
+  matches the given matcher.  (Jonathan Lange)
+
+
 0.9.22
 ~~~~~~
 

=== modified file 'testtools/matchers/_higherorder.py'
--- testtools/matchers/_higherorder.py	2012-09-10 11:37:46 +0000
+++ testtools/matchers/_higherorder.py	2012-12-13 15:10:43 +0000
@@ -236,6 +236,26 @@
             return MismatchesAll(mismatches)
 
 
+class AnyMatch(object):
+    """Matches if any of the provided values match the given matcher."""
+
+    def __init__(self, matcher):
+        self.matcher = matcher
+
+    def __str__(self):
+        return 'AnyMatch(%s)' % (self.matcher,)
+
+    def match(self, values):
+        mismatches = []
+        for value in values:
+            mismatch = self.matcher.match(value)
+            if mismatch:
+                mismatches.append(mismatch)
+            else:
+                return None
+        return MismatchesAll(mismatches)
+
+
 class MatchesPredicate(Matcher):
     """Match if a given function returns True.
 

=== modified file 'testtools/tests/matchers/test_higherorder.py'
--- testtools/tests/matchers/test_higherorder.py	2012-09-08 17:21:06 +0000
+++ testtools/tests/matchers/test_higherorder.py	2012-12-13 15:10:43 +0000
@@ -14,6 +14,7 @@
     AllMatch,
     Annotate,
     AnnotatedMismatch,
+    AnyMatch,
     MatchesAny,
     MatchesAll,
     MatchesPredicate,
@@ -50,6 +51,38 @@
         ]
 
 
+class TestAnyMatch(TestCase, TestMatchersInterface):
+
+    matches_matcher = AnyMatch(Equals('elephant'))
+    matches_matches = [
+        ['grass', 'cow', 'steak', 'milk', 'elephant'],
+        (13, 'elephant'),
+        ['elephant', 'elephant', 'elephant'],
+        set(['hippo', 'rhino', 'elephant']),
+        ]
+    matches_mismatches = [
+        [],
+        ['grass', 'cow', 'steak', 'milk'],
+        (13, 12, 10),
+        ['element', 'hephalump', 'pachyderm'],
+        set(['hippo', 'rhino', 'diplodocus']),
+        ]
+
+    str_examples = [
+        ("AnyMatch(Equals('elephant'))", AnyMatch(Equals('elephant'))),
+        ]
+
+    describe_examples = [
+        ('Differences: [\n'
+         '7 != 11\n'
+         '7 != 9\n'
+         '7 != 10\n'
+         ']',
+         [11, 9, 10],
+         AnyMatch(Equals(7))),
+        ]
+
+
 class TestAfterPreprocessing(TestCase, TestMatchersInterface):
 
     def parity(x):


Follow ups