1 # Copyright (c) 2008-2010 Jonathan M. Lange. See LICENSE for details.
3 """Tests for matchers."""
8 from testtools import (
9 Matcher, # check that Matcher is exposed at the top level for docs.
12 from testtools.matchers import (
37 class TestMismatch(TestCase):
39 def test_constructor_arguments(self):
40 mismatch = Mismatch("some description", {'detail': "things"})
41 self.assertEqual("some description", mismatch.describe())
42 self.assertEqual({'detail': "things"}, mismatch.get_details())
44 def test_constructor_no_arguments(self):
46 self.assertThat(mismatch.describe,
47 Raises(MatchesException(NotImplementedError)))
48 self.assertEqual({}, mismatch.get_details())
51 class TestMatchersInterface(object):
53 def test_matches_match(self):
54 matcher = self.matches_matcher
55 matches = self.matches_matches
56 mismatches = self.matches_mismatches
57 for candidate in matches:
58 self.assertEqual(None, matcher.match(candidate))
59 for candidate in mismatches:
60 mismatch = matcher.match(candidate)
61 self.assertNotEqual(None, mismatch)
62 self.assertNotEqual(None, getattr(mismatch, 'describe', None))
64 def test__str__(self):
65 # [(expected, object to __str__)].
66 examples = self.str_examples
67 for expected, matcher in examples:
68 self.assertThat(matcher, DocTestMatches(expected))
70 def test_describe_difference(self):
71 # [(expected, matchee, matcher), ...]
72 examples = self.describe_examples
73 for difference, matchee, matcher in examples:
74 mismatch = matcher.match(matchee)
75 self.assertEqual(difference, mismatch.describe())
77 def test_mismatch_details(self):
78 # The mismatch object must provide get_details, which must return a
79 # dictionary mapping names to Content objects.
80 examples = self.describe_examples
81 for difference, matchee, matcher in examples:
82 mismatch = matcher.match(matchee)
83 details = mismatch.get_details()
84 self.assertEqual(dict(details), details)
87 class TestDocTestMatchesInterface(TestCase, TestMatchersInterface):
89 matches_matcher = DocTestMatches("Ran 1 test in ...s", doctest.ELLIPSIS)
90 matches_matches = ["Ran 1 test in 0.000s", "Ran 1 test in 1.234s"]
91 matches_mismatches = ["Ran 1 tests in 0.000s", "Ran 2 test in 0.000s"]
93 str_examples = [("DocTestMatches('Ran 1 test in ...s\\n')",
94 DocTestMatches("Ran 1 test in ...s")),
95 ("DocTestMatches('foo\\n', flags=8)", DocTestMatches("foo", flags=8)),
98 describe_examples = [('Expected:\n Ran 1 tests in ...s\nGot:\n'
99 ' Ran 1 test in 0.123s\n', "Ran 1 test in 0.123s",
100 DocTestMatches("Ran 1 tests in ...s", doctest.ELLIPSIS))]
103 class TestDocTestMatchesSpecific(TestCase):
105 def test___init__simple(self):
106 matcher = DocTestMatches("foo")
107 self.assertEqual("foo\n", matcher.want)
109 def test___init__flags(self):
110 matcher = DocTestMatches("bar\n", doctest.ELLIPSIS)
111 self.assertEqual("bar\n", matcher.want)
112 self.assertEqual(doctest.ELLIPSIS, matcher.flags)
115 class TestEqualsInterface(TestCase, TestMatchersInterface):
117 matches_matcher = Equals(1)
118 matches_matches = [1]
119 matches_mismatches = [2]
121 str_examples = [("Equals(1)", Equals(1)), ("Equals('1')", Equals('1'))]
123 describe_examples = [("1 != 2", 2, Equals(1))]
126 class TestNotEqualsInterface(TestCase, TestMatchersInterface):
128 matches_matcher = NotEquals(1)
129 matches_matches = [2]
130 matches_mismatches = [1]
133 ("NotEquals(1)", NotEquals(1)), ("NotEquals('1')", NotEquals('1'))]
135 describe_examples = [("1 == 1", 1, NotEquals(1))]
138 class TestIsInterface(TestCase, TestMatchersInterface):
143 matches_matcher = Is(foo)
144 matches_matches = [foo]
145 matches_mismatches = [bar, 1]
147 str_examples = [("Is(2)", Is(2))]
149 describe_examples = [("1 is not 2", 2, Is(1))]
152 class TestLessThanInterface(TestCase, TestMatchersInterface):
154 matches_matcher = LessThan(4)
155 matches_matches = [-5, 3]
156 matches_mismatches = [4, 5, 5000]
159 ("LessThan(12)", LessThan(12)),
162 describe_examples = [('4 is >= 4', 4, LessThan(4))]
165 def make_error(type, *args, **kwargs):
167 raise type(*args, **kwargs)
169 return sys.exc_info()
172 class TestMatchesExceptionInstanceInterface(TestCase, TestMatchersInterface):
174 matches_matcher = MatchesException(ValueError("foo"))
175 error_foo = make_error(ValueError, 'foo')
176 error_bar = make_error(ValueError, 'bar')
177 error_base_foo = make_error(Exception, 'foo')
178 matches_matches = [error_foo]
179 matches_mismatches = [error_bar, error_base_foo]
182 ("MatchesException(Exception('foo',))",
183 MatchesException(Exception('foo')))
185 describe_examples = [
186 ("%r is not a %r" % (Exception, ValueError),
188 MatchesException(ValueError("foo"))),
189 ("ValueError('bar',) has different arguments to ValueError('foo',).",
191 MatchesException(ValueError("foo"))),
195 class TestMatchesExceptionTypeInterface(TestCase, TestMatchersInterface):
197 matches_matcher = MatchesException(ValueError)
198 error_foo = make_error(ValueError, 'foo')
199 error_sub = make_error(UnicodeError, 'bar')
200 error_base_foo = make_error(Exception, 'foo')
201 matches_matches = [error_foo, error_sub]
202 matches_mismatches = [error_base_foo]
205 ("MatchesException(%r)" % Exception,
206 MatchesException(Exception))
208 describe_examples = [
209 ("%r is not a %r" % (Exception, ValueError),
211 MatchesException(ValueError)),
215 class TestNotInterface(TestCase, TestMatchersInterface):
217 matches_matcher = Not(Equals(1))
218 matches_matches = [2]
219 matches_mismatches = [1]
222 ("Not(Equals(1))", Not(Equals(1))),
223 ("Not(Equals('1'))", Not(Equals('1')))]
225 describe_examples = [('1 matches Equals(1)', 1, Not(Equals(1)))]
228 class TestMatchersAnyInterface(TestCase, TestMatchersInterface):
230 matches_matcher = MatchesAny(DocTestMatches("1"), DocTestMatches("2"))
231 matches_matches = ["1", "2"]
232 matches_mismatches = ["3"]
235 "MatchesAny(DocTestMatches('1\\n'), DocTestMatches('2\\n'))",
236 MatchesAny(DocTestMatches("1"), DocTestMatches("2"))),
239 describe_examples = [("""Differences: [
251 "3", MatchesAny(DocTestMatches("1"), DocTestMatches("2")))]
254 class TestMatchesAllInterface(TestCase, TestMatchersInterface):
256 matches_matcher = MatchesAll(NotEquals(1), NotEquals(2))
257 matches_matches = [3, 4]
258 matches_mismatches = [1, 2]
261 ("MatchesAll(NotEquals(1), NotEquals(2))",
262 MatchesAll(NotEquals(1), NotEquals(2)))]
264 describe_examples = [("""Differences: [
267 1, MatchesAll(NotEquals(1), NotEquals(2)))]
270 class TestKeysEqual(TestCase, TestMatchersInterface):
272 matches_matcher = KeysEqual('foo', 'bar')
274 {'foo': 0, 'bar': 1},
276 matches_mismatches = [
280 {'foo': 0, 'bar': 1, 'baz': 2},
281 {'a': None, 'b': None, 'c': None},
285 ("KeysEqual('foo', 'bar')", KeysEqual('foo', 'bar')),
288 describe_examples = [
289 ("['bar', 'foo'] does not match {'baz': 2, 'foo': 0, 'bar': 1}: "
291 {'foo': 0, 'bar': 1, 'baz': 2}, KeysEqual('foo', 'bar')),
295 class TestAnnotate(TestCase, TestMatchersInterface):
297 matches_matcher = Annotate("foo", Equals(1))
298 matches_matches = [1]
299 matches_mismatches = [2]
302 ("Annotate('foo', Equals(1))", Annotate("foo", Equals(1)))]
304 describe_examples = [("1 != 2: foo", 2, Annotate('foo', Equals(1)))]
307 class TestRaisesInterface(TestCase, TestMatchersInterface):
309 matches_matcher = Raises()
311 raise Exception('foo')
312 matches_matches = [boom]
313 matches_mismatches = [lambda:None]
315 # Tricky to get function objects to render constantly, and the interfaces
316 # helper uses assertEqual rather than (for instance) DocTestMatches.
319 describe_examples = []
322 class TestRaisesExceptionMatcherInterface(TestCase, TestMatchersInterface):
324 matches_matcher = Raises(
325 exception_matcher=MatchesException(Exception('foo')))
327 raise Exception('bar')
329 raise Exception('foo')
330 matches_matches = [boom_foo]
331 matches_mismatches = [lambda:None, boom_bar]
333 # Tricky to get function objects to render constantly, and the interfaces
334 # helper uses assertEqual rather than (for instance) DocTestMatches.
337 describe_examples = []
340 class TestRaisesBaseTypes(TestCase):
343 raise KeyboardInterrupt('foo')
345 def test_KeyboardInterrupt_matched(self):
346 # When KeyboardInterrupt is matched, it is swallowed.
347 matcher = Raises(MatchesException(KeyboardInterrupt))
348 self.assertThat(self.raiser, matcher)
350 def test_KeyboardInterrupt_propogates(self):
351 # The default 'it raised' propogates KeyboardInterrupt.
352 match_keyb = Raises(MatchesException(KeyboardInterrupt))
353 def raise_keyb_from_match():
355 matcher.match(self.raiser)
356 self.assertThat(raise_keyb_from_match, match_keyb)
358 def test_KeyboardInterrupt_match_Exception_propogates(self):
359 # If the raised exception isn't matched, and it is not a subclass of
360 # Exception, it is propogated.
361 match_keyb = Raises(MatchesException(KeyboardInterrupt))
362 def raise_keyb_from_match():
363 if sys.version_info > (2, 5):
364 matcher = Raises(MatchesException(Exception))
366 # On Python 2.4 KeyboardInterrupt is a StandardError subclass
367 # but should propogate from less generic exception matchers
368 matcher = Raises(MatchesException(EnvironmentError))
369 matcher.match(self.raiser)
370 self.assertThat(raise_keyb_from_match, match_keyb)
373 class TestRaisesConvenience(TestCase):
375 def test_exc_type(self):
376 self.assertThat(lambda: 1/0, raises(ZeroDivisionError))
378 def test_exc_value(self):
379 e = RuntimeError("You lose!")
382 self.assertThat(raiser, raises(e))
385 class DoesNotStartWithTests(TestCase):
387 def test_describe(self):
388 mismatch = DoesNotStartWith("fo", "bo")
389 self.assertEqual("'fo' does not start with 'bo'.", mismatch.describe())
392 class StartsWithTests(TestCase):
395 matcher = StartsWith("bar")
396 self.assertEqual("Starts with 'bar'.", str(matcher))
398 def test_match(self):
399 matcher = StartsWith("bar")
400 self.assertIs(None, matcher.match("barf"))
402 def test_mismatch_returns_does_not_start_with(self):
403 matcher = StartsWith("bar")
404 self.assertIsInstance(matcher.match("foo"), DoesNotStartWith)
406 def test_mismatch_sets_matchee(self):
407 matcher = StartsWith("bar")
408 mismatch = matcher.match("foo")
409 self.assertEqual("foo", mismatch.matchee)
411 def test_mismatch_sets_expected(self):
412 matcher = StartsWith("bar")
413 mismatch = matcher.match("foo")
414 self.assertEqual("bar", mismatch.expected)
417 class DoesNotEndWithTests(TestCase):
419 def test_describe(self):
420 mismatch = DoesNotEndWith("fo", "bo")
421 self.assertEqual("'fo' does not end with 'bo'.", mismatch.describe())
424 class EndsWithTests(TestCase):
427 matcher = EndsWith("bar")
428 self.assertEqual("Ends with 'bar'.", str(matcher))
430 def test_match(self):
431 matcher = EndsWith("arf")
432 self.assertIs(None, matcher.match("barf"))
434 def test_mismatch_returns_does_not_end_with(self):
435 matcher = EndsWith("bar")
436 self.assertIsInstance(matcher.match("foo"), DoesNotEndWith)
438 def test_mismatch_sets_matchee(self):
439 matcher = EndsWith("bar")
440 mismatch = matcher.match("foo")
441 self.assertEqual("foo", mismatch.matchee)
443 def test_mismatch_sets_expected(self):
444 matcher = EndsWith("bar")
445 mismatch = matcher.match("foo")
446 self.assertEqual("bar", mismatch.expected)
450 from unittest import TestLoader
451 return TestLoader().loadTestsFromName(__name__)