summaryrefslogtreecommitdiff
path: root/lib/subunit/python/testtools/matchers.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/subunit/python/testtools/matchers.py')
-rw-r--r--lib/subunit/python/testtools/matchers.py282
1 files changed, 0 insertions, 282 deletions
diff --git a/lib/subunit/python/testtools/matchers.py b/lib/subunit/python/testtools/matchers.py
deleted file mode 100644
index 039c84b7c7..0000000000
--- a/lib/subunit/python/testtools/matchers.py
+++ /dev/null
@@ -1,282 +0,0 @@
-# Copyright (c) 2009 Jonathan M. Lange. See LICENSE for details.
-
-"""Matchers, a way to express complex assertions outside the testcase.
-
-Inspired by 'hamcrest'.
-
-Matcher provides the abstract API that all matchers need to implement.
-
-Bundled matchers are listed in __all__: a list can be obtained by running
-$ python -c 'import testtools.matchers; print testtools.matchers.__all__'
-"""
-
-__metaclass__ = type
-__all__ = [
- 'Annotate',
- 'DocTestMatches',
- 'Equals',
- 'MatchesAll',
- 'MatchesAny',
- 'NotEquals',
- 'Not',
- ]
-
-import doctest
-
-
-class Matcher:
- """A pattern matcher.
-
- A Matcher must implement match and __str__ to be used by
- testtools.TestCase.assertThat. Matcher.match(thing) returns None when
- thing is completely matched, and a Mismatch object otherwise.
-
- Matchers can be useful outside of test cases, as they are simply a
- pattern matching language expressed as objects.
-
- testtools.matchers is inspired by hamcrest, but is pythonic rather than
- a Java transcription.
- """
-
- def match(self, something):
- """Return None if this matcher matches something, a Mismatch otherwise.
- """
- raise NotImplementedError(self.match)
-
- def __str__(self):
- """Get a sensible human representation of the matcher.
-
- This should include the parameters given to the matcher and any
- state that would affect the matches operation.
- """
- raise NotImplementedError(self.__str__)
-
-
-class Mismatch:
- """An object describing a mismatch detected by a Matcher."""
-
- def describe(self):
- """Describe the mismatch.
-
- This should be either a human-readable string or castable to a string.
- """
- raise NotImplementedError(self.describe_difference)
-
-
-class DocTestMatches:
- """See if a string matches a doctest example."""
-
- def __init__(self, example, flags=0):
- """Create a DocTestMatches to match example.
-
- :param example: The example to match e.g. 'foo bar baz'
- :param flags: doctest comparison flags to match on. e.g.
- doctest.ELLIPSIS.
- """
- if not example.endswith('\n'):
- example += '\n'
- self.want = example # required variable name by doctest.
- self.flags = flags
- self._checker = doctest.OutputChecker()
-
- def __str__(self):
- if self.flags:
- flagstr = ", flags=%d" % self.flags
- else:
- flagstr = ""
- return 'DocTestMatches(%r%s)' % (self.want, flagstr)
-
- def _with_nl(self, actual):
- result = str(actual)
- if not result.endswith('\n'):
- result += '\n'
- return result
-
- def match(self, actual):
- with_nl = self._with_nl(actual)
- if self._checker.check_output(self.want, with_nl, self.flags):
- return None
- return DocTestMismatch(self, with_nl)
-
- def _describe_difference(self, with_nl):
- return self._checker.output_difference(self, with_nl, self.flags)
-
-
-class DocTestMismatch:
- """Mismatch object for DocTestMatches."""
-
- def __init__(self, matcher, with_nl):
- self.matcher = matcher
- self.with_nl = with_nl
-
- def describe(self):
- return self.matcher._describe_difference(self.with_nl)
-
-
-class Equals:
- """Matches if the items are equal."""
-
- def __init__(self, expected):
- self.expected = expected
-
- def match(self, other):
- if self.expected == other:
- return None
- return EqualsMismatch(self.expected, other)
-
- def __str__(self):
- return "Equals(%r)" % self.expected
-
-
-class EqualsMismatch:
- """Two things differed."""
-
- def __init__(self, expected, other):
- self.expected = expected
- self.other = other
-
- def describe(self):
- return "%r != %r" % (self.expected, self.other)
-
-
-class NotEquals:
- """Matches if the items are not equal.
-
- In most cases, this is equivalent to `Not(Equals(foo))`. The difference
- only matters when testing `__ne__` implementations.
- """
-
- def __init__(self, expected):
- self.expected = expected
-
- def __str__(self):
- return 'NotEquals(%r)' % (self.expected,)
-
- def match(self, other):
- if self.expected != other:
- return None
- return NotEqualsMismatch(self.expected, other)
-
-
-class NotEqualsMismatch:
- """Two things are the same."""
-
- def __init__(self, expected, other):
- self.expected = expected
- self.other = other
-
- def describe(self):
- return '%r == %r' % (self.expected, self.other)
-
-
-class MatchesAny:
- """Matches if any of the matchers it is created with match."""
-
- def __init__(self, *matchers):
- self.matchers = matchers
-
- def match(self, matchee):
- results = []
- for matcher in self.matchers:
- mismatch = matcher.match(matchee)
- if mismatch is None:
- return None
- results.append(mismatch)
- return MismatchesAll(results)
-
- def __str__(self):
- return "MatchesAny(%s)" % ', '.join([
- str(matcher) for matcher in self.matchers])
-
-
-class MatchesAll:
- """Matches if all of the matchers it is created with match."""
-
- def __init__(self, *matchers):
- self.matchers = matchers
-
- def __str__(self):
- return 'MatchesAll(%s)' % ', '.join(map(str, self.matchers))
-
- def match(self, matchee):
- results = []
- for matcher in self.matchers:
- mismatch = matcher.match(matchee)
- if mismatch is not None:
- results.append(mismatch)
- if results:
- return MismatchesAll(results)
- else:
- return None
-
-
-class MismatchesAll:
- """A mismatch with many child mismatches."""
-
- def __init__(self, mismatches):
- self.mismatches = mismatches
-
- def describe(self):
- descriptions = ["Differences: ["]
- for mismatch in self.mismatches:
- descriptions.append(mismatch.describe())
- descriptions.append("]\n")
- return '\n'.join(descriptions)
-
-
-class Not:
- """Inverts a matcher."""
-
- def __init__(self, matcher):
- self.matcher = matcher
-
- def __str__(self):
- return 'Not(%s)' % (self.matcher,)
-
- def match(self, other):
- mismatch = self.matcher.match(other)
- if mismatch is None:
- return MatchedUnexpectedly(self.matcher, other)
- else:
- return None
-
-
-class MatchedUnexpectedly:
- """A thing matched when it wasn't supposed to."""
-
- def __init__(self, matcher, other):
- self.matcher = matcher
- self.other = other
-
- def describe(self):
- return "%r matches %s" % (self.other, self.matcher)
-
-
-class Annotate:
- """Annotates a matcher with a descriptive string.
-
- Mismatches are then described as '<mismatch>: <annotation>'.
- """
-
- def __init__(self, annotation, matcher):
- self.annotation = annotation
- self.matcher = matcher
-
- def __str__(self):
- return 'Annotate(%r, %s)' % (self.annotation, self.matcher)
-
- def match(self, other):
- mismatch = self.matcher.match(other)
- if mismatch is not None:
- return AnnotatedMismatch(self.annotation, mismatch)
-
-
-class AnnotatedMismatch:
- """A mismatch annotated with a descriptive string."""
-
- def __init__(self, annotation, mismatch):
- self.annotation = annotation
- self.mismatch = mismatch
-
- def describe(self):
- return '%s: %s' % (self.mismatch.describe(), self.annotation)