Skip to content

Commit

Permalink
Merge branch 'master' of github.com:gabrielfalcao/sure
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielfalcao committed Mar 20, 2017
2 parents c59b874 + a77273d commit b24da79
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 9 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

*Nothing to release yet*
*Nothing here yet.*

## [v1.4.2]
### Added
- `ensure` context manager to provide custom assertion messages. Refs #125

## [v1.4.1]
### Added
Expand Down Expand Up @@ -41,7 +45,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).

Please see `git log`

[Unreleased]: https://github.com/gabrielfalcao/sure/compare/v1.4.1...HEAD
[Unreleased]: https://github.com/gabrielfalcao/sure/compare/v1.4.2...HEAD
[v1.4.2]: https://github.com/gabrielfalcao/sure/compare/1.4.1...v1.4.2
[v1.4.1]: https://github.com/gabrielfalcao/sure/compare/1.4.0...v1.4.1
[v1.4.0]: https://github.com/gabrielfalcao/sure/compare/1.3.0...v1.4.0
[v1.3.0]: https://github.com/gabrielfalcao/sure/compare/1.2.9...v1.3.0
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Installing
Documentation
-------------

Available in the `website <https://sure.readthedocs.io>`__ or under the
Available in the `website <https://sure.readthedocs.io/en/latest/>`__ or under the
``docs`` directory.

You can also build the documentation locally using sphinx:
Expand Down
26 changes: 23 additions & 3 deletions docs/source/api-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ Add custom assertions, chains and chain properties
``sure`` allows to add custom assertion methods, chain methods and chain properties.

Custom assertion methods
------------------------
~~~~~~~~~~~~~~~~~~~~~~~~

By default ``sure`` comes with a good amount of *assertion methods*. For example:

Expand Down Expand Up @@ -853,7 +853,7 @@ I'll admit you have to write the assertion method yourself, but the result is a


Chain methods
-------------
~~~~~~~~~~~~~

*chain methods* are similar to *assertion methods*. The only difference is that the *chain methods*, as the name implies, can be chained with further chains or assertions:

Expand All @@ -874,7 +874,7 @@ Chain methods
Chain properties
----------------
~~~~~~~~~~~~~~~~

*chain properties* are simple properties which are available to build an assertion.
Some of the default chain properties are:
Expand Down Expand Up @@ -919,3 +919,23 @@ Use the ``chainproperty`` decorator like the following to build your own *chain*
# Build awesome assertion chains
expect(Foo).having.attribute('magic')
Foo.doesnt.implement.attribute('nomagic')
Use custom assertion messages with ``ensure``
---------------------------------------------

With the ``ensure`` context manager *sure* provides an easy to use way to override the ``AssertionError`` message raised by ``sure``'s assertion methods. See the following example:

.. code:: python
import sure
name = myapi.do_something_that_returns_string()
with sure.ensure('the return value actually looks like: {0}', name):
name.should.contain('whatever')
In case ``name`` does not contain the string ``whatever`` it will raise an ``AssertionError`` exception
with the message *the return value actually looks like: <NAME>* (where *<NAME>* would be the actual value of the variable ``name``) instead of *sure*'s default error message in that particular case.

Only ``AssertionError`` exceptions are re-raised by ``sure.ensure()`` with the custom provided message. Every other exception will be ignored and handled as expected.
4 changes: 2 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@
# built documents.
#
# The short X.Y version.
version = '1.4.1'
version = '1.4.2'
# The full version, including alpha/beta/rc tags.
release = '1.4.1'
release = '1.4.2'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
30 changes: 29 additions & 1 deletion sure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
if not PY2:
basestring = str

version = '1.4.1'
version = '1.4.2'


not_here_error = \
Expand Down Expand Up @@ -941,6 +941,34 @@ def chainproperty(func):
return func


class ensure(object):
"""
Contextmanager to ensure that the given assertion message
is printed upon a raised ``AssertionError`` exception.
The ``args`` and ``kwargs`` are used to format
the message using ``format()``.
"""
def __init__(self, msg, *args, **kwargs):
self.msg = msg
self.args = args
self.kwargs = kwargs

def __enter__(self):
return self

def __exit__(self, exc_type, exc_value, traceback):
"""
Catch all ``AsertionError`` exceptions and reraise
them with the message provided to the context manager.
"""
if exc_type is not AssertionError:
return

msg = self.msg.format(*self.args, **self.kwargs)
raise AssertionError(msg)


allows_new_syntax = not os.getenv('SURE_DISABLE_NEW_SYNTAX')


Expand Down
32 changes: 32 additions & 0 deletions tests/test_ensure_ctxmgr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-

import sure


def test_ensure_simple_assertion():
"""Test ensure simple assertion"""

def __test_something():
# same calculated value
name = 'Hodor'
with sure.ensure('the return value actually looks like: {0}', name):
sure.expect(name).should.contain('whatever')


# check if the test function raises the custom AssertionError
sure.expect(__test_something).when.called_with().should.throw(AssertionError, \
'the return value actually looks like: Hodor')


def test_ensure_just_assertion_error():
"""Test that ensure only captures AssertionErrors"""
def __test_something():
# same calculated value
with sure.ensure('neverused'):
raise Exception('This is not an AssertionError')


# check if the test function does not override the original exception
# if it is not an AssertionError exception
sure.expect(__test_something).when.called_with().should.throw(Exception, \
'This is not an AssertionError')

0 comments on commit b24da79

Please sign in to comment.