Source code for verify.runners

"""Assertion runners.
"""

import re

import verify
from .base import Assertion, is_assertion


__all__ = (
    'ensure',
    'expect',
)


[docs]class expect(object): """Pass `value` through a set of assertable functions. There are two styles for invoking ``expect``: 1. Pass `value` and all `assertions` as arguments to the ``__init__`` method of ``expect``. 2. Pass `value` to the ``__init__`` method of ``expect`` and invoke assertions via method chaining. Examples: Passing `value` and `assertions` to ``expect.__init__``: >>> from verify import * >>> expect(5, Truthy(), Greater(4)) <expect(5)> >>> expect(5, Falsy()) Traceback (most recent call last): ... AssertionError... Using method chaining: >>> expect(5).Truthy().Greater(4) <expect(5)> >>> expect(5).Falsy() Traceback (most recent call last): ... AssertionError... Args: value (mixed): Value to test. *assertions (callable, optional): Callable objects that accept `value` as its first argument. It's expected that these callables assert something. Returns: self: Allows for method assertion chaining. Raises: AssertionError: If the evaluation of all assertions returns ``False``. Aliases: - ``ensure`` .. versionadded:: 0.0.1 .. versionchanged:: 0.1.0 - Rename from ``Expect`` to ``expect`` and change implementation from a class to a function. - Passed in `value` is no longer called if it's a callable. - Return ``True`` if all assertions pass. .. versionchanged:: 0.6.0 - Re-implement as class. - Support method chaining of assertion classes. - Wrap assertions that are not derived from Assertion in :class:`.Predicate` for consistent behavior from external assertion functions. """ def __init__(self, value, *assertions): self.value = value if assertions: self(*assertions) def __repr__(self): # pragma: no cover return '<{0}>'.format(self) def __str__(self): # pragma: no cover return '{0}({1})'.format(self.__class__.__name__, self.value)
[docs] def __getattr__(self, attr): """Invoke assertions via attribute access. All :mod:`verify` assertions are available. """ assertion = getattr(verify, attr, None) if not callable(assertion) and not attr.endswith('_'): # Alias method names not ending in underscore to their underscore # counterpart. This allows chaining of functions that have a name # conflict with builtins (e.g. "any_", "all_", etc). assertion = getattr(verify, attr + '_', None) if not is_assertion(assertion): raise AttributeError(('"{0}" is not a valid assertion method' .format(attr))) def chained_assertion(*args, **kargs): assertion(*args, **kargs)(self.value) return self chained_assertion.assertion = assertion return chained_assertion
def __call__(self, *assertions): for assertion in assertions: if not is_assertion(assertion): # Wrap non-verify assertions in Predicate for consistent # behavior. assertion = verify.Predicate(assertion) assertion(self.value) return self
ensure = expect