# Copyright (C) 2007-2012 Michael Foord & the mock team
# E-mail: fuzzyman AT voidspace DOT org DOT uk
# http://www.voidspace.org.uk/python/mock/

import os
import sys

from tests import support
from tests.support import unittest2, inPy3k, SomeClass, is_instance, callable

from mock import (
    NonCallableMock, CallableMixin, patch, sentinel,
    MagicMock, Mock, NonCallableMagicMock, patch, _patch,
    DEFAULT, call, _get_target
)

builtin_string = '__builtin__'
if inPy3k:
    builtin_string = 'builtins'
    unicode = str

PTModule = sys.modules[__name__]
MODNAME = '%s.PTModule' % __name__


def _get_proxy(obj, get_only=True):
    class Proxy(object):
        def __getattr__(self, name):
            return getattr(obj, name)
    if not get_only:
        def __setattr__(self, name, value):
            setattr(obj, name, value)
        def __delattr__(self, name):
            delattr(obj, name)
        Proxy.__setattr__ = __setattr__
        Proxy.__delattr__ = __delattr__
    return Proxy()


# for use in the test
something  = sentinel.Something
something_else  = sentinel.SomethingElse


class Foo(object):
    def __init__(self, a):
        pass
    def f(self, a):
        pass
    def g(self):
        pass
    foo = 'bar'

    class Bar(object):
        def a(self):
            pass

foo_name = '%s.Foo' % __name__


def function(a, b=Foo):
    pass


class Container(object):
    def __init__(self):
        self.values = {}

    def __getitem__(self, name):
        return self.values[name]

    def __setitem__(self, name, value):
        self.values[name] = value

    def __delitem__(self, name):
        del self.values[name]

    def __iter__(self):
        return iter(self.values)



class PatchTest(unittest2.TestCase):

    def assertNotCallable(self, obj, magic=True):
        MockClass = NonCallableMagicMock
        if not magic:
            MockClass = NonCallableMock

        self.assertRaises(TypeError, obj)
        self.assertTrue(is_instance(obj, MockClass))
        self.assertFalse(is_instance(obj, CallableMixin))


    def test_single_patchobject(self):
        class Something(object):
            attribute = sentinel.Original

        @patch.object(Something, 'attribute', sentinel.Patched)
        def test():
            self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")

        test()
        self.assertEqual(Something.attribute, sentinel.Original,
                         "patch not restored")


    def test_patchobject_with_none(self):
        class Something(object):
            attribute = sentinel.Original

        @patch.object(Something, 'attribute', None)
        def test():
            self.assertIsNone(Something.attribute, "unpatched")

        test()
        self.assertEqual(Something.attribute, sentinel.Original,
                         "patch not restored")


    def test_multiple_patchobject(self):
        class Something(object):
            attribute = sentinel.Original
            next_attribute = sentinel.Original2

        @patch.object(Something, 'attribute', sentinel.Patched)
        @patch.object(Something, 'next_attribute', sentinel.Patched2)
        def test():
            self.assertEqual(Something.attribute, sentinel.Patched,
                             "unpatched")
            self.assertEqual(Something.next_attribute, sentinel.Patched2,
                             "unpatched")

        test()
        self.assertEqual(Something.attribute, sentinel.Original,
                         "patch not restored")
        self.assertEqual(Something.next_attribute, sentinel.Original2,
                         "patch not restored")


    def test_object_lookup_is_quite_lazy(self):
        global something
        original = something
        @patch('%s.something' % __name__, sentinel.Something2)
        def test():
            pass

        try:
            something = sentinel.replacement_value
            test()
            self.assertEqual(something, sentinel.replacement_value)
        finally:
            something = original


    def test_patch(self):
        @patch('%s.something' % __name__, sentinel.Something2)
        def test():
            self.assertEqual(PTModule.something, sentinel.Something2,
                             "unpatched")

        test()
        self.assertEqual(PTModule.something, sentinel.Something,
                         "patch not restored")

        @patch('%s.something' % __name__, sentinel.Something2)
        @patch('%s.something_else' % __name__, sentinel.SomethingElse)
        def test():
            self.assertEqual(PTModule.something, sentinel.Something2,
                             "unpatched")
            self.assertEqual(PTModule.something_else, sentinel.SomethingElse,
                             "unpatched")

        self.assertEqual(PTModule.something, sentinel.Something,
                         "patch not restored")
        self.assertEqual(PTModule.something_else, sentinel.SomethingElse,
                         "patch not restored")

        # Test the patching and restoring works a second time
        test()

        self.assertEqual(PTModule.something, sentinel.Something,
                         "patch not restored")
        self.assertEqual(PTModule.something_else, sentinel.SomethingElse,
                         "patch not restored")

        mock = Mock()
        mock.return_value = sentinel.Handle
        @patch('%s.open' % builtin_string, mock)
        def test():
            self.assertEqual(open('filename', 'r'), sentinel.Handle,
                             "open not patched")
        test()
        test()

        self.assertNotEqual(open, mock, "patch not restored")


    def test_patch_class_attribute(self):
        @patch('%s.SomeClass.class_attribute' % __name__,
               sentinel.ClassAttribute)
        def test():
            self.assertEqual(PTModule.SomeClass.class_attribute,
                             sentinel.ClassAttribute, "unpatched")
        test()

        self.assertIsNone(PTModule.SomeClass.class_attribute,
                          "patch not restored")


    def test_patchobject_with_default_mock(self):
        class Test(object):
            something = sentinel.Original
            something2 = sentinel.Original2

        @patch.object(Test, 'something')
        def test(mock):
            self.assertEqual(mock, Test.something,
                             "Mock not passed into test function")
            self.assertIsInstance(mock, MagicMock,
                            "patch with two arguments did not create a mock")

        test()

        @patch.object(Test, 'something')
        @patch.object(Test, 'something2')
        def test(this1, this2, mock1, mock2):
            self.assertEqual(this1, sentinel.this1,
                             "Patched function didn't receive initial argument")
            self.assertEqual(this2, sentinel.this2,
                             "Patched function didn't receive second argument")
            self.assertEqual(mock1, Test.something2,
                             "Mock not passed into test function")
            self.assertEqual(mock2, Test.something,
                             "Second Mock not passed into test function")
            self.assertIsInstance(mock2, MagicMock,
                            "patch with two arguments did not create a mock")
            self.assertIsInstance(mock2, MagicMock,
                            "patch with two arguments did not create a mock")

            # A hack to test that new mocks are passed the second time
            self.assertNotEqual(outerMock1, mock1, "unexpected value for mock1")
            self.assertNotEqual(outerMock2, mock2, "unexpected value for mock1")
            return mock1, mock2

        outerMock1 = outerMock2 = None
        outerMock1, outerMock2 = test(sentinel.this1, sentinel.this2)

        # Test that executing a second time creates new mocks
        test(sentinel.this1, sentinel.this2)


    def test_patch_with_spec(self):
        @patch('%s.SomeClass' % __name__, spec=SomeClass)
        def test(MockSomeClass):
            self.assertEqual(SomeClass, MockSomeClass)
            self.assertTrue(is_instance(SomeClass.wibble, MagicMock))
            self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)

        test()


    def test_patchobject_with_spec(self):
        @patch.object(SomeClass, 'class_attribute', spec=SomeClass)
        def test(MockAttribute):
            self.assertEqual(SomeClass.class_attribute, MockAttribute)
            self.assertTrue(is_instance(SomeClass.class_attribute.wibble,
                                       MagicMock))
            self.assertRaises(AttributeError,
                              lambda: SomeClass.class_attribute.not_wibble)

        test()


    def test_patch_with_spec_as_list(self):
        @patch('%s.SomeClass' % __name__, spec=['wibble'])
        def test(MockSomeClass):
            self.assertEqual(SomeClass, MockSomeClass)
            self.assertTrue(is_instance(SomeClass.wibble, MagicMock))
            self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)

        test()


    def test_patchobject_with_spec_as_list(self):
        @patch.object(SomeClass, 'class_attribute', spec=['wibble'])
        def test(MockAttribute):
            self.assertEqual(SomeClass.class_attribute, MockAttribute)
            self.assertTrue(is_instance(SomeClass.class_attribute.wibble,
                                       MagicMock))
            self.assertRaises(AttributeError,
                              lambda: SomeClass.class_attribute.not_wibble)

        test()


    def test_nested_patch_with_spec_as_list(self):
        # regression test for nested decorators
        @patch('%s.open' % builtin_string)
        @patch('%s.SomeClass' % __name__, spec=['wibble'])
        def test(MockSomeClass, MockOpen):
            self.assertEqual(SomeClass, MockSomeClass)
            self.assertTrue(is_instance(SomeClass.wibble, MagicMock))
            self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
        test()


    def test_patch_with_spec_as_boolean(self):
        @patch('%s.SomeClass' % __name__, spec=True)
        def test(MockSomeClass):
            self.assertEqual(SomeClass, MockSomeClass)
            # Should not raise attribute error
            MockSomeClass.wibble

            self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble)

        test()


    def test_patch_object_with_spec_as_boolean(self):
        @patch.object(PTModule, 'SomeClass', spec=True)
        def test(MockSomeClass):
            self.assertEqual(SomeClass, MockSomeClass)
            # Should not raise attribute error
            MockSomeClass.wibble

            self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble)

        test()


    def test_patch_class_acts_with_spec_is_inherited(self):
        @patch('%s.SomeClass' % __name__, spec=True)
        def test(MockSomeClass):
            self.assertTrue(is_instance(MockSomeClass, MagicMock))
            instance = MockSomeClass()
            self.assertNotCallable(instance)
            # Should not raise attribute error
            instance.wibble

            self.assertRaises(AttributeError, lambda: instance.not_wibble)

        test()


    def test_patch_with_create_mocks_non_existent_attributes(self):
        @patch('%s.frooble' % builtin_string, sentinel.Frooble, create=True)
        def test():
            self.assertEqual(frooble, sentinel.Frooble)

        test()
        self.assertRaises(NameError, lambda: frooble)


    def test_patchobject_with_create_mocks_non_existent_attributes(self):
        @patch.object(SomeClass, 'frooble', sentinel.Frooble, create=True)
        def test():
            self.assertEqual(SomeClass.frooble, sentinel.Frooble)

        test()
        self.assertFalse(hasattr(SomeClass, 'frooble'))


    def test_patch_wont_create_by_default(self):
        try:
            @patch('%s.frooble' % builtin_string, sentinel.Frooble)
            def test():
                self.assertEqual(frooble, sentinel.Frooble)

            test()
        except AttributeError:
            pass
        else:
            self.fail('Patching non existent attributes should fail')

        self.assertRaises(NameError, lambda: frooble)


    def test_patchobject_wont_create_by_default(self):
        try:
            @patch.object(SomeClass, 'frooble', sentinel.Frooble)
            def test():
                self.fail('Patching non existent attributes should fail')

            test()
        except AttributeError:
            pass
        else:
            self.fail('Patching non existent attributes should fail')
        self.assertFalse(hasattr(SomeClass, 'frooble'))


    def test_patch_with_static_methods(self):
        class Foo(object):
            @staticmethod
            def woot():
                return sentinel.Static

        @patch.object(Foo, 'woot', staticmethod(lambda: sentinel.Patched))
        def anonymous():
            self.assertEqual(Foo.woot(), sentinel.Patched)
        anonymous()

        self.assertEqual(Foo.woot(), sentinel.Static)


    def test_patch_local(self):
        foo = sentinel.Foo
        @patch.object(sentinel, 'Foo', 'Foo')
        def anonymous():
            self.assertEqual(sentinel.Foo, 'Foo')
        anonymous()

        self.assertEqual(sentinel.Foo, foo)


    def test_patch_slots(self):
        class Foo(object):
            __slots__ = ('Foo',)

        foo = Foo()
        foo.Foo = sentinel.Foo

        @patch.object(foo, 'Foo', 'Foo')
        def anonymous():
            self.assertEqual(foo.Foo, 'Foo')
        anonymous()

        self.assertEqual(foo.Foo, sentinel.Foo)


    def test_patchobject_class_decorator(self):
        class Something(object):
            attribute = sentinel.Original

        class Foo(object):
            def test_method(other_self):
                self.assertEqual(Something.attribute, sentinel.Patched,
                                 "unpatched")
            def not_test_method(other_self):
                self.assertEqual(Something.attribute, sentinel.Original,
                                 "non-test method patched")

        Foo = patch.object(Something, 'attribute', sentinel.Patched)(Foo)

        f = Foo()
        f.test_method()
        f.not_test_method()

        self.assertEqual(Something.attribute, sentinel.Original,
                         "patch not restored")


    def test_patch_class_decorator(self):
        class Something(object):
            attribute = sentinel.Original

        class Foo(object):
            def test_method(other_self, mock_something):
                self.assertEqual(PTModule.something, mock_something,
                                 "unpatched")
            def not_test_method(other_self):
                self.assertEqual(PTModule.something, sentinel.Something,
                                 "non-test method patched")
        Foo = patch('%s.something' % __name__)(Foo)

        f = Foo()
        f.test_method()
        f.not_test_method()

        self.assertEqual(Something.attribute, sentinel.Original,
                         "patch not restored")
        self.assertEqual(PTModule.something, sentinel.Something,
                         "patch not restored")


    def test_patchobject_twice(self):
        class Something(object):
            attribute = sentinel.Original
            next_attribute = sentinel.Original2

        @patch.object(Something, 'attribute', sentinel.Patched)
        @patch.object(Something, 'attribute', sentinel.Patched)
        def test():
            self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")

        test()

        self.assertEqual(Something.attribute, sentinel.Original,
                         "patch not restored")


    def test_patch_dict(self):
        foo = {'initial': object(), 'other': 'something'}
        original = foo.copy()

        @patch.dict(foo)
        def test():
            foo['a'] = 3
            del foo['initial']
            foo['other'] = 'something else'

        test()

        self.assertEqual(foo, original)

        @patch.dict(foo, {'a': 'b'})
        def test():
            self.assertEqual(len(foo), 3)
            self.assertEqual(foo['a'], 'b')

        test()

        self.assertEqual(foo, original)

        @patch.dict(foo, [('a', 'b')])
        def test():
            self.assertEqual(len(foo), 3)
            self.assertEqual(foo['a'], 'b')

        test()

        self.assertEqual(foo, original)


    def test_patch_dict_with_container_object(self):
        foo = Container()
        foo['initial'] = object()
        foo['other'] =  'something'

        original = foo.values.copy()

        @patch.dict(foo)
        def test():
            foo['a'] = 3
            del foo['initial']
            foo['other'] = 'something else'

        test()

        self.assertEqual(foo.values, original)

        @patch.dict(foo, {'a': 'b'})
        def test():
            self.assertEqual(len(foo.values), 3)
            self.assertEqual(foo['a'], 'b')

        test()

        self.assertEqual(foo.values, original)


    def test_patch_dict_with_clear(self):
        foo = {'initial': object(), 'other': 'something'}
        original = foo.copy()

        @patch.dict(foo, clear=True)
        def test():
            self.assertEqual(foo, {})
            foo['a'] = 3
            foo['other'] = 'something else'

        test()

        self.assertEqual(foo, original)

        @patch.dict(foo, {'a': 'b'}, clear=True)
        def test():
            self.assertEqual(foo, {'a': 'b'})

        test()

        self.assertEqual(foo, original)

        @patch.dict(foo, [('a', 'b')], clear=True)
        def test():
            self.assertEqual(foo, {'a': 'b'})

        test()

        self.assertEqual(foo, original)


    def test_patch_dict_with_container_object_and_clear(self):
        foo = Container()
        foo['initial'] = object()
        foo['other'] =  'something'

        original = foo.values.copy()

        @patch.dict(foo, clear=True)
        def test():
            self.assertEqual(foo.values, {})
            foo['a'] = 3
            foo['other'] = 'something else'

        test()

        self.assertEqual(foo.values, original)

        @patch.dict(foo, {'a': 'b'}, clear=True)
        def test():
            self.assertEqual(foo.values, {'a': 'b'})

        test()

        self.assertEqual(foo.values, original)


    def test_name_preserved(self):
        foo = {}

        @patch('%s.SomeClass' % __name__, object())
        @patch('%s.SomeClass' % __name__, object(), autospec=True)
        @patch.object(SomeClass, object())
        @patch.dict(foo)
        def some_name():
            pass

        self.assertEqual(some_name.__name__, 'some_name')


    def test_patch_with_exception(self):
        foo = {}

        @patch.dict(foo, {'a': 'b'})
        def test():
            raise NameError('Konrad')
        try:
            test()
        except NameError:
            pass
        else:
            self.fail('NameError not raised by test')

        self.assertEqual(foo, {})


    def test_patch_dict_with_string(self):
        @patch.dict('os.environ', {'konrad_delong': 'some value'})
        def test():
            self.assertIn('konrad_delong', os.environ)

        test()


    @unittest2.expectedFailure
    def test_patch_descriptor(self):
        # would be some effort to fix this - we could special case the
        # builtin descriptors: classmethod, property, staticmethod
        class Nothing(object):
            foo = None

        class Something(object):
            foo = {}

            @patch.object(Nothing, 'foo', 2)
            @classmethod
            def klass(cls):
                self.assertIs(cls, Something)

            @patch.object(Nothing, 'foo', 2)
            @staticmethod
            def static(arg):
                return arg

            @patch.dict(foo)
            @classmethod
            def klass_dict(cls):
                self.assertIs(cls, Something)

            @patch.dict(foo)
            @staticmethod
            def static_dict(arg):
                return arg

        # these will raise exceptions if patching descriptors is broken
        self.assertEqual(Something.static('f00'), 'f00')
        Something.klass()
        self.assertEqual(Something.static_dict('f00'), 'f00')
        Something.klass_dict()

        something = Something()
        self.assertEqual(something.static('f00'), 'f00')
        something.klass()
        self.assertEqual(something.static_dict('f00'), 'f00')
        something.klass_dict()


    def test_patch_spec_set(self):
        @patch('%s.SomeClass' % __name__, spec_set=SomeClass)
        def test(MockClass):
            MockClass.z = 'foo'

        self.assertRaises(AttributeError, test)

        @patch.object(support, 'SomeClass', spec_set=SomeClass)
        def test(MockClass):
            MockClass.z = 'foo'

        self.assertRaises(AttributeError, test)
        @patch('%s.SomeClass' % __name__, spec_set=True)
        def test(MockClass):
            MockClass.z = 'foo'

        self.assertRaises(AttributeError, test)

        @patch.object(support, 'SomeClass', spec_set=True)
        def test(MockClass):
            MockClass.z = 'foo'

        self.assertRaises(AttributeError, test)


    def test_spec_set_inherit(self):
        @patch('%s.SomeClass' % __name__, spec_set=True)
        def test(MockClass):
            instance = MockClass()
            instance.z = 'foo'

        self.assertRaises(AttributeError, test)


    def test_patch_start_stop(self):
        original = something
        patcher = patch('%s.something' % __name__)
        self.assertIs(something, original)
        mock = patcher.start()
        try:
            self.assertIsNot(mock, original)
            self.assertIs(something, mock)
        finally:
            patcher.stop()
        self.assertIs(something, original)


    def test_stop_without_start(self):
        patcher = patch(foo_name, 'bar', 3)

        # calling stop without start used to produce a very obscure error
        self.assertRaises(RuntimeError, patcher.stop)


    def test_patchobject_start_stop(self):
        original = something
        patcher = patch.object(PTModule, 'something', 'foo')
        self.assertIs(something, original)
        replaced = patcher.start()
        try:
            self.assertEqual(replaced, 'foo')
            self.assertIs(something, replaced)
        finally:
            patcher.stop()
        self.assertIs(something, original)


    def test_patch_dict_start_stop(self):
        d = {'foo': 'bar'}
        original = d.copy()
        patcher = patch.dict(d, [('spam', 'eggs')], clear=True)
        self.assertEqual(d, original)

        patcher.start()
        try:
            self.assertEqual(d, {'spam': 'eggs'})
        finally:
            patcher.stop()
        self.assertEqual(d, original)


    def test_patch_dict_class_decorator(self):
        this = self
        d = {'spam': 'eggs'}
        original = d.copy()

        class Test(object):
            def test_first(self):
                this.assertEqual(d, {'foo': 'bar'})
            def test_second(self):
                this.assertEqual(d, {'foo': 'bar'})

        Test = patch.dict(d, {'foo': 'bar'}, clear=True)(Test)
        self.assertEqual(d, original)

        test = Test()

        test.test_first()
        self.assertEqual(d, original)

        test.test_second()
        self.assertEqual(d, original)

        test = Test()

        test.test_first()
        self.assertEqual(d, original)

        test.test_second()
        self.assertEqual(d, original)


    def test_get_only_proxy(self):
        class Something(object):
            foo = 'foo'
        class SomethingElse:
            foo = 'foo'

        for thing in Something, SomethingElse, Something(), SomethingElse:
            proxy = _get_proxy(thing)

            @patch.object(proxy, 'foo', 'bar')
            def test():
                self.assertEqual(proxy.foo, 'bar')
            test()
            self.assertEqual(proxy.foo, 'foo')
            self.assertEqual(thing.foo, 'foo')
            self.assertNotIn('foo', proxy.__dict__)


    def test_get_set_delete_proxy(self):
        class Something(object):
            foo = 'foo'
        class SomethingElse:
            foo = 'foo'

        for thing in Something, SomethingElse, Something(), SomethingElse:
            proxy = _get_proxy(Something, get_only=False)

            @patch.object(proxy, 'foo', 'bar')
            def test():
                self.assertEqual(proxy.foo, 'bar')
            test()
            self.assertEqual(proxy.foo, 'foo')
            self.assertEqual(thing.foo, 'foo')
            self.assertNotIn('foo', proxy.__dict__)


    def test_patch_keyword_args(self):
        kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33,
                  'foo': MagicMock()}

        patcher = patch(foo_name, **kwargs)
        mock = patcher.start()
        patcher.stop()

        self.assertRaises(KeyError, mock)
        self.assertEqual(mock.foo.bar(), 33)
        self.assertIsInstance(mock.foo, MagicMock)


    def test_patch_object_keyword_args(self):
        kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33,
                  'foo': MagicMock()}

        patcher = patch.object(Foo, 'f', **kwargs)
        mock = patcher.start()
        patcher.stop()

        self.assertRaises(KeyError, mock)
        self.assertEqual(mock.foo.bar(), 33)
        self.assertIsInstance(mock.foo, MagicMock)


    def test_patch_dict_keyword_args(self):
        original = {'foo': 'bar'}
        copy = original.copy()

        patcher = patch.dict(original, foo=3, bar=4, baz=5)
        patcher.start()

        try:
            self.assertEqual(original, dict(foo=3, bar=4, baz=5))
        finally:
            patcher.stop()

        self.assertEqual(original, copy)


    def test_autospec(self):
        class Boo(object):
            def __init__(self, a):
                pass
            def f(self, a):
                pass
            def g(self):
                pass
            foo = 'bar'

            class Bar(object):
                def a(self):
                    pass

        def _test(mock):
            mock(1)
            mock.assert_called_with(1)
            self.assertRaises(TypeError, mock)

        def _test2(mock):
            mock.f(1)
            mock.f.assert_called_with(1)
            self.assertRaises(TypeError, mock.f)

            mock.g()
            mock.g.assert_called_with()
            self.assertRaises(TypeError, mock.g, 1)

            self.assertRaises(AttributeError, getattr, mock, 'h')

            mock.foo.lower()
            mock.foo.lower.assert_called_with()
            self.assertRaises(AttributeError, getattr, mock.foo, 'bar')

            mock.Bar()
            mock.Bar.assert_called_with()

            mock.Bar.a()
            mock.Bar.a.assert_called_with()
            self.assertRaises(TypeError, mock.Bar.a, 1)

            mock.Bar().a()
            mock.Bar().a.assert_called_with()
            self.assertRaises(TypeError, mock.Bar().a, 1)

            self.assertRaises(AttributeError, getattr, mock.Bar, 'b')
            self.assertRaises(AttributeError, getattr, mock.Bar(), 'b')

        def function(mock):
            _test(mock)
            _test2(mock)
            _test2(mock(1))
            self.assertIs(mock, Foo)
            return mock

        test = patch(foo_name, autospec=True)(function)

        mock = test()
        self.assertIsNot(Foo, mock)
        # test patching a second time works
        test()

        module = sys.modules[__name__]
        test = patch.object(module, 'Foo', autospec=True)(function)

        mock = test()
        self.assertIsNot(Foo, mock)
        # test patching a second time works
        test()


    def test_autospec_function(self):
        @patch('%s.function' % __name__, autospec=True)
        def test(mock):
            function(1)
            function.assert_called_with(1)
            function(2, 3)
            function.assert_called_with(2, 3)

            self.assertRaises(TypeError, function)
            self.assertRaises(AttributeError, getattr, function, 'foo')

        test()


    def test_autospec_keywords(self):
        @patch('%s.function' % __name__, autospec=True,
               return_value=3)
        def test(mock_function):
            #self.assertEqual(function.abc, 'foo')
            return function(1, 2)

        result = test()
        self.assertEqual(result, 3)


    def test_autospec_with_new(self):
        patcher = patch('%s.function' % __name__, new=3, autospec=True)
        self.assertRaises(TypeError, patcher.start)

        module = sys.modules[__name__]
        patcher = patch.object(module, 'function', new=3, autospec=True)
        self.assertRaises(TypeError, patcher.start)


    def test_autospec_with_object(self):
        class Bar(Foo):
            extra = []

        patcher = patch(foo_name, autospec=Bar)
        mock = patcher.start()
        try:
            self.assertIsInstance(mock, Bar)
            self.assertIsInstance(mock.extra, list)
        finally:
            patcher.stop()


    def test_autospec_inherits(self):
        FooClass = Foo
        patcher = patch(foo_name, autospec=True)
        mock = patcher.start()
        try:
            self.assertIsInstance(mock, FooClass)
            self.assertIsInstance(mock(3), FooClass)
        finally:
            patcher.stop()


    def test_autospec_name(self):
        patcher = patch(foo_name, autospec=True)
        mock = patcher.start()

        try:
            self.assertIn(" name='Foo'", repr(mock))
            self.assertIn(" name='Foo.f'", repr(mock.f))
            self.assertIn(" name='Foo()'", repr(mock(None)))
            self.assertIn(" name='Foo().f'", repr(mock(None).f))
        finally:
            patcher.stop()


    def test_tracebacks(self):
        @patch.object(Foo, 'f', object())
        def test():
            raise AssertionError
        try:
            test()
        except:
            err = sys.exc_info()

        result = unittest2.TextTestResult(None, None, 0)
        traceback = result._exc_info_to_string(err, self)
        self.assertIn('raise AssertionError', traceback)


    def test_new_callable_patch(self):
        patcher = patch(foo_name, new_callable=NonCallableMagicMock)

        m1 = patcher.start()
        patcher.stop()
        m2 = patcher.start()
        patcher.stop()

        self.assertIsNot(m1, m2)
        for mock in m1, m2:
            self.assertNotCallable(m1)


    def test_new_callable_patch_object(self):
        patcher = patch.object(Foo, 'f', new_callable=NonCallableMagicMock)

        m1 = patcher.start()
        patcher.stop()
        m2 = patcher.start()
        patcher.stop()

        self.assertIsNot(m1, m2)
        for mock in m1, m2:
            self.assertNotCallable(m1)


    def test_new_callable_keyword_arguments(self):
        class Bar(object):
            kwargs = None
            def __init__(self, **kwargs):
                Bar.kwargs = kwargs

        patcher = patch(foo_name, new_callable=Bar, arg1=1, arg2=2)
        m = patcher.start()
        try:
            self.assertIs(type(m), Bar)
            self.assertEqual(Bar.kwargs, dict(arg1=1, arg2=2))
        finally:
            patcher.stop()


    def test_new_callable_spec(self):
        class Bar(object):
            kwargs = None
            def __init__(self, **kwargs):
                Bar.kwargs = kwargs

        patcher = patch(foo_name, new_callable=Bar, spec=Bar)
        patcher.start()
        try:
            self.assertEqual(Bar.kwargs, dict(spec=Bar))
        finally:
            patcher.stop()

        patcher = patch(foo_name, new_callable=Bar, spec_set=Bar)
        patcher.start()
        try:
            self.assertEqual(Bar.kwargs, dict(spec_set=Bar))
        finally:
            patcher.stop()


    def test_new_callable_create(self):
        non_existent_attr = '%s.weeeee' % foo_name
        p = patch(non_existent_attr, new_callable=NonCallableMock)
        self.assertRaises(AttributeError, p.start)

        p = patch(non_existent_attr, new_callable=NonCallableMock,
                  create=True)
        m = p.start()
        try:
            self.assertNotCallable(m, magic=False)
        finally:
            p.stop()


    def test_new_callable_incompatible_with_new(self):
        self.assertRaises(
            ValueError, patch, foo_name, new=object(), new_callable=MagicMock
        )
        self.assertRaises(
            ValueError, patch.object, Foo, 'f', new=object(),
            new_callable=MagicMock
        )


    def test_new_callable_incompatible_with_autospec(self):
        self.assertRaises(
            ValueError, patch, foo_name, new_callable=MagicMock,
            autospec=True
        )
        self.assertRaises(
            ValueError, patch.object, Foo, 'f', new_callable=MagicMock,
            autospec=True
        )


    def test_new_callable_inherit_for_mocks(self):
        class MockSub(Mock):
            pass

        MockClasses = (
            NonCallableMock, NonCallableMagicMock, MagicMock, Mock, MockSub
        )
        for Klass in MockClasses:
            for arg in 'spec', 'spec_set':
                kwargs = {arg: True}
                p = patch(foo_name, new_callable=Klass, **kwargs)
                m = p.start()
                try:
                    instance = m.return_value
                    self.assertRaises(AttributeError, getattr, instance, 'x')
                finally:
                    p.stop()


    def test_new_callable_inherit_non_mock(self):
        class NotAMock(object):
            def __init__(self, spec):
                self.spec = spec

        p = patch(foo_name, new_callable=NotAMock, spec=True)
        m = p.start()
        try:
            self.assertTrue(is_instance(m, NotAMock))
            self.assertRaises(AttributeError, getattr, m, 'return_value')
        finally:
            p.stop()

        self.assertEqual(m.spec, Foo)


    def test_new_callable_class_decorating(self):
        test = self
        original = Foo
        class SomeTest(object):

            def _test(self, mock_foo):
                test.assertIsNot(Foo, original)
                test.assertIs(Foo, mock_foo)
                test.assertIsInstance(Foo, SomeClass)

            def test_two(self, mock_foo):
                self._test(mock_foo)
            def test_one(self, mock_foo):
                self._test(mock_foo)

        SomeTest = patch(foo_name, new_callable=SomeClass)(SomeTest)
        SomeTest().test_one()
        SomeTest().test_two()
        self.assertIs(Foo, original)


    def test_patch_multiple(self):
        original_foo = Foo
        original_f = Foo.f
        original_g = Foo.g

        patcher1 = patch.multiple(foo_name, f=1, g=2)
        patcher2 = patch.multiple(Foo, f=1, g=2)

        for patcher in patcher1, patcher2:
            patcher.start()
            try:
                self.assertIs(Foo, original_foo)
                self.assertEqual(Foo.f, 1)
                self.assertEqual(Foo.g, 2)
            finally:
                patcher.stop()

            self.assertIs(Foo, original_foo)
            self.assertEqual(Foo.f, original_f)
            self.assertEqual(Foo.g, original_g)


        @patch.multiple(foo_name, f=3, g=4)
        def test():
            self.assertIs(Foo, original_foo)
            self.assertEqual(Foo.f, 3)
            self.assertEqual(Foo.g, 4)

        test()


    def test_patch_multiple_no_kwargs(self):
        self.assertRaises(ValueError, patch.multiple, foo_name)
        self.assertRaises(ValueError, patch.multiple, Foo)


    def test_patch_multiple_create_mocks(self):
        original_foo = Foo
        original_f = Foo.f
        original_g = Foo.g

        @patch.multiple(foo_name, f=DEFAULT, g=3, foo=DEFAULT)
        def test(f, foo):
            self.assertIs(Foo, original_foo)
            self.assertIs(Foo.f, f)
            self.assertEqual(Foo.g, 3)
            self.assertIs(Foo.foo, foo)
            self.assertTrue(is_instance(f, MagicMock))
            self.assertTrue(is_instance(foo, MagicMock))

        test()
        self.assertEqual(Foo.f, original_f)
        self.assertEqual(Foo.g, original_g)


    def test_patch_multiple_create_mocks_different_order(self):
        # bug revealed by Jython!
        original_f = Foo.f
        original_g = Foo.g

        patcher = patch.object(Foo, 'f', 3)
        patcher.attribute_name = 'f'

        other = patch.object(Foo, 'g', DEFAULT)
        other.attribute_name = 'g'
        patcher.additional_patchers = [other]

        @patcher
        def test(g):
            self.assertIs(Foo.g, g)
            self.assertEqual(Foo.f, 3)

        test()
        self.assertEqual(Foo.f, original_f)
        self.assertEqual(Foo.g, original_g)


    def test_patch_multiple_stacked_decorators(self):
        original_foo = Foo
        original_f = Foo.f
        original_g = Foo.g

        @patch.multiple(foo_name, f=DEFAULT)
        @patch.multiple(foo_name, foo=DEFAULT)
        @patch(foo_name + '.g')
        def test1(g, **kwargs):
            _test(g, **kwargs)

        @patch.multiple(foo_name, f=DEFAULT)
        @patch(foo_name + '.g')
        @patch.multiple(foo_name, foo=DEFAULT)
        def test2(g, **kwargs):
            _test(g, **kwargs)

        @patch(foo_name + '.g')
        @patch.multiple(foo_name, f=DEFAULT)
        @patch.multiple(foo_name, foo=DEFAULT)
        def test3(g, **kwargs):
            _test(g, **kwargs)

        def _test(g, **kwargs):
            f = kwargs.pop('f')
            foo = kwargs.pop('foo')
            self.assertFalse(kwargs)

            self.assertIs(Foo, original_foo)
            self.assertIs(Foo.f, f)
            self.assertIs(Foo.g, g)
            self.assertIs(Foo.foo, foo)
            self.assertTrue(is_instance(f, MagicMock))
            self.assertTrue(is_instance(g, MagicMock))
            self.assertTrue(is_instance(foo, MagicMock))

        test1()
        test2()
        test3()
        self.assertEqual(Foo.f, original_f)
        self.assertEqual(Foo.g, original_g)


    def test_patch_multiple_create_mocks_patcher(self):
        original_foo = Foo
        original_f = Foo.f
        original_g = Foo.g

        patcher = patch.multiple(foo_name, f=DEFAULT, g=3, foo=DEFAULT)

        result = patcher.start()
        try:
            f = result['f']
            foo = result['foo']
            self.assertEqual(set(result), set(['f', 'foo']))

            self.assertIs(Foo, original_foo)
            self.assertIs(Foo.f, f)
            self.assertIs(Foo.foo, foo)
            self.assertTrue(is_instance(f, MagicMock))
            self.assertTrue(is_instance(foo, MagicMock))
        finally:
            patcher.stop()

        self.assertEqual(Foo.f, original_f)
        self.assertEqual(Foo.g, original_g)


    def test_patch_multiple_decorating_class(self):
        test = self
        original_foo = Foo
        original_f = Foo.f
        original_g = Foo.g

        class SomeTest(object):

            def _test(self, f, foo):
                test.assertIs(Foo, original_foo)
                test.assertIs(Foo.f, f)
                test.assertEqual(Foo.g, 3)
                test.assertIs(Foo.foo, foo)
                test.assertTrue(is_instance(f, MagicMock))
                test.assertTrue(is_instance(foo, MagicMock))

            def test_two(self, f, foo):
                self._test(f, foo)
            def test_one(self, f, foo):
                self._test(f, foo)

        SomeTest = patch.multiple(
            foo_name, f=DEFAULT, g=3, foo=DEFAULT
        )(SomeTest)

        thing = SomeTest()
        thing.test_one()
        thing.test_two()

        self.assertEqual(Foo.f, original_f)
        self.assertEqual(Foo.g, original_g)


    def test_patch_multiple_create(self):
        patcher = patch.multiple(Foo, blam='blam')
        self.assertRaises(AttributeError, patcher.start)

        patcher = patch.multiple(Foo, blam='blam', create=True)
        patcher.start()
        try:
            self.assertEqual(Foo.blam, 'blam')
        finally:
            patcher.stop()

        self.assertFalse(hasattr(Foo, 'blam'))


    def test_patch_multiple_spec_set(self):
        # if spec_set works then we can assume that spec and autospec also
        # work as the underlying machinery is the same
        patcher = patch.multiple(Foo, foo=DEFAULT, spec_set=['a', 'b'])
        result = patcher.start()
        try:
            self.assertEqual(Foo.foo, result['foo'])
            Foo.foo.a(1)
            Foo.foo.b(2)
            Foo.foo.a.assert_called_with(1)
            Foo.foo.b.assert_called_with(2)
            self.assertRaises(AttributeError, setattr, Foo.foo, 'c', None)
        finally:
            patcher.stop()


    def test_patch_multiple_new_callable(self):
        class Thing(object):
            pass

        patcher = patch.multiple(
            Foo, f=DEFAULT, g=DEFAULT, new_callable=Thing
        )
        result = patcher.start()
        try:
            self.assertIs(Foo.f, result['f'])
            self.assertIs(Foo.g, result['g'])
            self.assertIsInstance(Foo.f, Thing)
            self.assertIsInstance(Foo.g, Thing)
            self.assertIsNot(Foo.f, Foo.g)
        finally:
            patcher.stop()


    def test_nested_patch_failure(self):
        original_f = Foo.f
        original_g = Foo.g

        @patch.object(Foo, 'g', 1)
        @patch.object(Foo, 'missing', 1)
        @patch.object(Foo, 'f', 1)
        def thing1():
            pass

        @patch.object(Foo, 'missing', 1)
        @patch.object(Foo, 'g', 1)
        @patch.object(Foo, 'f', 1)
        def thing2():
            pass

        @patch.object(Foo, 'g', 1)
        @patch.object(Foo, 'f', 1)
        @patch.object(Foo, 'missing', 1)
        def thing3():
            pass

        for func in thing1, thing2, thing3:
            self.assertRaises(AttributeError, func)
            self.assertEqual(Foo.f, original_f)
            self.assertEqual(Foo.g, original_g)


    def test_new_callable_failure(self):
        original_f = Foo.f
        original_g = Foo.g
        original_foo = Foo.foo

        def crasher():
            raise NameError('crasher')

        @patch.object(Foo, 'g', 1)
        @patch.object(Foo, 'foo', new_callable=crasher)
        @patch.object(Foo, 'f', 1)
        def thing1():
            pass

        @patch.object(Foo, 'foo', new_callable=crasher)
        @patch.object(Foo, 'g', 1)
        @patch.object(Foo, 'f', 1)
        def thing2():
            pass

        @patch.object(Foo, 'g', 1)
        @patch.object(Foo, 'f', 1)
        @patch.object(Foo, 'foo', new_callable=crasher)
        def thing3():
            pass

        for func in thing1, thing2, thing3:
            self.assertRaises(NameError, func)
            self.assertEqual(Foo.f, original_f)
            self.assertEqual(Foo.g, original_g)
            self.assertEqual(Foo.foo, original_foo)


    def test_patch_multiple_failure(self):
        original_f = Foo.f
        original_g = Foo.g

        patcher = patch.object(Foo, 'f', 1)
        patcher.attribute_name = 'f'

        good = patch.object(Foo, 'g', 1)
        good.attribute_name = 'g'

        bad = patch.object(Foo, 'missing', 1)
        bad.attribute_name = 'missing'

        for additionals in [good, bad], [bad, good]:
            patcher.additional_patchers = additionals

            @patcher
            def func():
                pass

            self.assertRaises(AttributeError, func)
            self.assertEqual(Foo.f, original_f)
            self.assertEqual(Foo.g, original_g)


    def test_patch_multiple_new_callable_failure(self):
        original_f = Foo.f
        original_g = Foo.g
        original_foo = Foo.foo

        def crasher():
            raise NameError('crasher')

        patcher = patch.object(Foo, 'f', 1)
        patcher.attribute_name = 'f'

        good = patch.object(Foo, 'g', 1)
        good.attribute_name = 'g'

        bad = patch.object(Foo, 'foo', new_callable=crasher)
        bad.attribute_name = 'foo'

        for additionals in [good, bad], [bad, good]:
            patcher.additional_patchers = additionals

            @patcher
            def func():
                pass

            self.assertRaises(NameError, func)
            self.assertEqual(Foo.f, original_f)
            self.assertEqual(Foo.g, original_g)
            self.assertEqual(Foo.foo, original_foo)


    def test_patch_multiple_string_subclasses(self):
        for base in (str, unicode):
            Foo = type('Foo', (base,), {'fish': 'tasty'})
            foo = Foo()
            @patch.multiple(foo, fish='nearly gone')
            def test():
                self.assertEqual(foo.fish, 'nearly gone')

            test()
            self.assertEqual(foo.fish, 'tasty')


    @patch('mock.patch.TEST_PREFIX', 'foo')
    def test_patch_test_prefix(self):
        class Foo(object):
            thing = 'original'

            def foo_one(self):
                return self.thing
            def foo_two(self):
                return self.thing
            def test_one(self):
                return self.thing
            def test_two(self):
                return self.thing

        Foo = patch.object(Foo, 'thing', 'changed')(Foo)

        foo = Foo()
        self.assertEqual(foo.foo_one(), 'changed')
        self.assertEqual(foo.foo_two(), 'changed')
        self.assertEqual(foo.test_one(), 'original')
        self.assertEqual(foo.test_two(), 'original')


    @patch('mock.patch.TEST_PREFIX', 'bar')
    def test_patch_dict_test_prefix(self):
        class Foo(object):
            def bar_one(self):
                return dict(the_dict)
            def bar_two(self):
                return dict(the_dict)
            def test_one(self):
                return dict(the_dict)
            def test_two(self):
                return dict(the_dict)

        the_dict = {'key': 'original'}
        Foo = patch.dict(the_dict, key='changed')(Foo)

        foo =Foo()
        self.assertEqual(foo.bar_one(), {'key': 'changed'})
        self.assertEqual(foo.bar_two(), {'key': 'changed'})
        self.assertEqual(foo.test_one(), {'key': 'original'})
        self.assertEqual(foo.test_two(), {'key': 'original'})


    def test_patch_with_spec_mock_repr(self):
        for arg in ('spec', 'autospec', 'spec_set'):
            p = patch('%s.SomeClass' % __name__, **{arg: True})
            m = p.start()
            try:
                self.assertIn(" name='SomeClass'", repr(m))
                self.assertIn(" name='SomeClass.class_attribute'",
                              repr(m.class_attribute))
                self.assertIn(" name='SomeClass()'", repr(m()))
                self.assertIn(" name='SomeClass().class_attribute'",
                              repr(m().class_attribute))
            finally:
                p.stop()


    def test_patch_nested_autospec_repr(self):
        p = patch('tests.support', autospec=True)
        m = p.start()
        try:
            self.assertIn(" name='support.SomeClass.wibble()'",
                          repr(m.SomeClass.wibble()))
            self.assertIn(" name='support.SomeClass().wibble()'",
                          repr(m.SomeClass().wibble()))
        finally:
            p.stop()


    def test_mock_calls_with_patch(self):
        for arg in ('spec', 'autospec', 'spec_set'):
            p = patch('%s.SomeClass' % __name__, **{arg: True})
            m = p.start()
            try:
                m.wibble()

                kalls = [call.wibble()]
                self.assertEqual(m.mock_calls, kalls)
                self.assertEqual(m.method_calls, kalls)
                self.assertEqual(m.wibble.mock_calls, [call()])

                result = m()
                kalls.append(call())
                self.assertEqual(m.mock_calls, kalls)

                result.wibble()
                kalls.append(call().wibble())
                self.assertEqual(m.mock_calls, kalls)

                self.assertEqual(result.mock_calls, [call.wibble()])
                self.assertEqual(result.wibble.mock_calls, [call()])
                self.assertEqual(result.method_calls, [call.wibble()])
            finally:
                p.stop()


    def test_patch_imports_lazily(self):
        sys.modules.pop('squizz', None)

        p1 = patch('squizz.squozz')
        self.assertRaises(ImportError, p1.start)

        squizz = Mock()
        squizz.squozz = 6
        sys.modules['squizz'] = squizz
        p1 = patch('squizz.squozz')
        squizz.squozz = 3
        p1.start()
        p1.stop()
        self.assertEqual(squizz.squozz, 3)


    def test_patch_propogrates_exc_on_exit(self):
        class holder:
            exc_info = None, None, None

        class custom_patch(_patch):
            def __exit__(self, etype=None, val=None, tb=None):
                _patch.__exit__(self, etype, val, tb)
                holder.exc_info = etype, val, tb
            stop = __exit__

        def with_custom_patch(target):
            getter, attribute = _get_target(target)
            return custom_patch(
                getter, attribute, DEFAULT, None, False, None,
                None, None, {}
            )

        @with_custom_patch('squizz.squozz')
        def test(mock):
            raise RuntimeError

        self.assertRaises(RuntimeError, test)
        self.assertIs(holder.exc_info[0], RuntimeError)
        self.assertIsNotNone(holder.exc_info[1],
                            'exception value not propgated')
        self.assertIsNotNone(holder.exc_info[2],
                            'exception traceback not propgated')


    def test_create_and_specs(self):
        for kwarg in ('spec', 'spec_set', 'autospec'):
            p = patch('%s.doesnotexist' % __name__, create=True,
                      **{kwarg: True})
            self.assertRaises(TypeError, p.start)
            self.assertRaises(NameError, lambda: doesnotexist)

            # check that spec with create is innocuous if the original exists
            p = patch(MODNAME, create=True, **{kwarg: True})
            p.start()
            p.stop()


    def test_multiple_specs(self):
        original = PTModule
        for kwarg in ('spec', 'spec_set'):
            p = patch(MODNAME, autospec=0, **{kwarg: 0})
            self.assertRaises(TypeError, p.start)
            self.assertIs(PTModule, original)

        for kwarg in ('spec', 'autospec'):
            p = patch(MODNAME, spec_set=0, **{kwarg: 0})
            self.assertRaises(TypeError, p.start)
            self.assertIs(PTModule, original)

        for kwarg in ('spec_set', 'autospec'):
            p = patch(MODNAME, spec=0, **{kwarg: 0})
            self.assertRaises(TypeError, p.start)
            self.assertIs(PTModule, original)


    def test_specs_false_instead_of_none(self):
        p = patch(MODNAME, spec=False, spec_set=False, autospec=False)
        mock = p.start()
        try:
            # no spec should have been set, so attribute access should not fail
            mock.does_not_exist
            mock.does_not_exist = 3
        finally:
            p.stop()


    def test_falsey_spec(self):
        for kwarg in ('spec', 'autospec', 'spec_set'):
            p = patch(MODNAME, **{kwarg: 0})
            m = p.start()
            try:
                self.assertRaises(AttributeError, getattr, m, 'doesnotexit')
            finally:
                p.stop()


    def test_spec_set_true(self):
        for kwarg in ('spec', 'autospec'):
            p = patch(MODNAME, spec_set=True, **{kwarg: True})
            m = p.start()
            try:
                self.assertRaises(AttributeError, setattr, m,
                                  'doesnotexist', 'something')
                self.assertRaises(AttributeError, getattr, m, 'doesnotexist')
            finally:
                p.stop()


    def test_callable_spec_as_list(self):
        spec = ('__call__',)
        p = patch(MODNAME, spec=spec)
        m = p.start()
        try:
            self.assertTrue(callable(m))
        finally:
            p.stop()


    def test_not_callable_spec_as_list(self):
        spec = ('foo', 'bar')
        p = patch(MODNAME, spec=spec)
        m = p.start()
        try:
            self.assertFalse(callable(m))
        finally:
            p.stop()


    def test_patch_stopall(self):
        unlink = os.unlink
        chdir = os.chdir
        path = os.path
        patch('os.unlink', something).start()
        patch('os.chdir', something_else).start()

        @patch('os.path')
        def patched(mock_path):
            patch.stopall()
            self.assertIs(os.path, mock_path)
            self.assertIs(os.unlink, unlink)
            self.assertIs(os.chdir, chdir)

        patched()
        self.assertIs(os.path, path)


    def test_wrapped_patch(self):
        decorated = patch('sys.modules')(function)
        self.assertIs(decorated.__wrapped__, function)


    def test_wrapped_patch_object(self):
        decorated = patch.object(sys, 'modules')(function)
        self.assertIs(decorated.__wrapped__, function)


    def test_wrapped_patch_dict(self):
        decorated = patch.dict('sys.modules')(function)
        self.assertIs(decorated.__wrapped__, function)


    def test_wrapped_patch_multiple(self):
        decorated = patch.multiple('sys', modules={})(function)
        self.assertIs(decorated.__wrapped__, function)


if __name__ == '__main__':
    unittest2.main()
