Skip to content

Commit

Permalink
Merge d261ec3 into 3fb4ab4
Browse files Browse the repository at this point in the history
  • Loading branch information
catriuspham authored May 31, 2017
2 parents 3fb4ab4 + d261ec3 commit 2d52af0
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 5 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,22 @@ expect({'foo': 'bar'}).to.exclude('baz')

#### throw

Asserts that the target throws an exception
Asserts that the target throws an exception (or its parent)

```python
expect(lambda: raise_exception(...)).to.throw(Exception)
expect(lambda: raise_exception(...)).to.throw(ParentException)
expect(any_callable).to.throw(Exception)
expect(any_callable).to.throw(ParentException)
```

#### throw_exactly

Asserts that the target throws exactly an exception (not its parent)

```python
expect(lambda: raise_exception(...)).to.throw_exactly(Exception)
expect(any_callable).to.throw_exactly(Exception)
```

#### called
Expand Down
19 changes: 18 additions & 1 deletion robber/matchers/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,31 @@ def raised(self):
def matches(self):
return isinstance(self.raised, self.expected)

@property
def verb(self):
return 'be raised'

@property
def explanation(self):
if self.raised:
got = self.raised.__class__.__name__
else:
got = 'nothing'

return Explanation(self.expected.__name__, self.is_negative, 'be raised', other=got)
return Explanation(self.expected.__name__, self.is_negative, self.verb, other=got)


class ExactExceptionMatcher(ExceptionMatcher):
"""
expect(lambda: call_something(with_some_params)).to.throw_exactly(any_exception)
"""

def matches(self):
return type(self.raised) == self.expected

@property
def verb(self):
return 'be exactly raised'

expect.register('throw', ExceptionMatcher)
expect.register('throw_exactly', ExactExceptionMatcher)
16 changes: 16 additions & 0 deletions tests/integrations/test_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,19 @@ def test_not_exception_success(self):
@must_fail
def test_not_exception_failure(self):
expect(lambda: 1 / 0).not_to.throw(ZeroDivisionError)


class TestExactExceptionIntegrations(TestCase):
def test_exact_exception_success(self):
expect(lambda: 1 / 0).to.throw_exactly(ZeroDivisionError)

@must_fail
def test_exact_exception_failure(self):
expect(lambda: 1 / 0).to.throw_exactly(Exception)

def test_not_exact_exception_success(self):
expect(lambda: 1 / 0).not_to.throw_exactly(Exception)

@must_fail
def test_not_exact_exception_failure(self):
expect(lambda: 1 / 0).not_to.throw_exactly(ZeroDivisionError)
60 changes: 57 additions & 3 deletions tests/matchers/test_exception.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import unittest
from unittest import TestCase

from robber import expect
from robber.matchers.exception import ExceptionMatcher
from robber.matchers.exception import ExceptionMatcher, ExactExceptionMatcher


class TestExceptionMatcher(unittest.TestCase):
class TestExceptionMatcher(TestCase):
def raise_exception(self, ex):
raise ex

def test_verb(self):
exception = ExceptionMatcher(lambda: 1 / 1)
expect(exception.verb).to.eq('be raised')

def test_matches(self):
expect(ExceptionMatcher(lambda: 1 / 0, ZeroDivisionError).matches()).to.eq(True)
expect(ExceptionMatcher(lambda: 1 / 0, Exception).matches()).to.eq(True)
expect(ExceptionMatcher(lambda: None, Exception).matches()).to.eq(False)

def test_actual_is_not_callable(self):
Expand Down Expand Up @@ -44,3 +49,52 @@ def test_explanation_message_with_no_exception_was_raised(self):
Expected A to be raised
Actually raised Z
"""

def test_register(self):
expect(expect.matcher('throw')) == ExceptionMatcher


class TestExactExceptionMatcher(TestCase):
def raise_exception(self, ex):
raise ex

def test_verb(self):
exception = ExactExceptionMatcher(lambda: 1 + 1)
expect(exception.verb).to.eq('be exactly raised')

def test_matches(self):
expect(ExactExceptionMatcher(lambda: 1 / 0, ZeroDivisionError).matches()).to.eq(True)
expect(ExactExceptionMatcher(lambda: 1 / 0, Exception).matches()).to.eq(False)

def test_explanation_message_with_wrong_exception(self):
exception_raised = ExactExceptionMatcher(lambda: self.raise_exception(TypeError()), ZeroDivisionError)
message = exception_raised.explanation.message
expect(message) == """
A = 'ZeroDivisionError'
Z = 'TypeError'
Expected A to be exactly raised
Actually exactly raised Z
"""

def test_negative_explanation_message_with_wrong_exception(self):
exception_raised = ExactExceptionMatcher(
lambda: self.raise_exception(ZeroDivisionError()), ZeroDivisionError, is_negative=True)
message = exception_raised.explanation.message
expect(message) == """
A = 'ZeroDivisionError'
Expected A not to be exactly raised
But it happened
"""

def test_explanation_message_with_no_exception_was_raised(self):
no_exception = ExactExceptionMatcher(lambda: None, Exception)
message = no_exception.explanation.message
expect(message) == """
A = 'Exception'
Z = 'nothing'
Expected A to be exactly raised
Actually exactly raised Z
"""

def test_register(self):
expect(expect.matcher('throw_exactly')) == ExactExceptionMatcher

0 comments on commit 2d52af0

Please sign in to comment.