testtools-dev team mailing list archive
-
testtools-dev team
-
Mailing list archive
-
Message #01046
[Merge] lp:~jml/testtools/same-members into lp:testtools
Jonathan Lange has proposed merging lp:~jml/testtools/same-members into lp:testtools.
Requested reviews:
testtools committers (testtools-committers)
For more details, see:
https://code.launchpad.net/~jml/testtools/same-members/+merge/109331
I saw assertContentEquals in Launchpad's base test case and I thought, "How awful! This ought to be a matcher." And lo, it was so.
This has the advantage of having a nicer error message.
--
https://code.launchpad.net/~jml/testtools/same-members/+merge/109331
Your team testtools developers is subscribed to branch lp:testtools.
=== modified file 'testtools/matchers.py'
--- testtools/matchers.py 2012-05-28 14:24:55 +0000
+++ testtools/matchers.py 2012-06-08 11:08:20 +0000
@@ -1277,6 +1277,28 @@
return Equals(f(self.path)).match(f(other_path))
+class SameMembers(Matcher):
+ """Matches if two iterators have the same members.
+
+ This is not the same as set equivalence. The two iterators must be of the
+ same length and have the same repetitions.
+ """
+
+ def __init__(self, expected):
+ super(SameMembers, self).__init__()
+ self.expected = expected
+
+ def __str__(self):
+ return '%s(%r)' % (self.__class__.__name__, self.expected)
+
+ def match(self, observed):
+ expected = sorted(self.expected)
+ observed = sorted(observed)
+ if expected == observed:
+ return
+ return _BinaryMismatch(expected, "elements differ", observed)
+
+
class HasPermissions(Matcher):
"""Matches if a file has the given permissions.
=== modified file 'testtools/tests/test_matchers.py'
--- testtools/tests/test_matchers.py 2012-05-28 14:24:55 +0000
+++ testtools/tests/test_matchers.py 2012-06-08 11:08:20 +0000
@@ -60,6 +60,7 @@
PathExists,
Raises,
raises,
+ SameMembers,
SamePath,
StartsWith,
TarballContains,
@@ -1101,6 +1102,36 @@
]
+class TestSameMembers(TestCase, TestMatchersInterface):
+
+ matches_matcher = SameMembers([1, 1, 2, 3, {'foo': 'bar'}])
+ matches_matches = [
+ [1, 1, 2, 3, {'foo': 'bar'}],
+ [3, {'foo': 'bar'}, 1, 2, 1],
+ [3, 2, 1, {'foo': 'bar'}, 1],
+ (2, {'foo': 'bar'}, 3, 1, 1),
+ ]
+ matches_mismatches = [
+ set([1, 2, 3]),
+ [1, 1, 2, 3, 5],
+ 'foo',
+ ]
+
+ describe_examples = [
+ (("elements differ:\n"
+ "reference = ['apple', 'banana', 'canteloupe', 'lemon', 'orange', 'watermelon']\n"
+ "actual = ['apple', 'banana', 'canteloupe', 'lemon', 'orange', 'sparrow']\n"),
+ ['orange', 'apple', 'banana', 'sparrow', 'lemon', 'canteloupe',],
+ SameMembers(
+ ['apple', 'orange', 'canteloupe', 'watermelon',
+ 'lemon', 'banana',])),
+ ]
+
+ str_examples = [
+ ('SameMembers([1, 2, 3])', SameMembers([1, 2, 3])),
+ ]
+
+
class PathHelpers(object):
def mkdtemp(self):
Follow ups