Source code for doubles.targets.allowance_target

from inspect import stack

from doubles.lifecycle import current_space
from doubles.class_double import ClassDouble
from doubles.exceptions import ConstructorDoubleError


[docs]def allow(target): """ Prepares a target object for a method call allowance (stub). The name of the method to allow should be called as a method on the return value of this function:: allow(foo).bar Accessing the ``bar`` attribute will return an ``Allowance`` which provides additional methods to configure the stub. :param object target: The object that will be stubbed. :return: An ``AllowanceTarget`` for the target object. """ return AllowanceTarget(target)
[docs]def allow_constructor(target): """ Set an allowance on a ``ClassDouble`` constructor This allows the caller to control what a ClassDouble returns when a new instance is created. :param ClassDouble target: The ClassDouble to set the allowance on. :return: an ``Allowance`` for the __new__ method. :raise: ``ConstructorDoubleError`` if target is not a ClassDouble. """ if not isinstance(target, ClassDouble): raise ConstructorDoubleError( 'Cannot allow_constructor of {} since it is not a ClassDouble.'.format(target), ) return allow(target)._doubles__new__
class AllowanceTarget(object): """A wrapper around a target object that creates new allowances on attribute access.""" def __init__(self, target): """ :param object target: The object to wrap. """ self._proxy = current_space().proxy_for(target) def __getattribute__(self, attr_name): """ Returns the value of existing attributes, and returns a new allowance for any attribute that doesn't yet exist. :param str attr_name: The name of the attribute to look up. :return: The existing value or a new ``Allowance``. :rtype: object, Allowance """ __dict__ = object.__getattribute__(self, '__dict__') if __dict__ and attr_name in __dict__: return __dict__[attr_name] caller = stack()[1] return self._proxy.add_allowance(attr_name, caller)