# Path: doubles/instance_double.py
# class InstanceDouble(ObjectDouble):
#     """A pure double representing an instance of the target class.
# 
#     Any kwargs supplied will be set as attributes on the instance that is
#     created.
# 
#     ::
# 
#         user = InstanceDouble('myapp.User', name='Bob Barker')
# 
#     :param str path: The absolute module path to the class.
#     """
# 
#     def __init__(self, path, **kwargs):
#         module_path, class_name = get_path_components(path)
#         module = get_module(module_path, path)
#         self._doubles_target = _get_doubles_target(module, class_name, path)
#         for k, v in kwargs.items():
#             setattr(self, k, v)
# 
# Path: doubles/lifecycle.py
# @contextmanager
# def no_builtin_verification():
#     """Turn off validation for builtin methods
# 
#     While inside this context we will ignore errors raised while verifying the
#     arguments of builtins.
# 
#     Note: It is impossible to verify the expected arguments of built in functions
#     """
#     current_space().skip_builtin_verification = True
#     yield
#     current_space().skip_builtin_verification = False
# 
# Path: doubles/targets/allowance_target.py
# 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)
# 
# Path: doubles/exceptions.py
# class VerifyingDoubleArgumentError(AssertionError):
#     """
#     An exception raised when attempting to double a method with arguments that do not match the
#     signature of the real method.
#     """
# 
#     pass
# 
# class VerifyingDoubleError(AssertionError):
#     """
#     An exception raised when attempting to double a method that does not exist on the real object.
#     """
# 
#     def __init__(self, method_name, doubled_obj):
#         """
#         :param str method_name: The name of the method to double.
#         :param object doubled_obj: The real object being doubled.
#         """
# 
#         self._method_name = method_name
#         self._doubled_obj = doubled_obj
#         self.args = (method_name, doubled_obj)
#         self.message = "Cannot double method '{}' of '{}'."
# 
#     def no_matching_method(self):
#         self.message = "Cannot double method '{}' because {} does not implement it."
# 
#         return self
# 
#     def not_callable(self):
#         self.message = "Cannot double method '{}' because it is not a callable attribute on {}."
# 
#         return self
# 
#     def requires_instance(self):
#         self.message = "Cannot double method '{}' because it is not callable directly on {}."
# 
#         return self
# 
#     def __str__(self):
#         return self.message.format(self._method_name, self._doubled_obj)
# 
# class VerifyingDoubleImportError(AssertionError):
#     """
#     An exception raised when attempting to create a verifying double from an invalid module path.
#     """


from pytest import raises
from doubles import allow, InstanceDouble, no_builtin_verification
from doubles.exceptions import (
    VerifyingDoubleArgumentError,
    VerifyingDoubleError,
    VerifyingDoubleImportError
)
        with raises(VerifyingDoubleError):
            allow(date).nonexistent_method

    def test_raises_when_stubbing_noncallable_attributes(self):
        date = InstanceDouble('datetime.date')

        with raises(VerifyingDoubleError):
            allow(date).year

    def test_raises_when_argspec_does_not_match(self):
        date = InstanceDouble('datetime.date')

        with raises(VerifyingDoubleArgumentError):
            allow(date).ctime.with_args('foo')

    def test_allows_stubs_on_existing_class_methods(self):
        with no_builtin_verification():
            date = InstanceDouble('datetime.date')

            allow(date).today.with_args()

            assert date.today() is None

    def test_raises_when_target_is_a_top_level_module(self):
        with raises(VerifyingDoubleImportError) as e:
            InstanceDouble('foo')

        assert str(e.value) == 'Invalid import path: foo.'

    def test_raises_on_import_error(self):

# Path: doubles/instance_double.py
# class InstanceDouble(ObjectDouble):
#     """A pure double representing an instance of the target class.
# 
#     Any kwargs supplied will be set as attributes on the instance that is
#     created.
# 
#     ::
# 
#         user = InstanceDouble('myapp.User', name='Bob Barker')
# 
#     :param str path: The absolute module path to the class.
#     """
# 
#     def __init__(self, path, **kwargs):
#         module_path, class_name = get_path_components(path)
#         module = get_module(module_path, path)
#         self._doubles_target = _get_doubles_target(module, class_name, path)
#         for k, v in kwargs.items():
#             setattr(self, k, v)
# 
# Path: doubles/lifecycle.py
# @contextmanager
# def no_builtin_verification():
#     """Turn off validation for builtin methods
# 
#     While inside this context we will ignore errors raised while verifying the
#     arguments of builtins.
# 
#     Note: It is impossible to verify the expected arguments of built in functions
#     """
#     current_space().skip_builtin_verification = True
#     yield
#     current_space().skip_builtin_verification = False
# 
# Path: doubles/targets/allowance_target.py
# 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)
# 
# Path: doubles/exceptions.py
# class VerifyingDoubleArgumentError(AssertionError):
#     """
#     An exception raised when attempting to double a method with arguments that do not match the
#     signature of the real method.
#     """
# 
#     pass
# 
# class VerifyingDoubleError(AssertionError):
#     """
#     An exception raised when attempting to double a method that does not exist on the real object.
#     """
# 
#     def __init__(self, method_name, doubled_obj):
#         """
#         :param str method_name: The name of the method to double.
#         :param object doubled_obj: The real object being doubled.
#         """
# 
#         self._method_name = method_name
#         self._doubled_obj = doubled_obj
#         self.args = (method_name, doubled_obj)
#         self.message = "Cannot double method '{}' of '{}'."
# 
#     def no_matching_method(self):
#         self.message = "Cannot double method '{}' because {} does not implement it."
# 
#         return self
# 
#     def not_callable(self):
#         self.message = "Cannot double method '{}' because it is not a callable attribute on {}."
# 
#         return self
# 
#     def requires_instance(self):
#         self.message = "Cannot double method '{}' because it is not callable directly on {}."
# 
#         return self
# 
#     def __str__(self):
#         return self.message.format(self._method_name, self._doubled_obj)
# 
# class VerifyingDoubleImportError(AssertionError):
#     """
#     An exception raised when attempting to create a verifying double from an invalid module path.
#     """


# Path: test/instance_double_test.py
from pytest import raises
from doubles import allow, InstanceDouble, no_builtin_verification
from doubles.exceptions import (
    VerifyingDoubleArgumentError,
    VerifyingDoubleError,
    VerifyingDoubleImportError
)

        with raises(VerifyingDoubleError):
            allow(date).nonexistent_method

    def test_raises_when_stubbing_noncallable_attributes(self):
        date = InstanceDouble('datetime.date')

        with raises(VerifyingDoubleError):
            allow(date).year

    def test_raises_when_argspec_does_not_match(self):
        date = InstanceDouble('datetime.date')

        with raises(VerifyingDoubleArgumentError):
            allow(date).ctime.with_args('foo')

    def test_allows_stubs_on_existing_class_methods(self):
        with no_builtin_verification():
            date = InstanceDouble('datetime.date')

            allow(date).today.with_args()

            assert date.today() is None

    def test_raises_when_target_is_a_top_level_module(self):
        with raises(VerifyingDoubleImportError) as e:
            InstanceDouble('foo')

        assert str(e.value) == 'Invalid import path: foo.'

    def test_raises_on_import_error(self):

        with raises(VerifyingDoubleImportError) as e: