summaryrefslogtreecommitdiff
path: root/test.py
diff options
context:
space:
mode:
authorGustavo Niemeyer <gustavo@niemeyer.net>2007-10-29 00:13:18 -0200
committerGustavo Niemeyer <gustavo@niemeyer.net>2007-10-29 00:13:18 -0200
commitdddccbae4b89957a5664462b1ca953357d51d59e (patch)
treeff53d141c9f2af07e535bbfd08f5b97bf30c6086 /test.py
parent672b6a5b727c10a32c5274aee4e11a639f5ae27f (diff)
downloadmocker-dddccbae4b89957a5664462b1ca953357d51d59e.tar.gz
Moved it forward, most importantly implementing the patching feature.
Diffstat (limited to 'test.py')
-rwxr-xr-xtest.py1333
1 files changed, 1005 insertions, 328 deletions
diff --git a/test.py b/test.py
index f51edb9..d5fcd7b 100755
--- a/test.py
+++ b/test.py
@@ -1,6 +1,7 @@
#!/usr/bin/python
import unittest
import sys
+import os
import gc
from types import ModuleType
@@ -11,7 +12,8 @@ from mocker import (
run_counter_recorder, run_counter_removal_recorder, MockReturner,
mock_returner_recorder, FunctionRunner, Orderer, SpecChecker,
spec_checker_recorder, match_params, ANY, VARIOUS, SAME, CONTAINS,
- UnexpectedExprError, PathApplier, RECORD, REPLAY, RESTORE, ProxyInstaller)
+ ARGS, KWARGS, MatchError, PathExecuter, RECORD, REPLAY, RESTORE,
+ ProxyReplacer, Patcher, Undefined, PatchedMethod)
class CleanMocker(MockerBase):
@@ -24,7 +26,7 @@ class IntegrationTest(unittest.TestCase):
self.mocker = Mocker()
def test_count(self):
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
obj.x
self.mocker.count(2, 3)
@@ -38,7 +40,7 @@ class IntegrationTest(unittest.TestCase):
self.assertRaises(AssertionError, getattr, obj, "x")
def test_ordered(self):
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
with_manager = self.mocker.ordered()
with_manager.__enter__()
@@ -56,11 +58,11 @@ class IntegrationTest(unittest.TestCase):
obj.y
obj.z
- def test_spec(self):
+ def test_spec_and_type(self):
class C(object):
def m(self, a): pass
- obj = self.mocker.obj(C)
+ obj = self.mocker.mock(C)
obj.m(1)
obj.m(a=1)
@@ -73,6 +75,8 @@ class IntegrationTest(unittest.TestCase):
self.mocker.replay()
+ self.assertTrue(isinstance(obj, C))
+
obj.m(1)
obj.m(a=1)
obj.y()
@@ -82,14 +86,14 @@ class IntegrationTest(unittest.TestCase):
self.assertRaises(AssertionError, obj.z)
def test_result(self):
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
obj.x
self.mocker.result(42)
self.mocker.replay()
self.assertEquals(obj.x, 42)
def test_throw(self):
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
obj.x()
self.mocker.throw(ValueError)
self.mocker.replay()
@@ -100,7 +104,7 @@ class IntegrationTest(unittest.TestCase):
def func(arg):
calls.append(arg)
return 42
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
obj.x(24)
self.mocker.call(func)
self.mocker.replay()
@@ -112,7 +116,7 @@ class IntegrationTest(unittest.TestCase):
def func(arg):
calls.append(arg)
return arg
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
obj.x(24)
self.mocker.call(func)
self.mocker.result(42)
@@ -126,7 +130,7 @@ class IntegrationTest(unittest.TestCase):
return sum(args)
obj = self.mocker.proxy(C())
- expect(obj.multiply(2, 3)).result(6)
+ expect(obj.multiply(2, 3)).result(6).nospec()
expect(obj.sum(0, 0)).result(1)
expect(obj.sum(0, 0)).passthrough()
@@ -140,9 +144,9 @@ class IntegrationTest(unittest.TestCase):
self.assertEquals(obj.sum(0, 0), 0) # Passed through explicitly.
self.assertRaises(AssertionError, obj.sum, 0, 0) # Seen twice.
- def test_module_install_and_restore(self):
+ def test_replace_install_and_restore(self):
try:
- module = self.mocker.module("calendar")
+ module = self.mocker.replace("calendar")
import calendar
self.assertTrue(calendar is not module)
self.mocker.replay()
@@ -154,11 +158,11 @@ class IntegrationTest(unittest.TestCase):
finally:
self.mocker.restore()
- def test_module_os_path(self):
+ def test_replace_os_path_join(self):
try:
- path = self.mocker.module("os.path")
- expect(path.join(VARIOUS)).call(lambda *args: "-".join(args))
- expect(path.join("e", VARIOUS)).passthrough()
+ path = self.mocker.replace("os.path")
+ expect(path.join(ARGS)).call(lambda *args: "-".join(args))
+ expect(path.join("e", ARGS)).passthrough()
self.mocker.replay()
import os
self.assertEquals(os.path.join("a", "b", "c"), "a-b-c")
@@ -166,6 +170,18 @@ class IntegrationTest(unittest.TestCase):
finally:
self.mocker.restore()
+ def test_replace_os_path_isfile(self):
+ try:
+ path = self.mocker.replace("os.path")
+ expect(path.isfile("unexistent")).result(True)
+ expect(path.isfile(ANY)).passthrough().count(2)
+ self.mocker.replay()
+ import os
+ self.assertFalse(os.path.isfile("another-unexistent"))
+ self.assertTrue(os.path.isfile("unexistent"))
+ self.assertFalse(os.path.isfile("unexistent"))
+ finally:
+ self.mocker.restore()
class ExpectTest(unittest.TestCase):
@@ -173,13 +189,13 @@ class ExpectTest(unittest.TestCase):
self.mocker = CleanMocker()
def test_calling_mocker(self):
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
expect(obj.attr).result(123)
self.mocker.replay()
self.assertEquals(obj.attr, 123)
def test_chaining(self):
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
expect(obj.attr).result(123).result(42)
self.mocker.replay()
self.assertEquals(obj.attr, 42)
@@ -194,8 +210,8 @@ class MockerTest(unittest.TestCase):
def recorder(mocker, event):
self.recorded.append((mocker, event))
- self.action = Action(Path(Mock(self.mocker, name="mock")),
- "getattr", ("attr",), {})
+ self.action = Action("getattr", ("attr",), {},
+ Path(Mock(self.mocker, name="mock")))
self.path = self.action.path + self.action
def test_default_state(self):
@@ -233,18 +249,77 @@ class MockerTest(unittest.TestCase):
self.assertEquals(calls, [RESTORE])
def test_verify(self):
- calls = []
class MyEvent(object):
- def __init__(self, name):
- self.name = name
+ def __init__(self, id, failed):
+ self.id = id
+ self.failed = failed
def verify(self):
- calls.append(self.name)
- self.mocker.add_event(MyEvent("1"))
- self.mocker.add_event(MyEvent("2"))
+ if self.failed:
+ raise AssertionError("%d failed\n- Line 1\n- Line 2\n"
+ % self.id)
- self.mocker.verify()
+ self.mocker.add_event(MyEvent(1, True))
+ self.mocker.add_event(MyEvent(2, False))
+ self.mocker.add_event(MyEvent(3, True))
+
+ try:
+ self.mocker.verify()
+ except AssertionError, e:
+ message = os.linesep.join(["[Mocker] Unmet expectations:",
+ "",
+ "=> 1 failed",
+ " - Line 1",
+ " - Line 2",
+ "",
+ "=> 3 failed",
+ " - Line 1",
+ " - Line 2",
+ ""])
+ self.assertEquals(str(e), message)
+ else:
+ self.fail("AssertionError not raised")
+
+ def test_mocker_as_context_manager(self):
+ calls = []
+ throw = False
+ class MyEvent(Event):
+ def verify(self):
+ calls.append("verify")
+ if throw:
+ raise AssertionError("Some problem")
+ def set_state(self, state):
+ calls.append({REPLAY: "replay", RESTORE: "restore"}[state])
+
+ event = MyEvent()
+ self.mocker.add_event(event)
+
+ self.assertEquals(calls, [])
+
+ mocker = self.mocker.__enter__()
+ self.assertTrue(mocker is self.mocker)
+ self.assertEquals(calls, ["replay"])
+
+ # Verify without errors.
+ del calls[:]
+ result = self.mocker.__exit__(None, None, None)
+ self.assertEquals(result, False)
+ self.assertEquals(calls, ["restore", "verify"])
- self.assertEquals(calls, ["1", "2"])
+ throw = True
+
+ # Verify raising an error.
+ self.mocker.replay()
+ del calls[:]
+ self.assertRaises(AssertionError,
+ self.mocker.__exit__, None, None, None)
+ self.assertEquals(calls, ["restore", "verify"])
+
+ # An exception happened in the 'with' block. Verify won't raise.
+ self.mocker.replay()
+ del calls[:]
+ result = self.mocker.__exit__(AssertionError, None, None)
+ self.assertEquals(result, False)
+ self.assertEquals(calls, ["restore"])
def test_add_recorder_on_instance(self):
obj1 = object()
@@ -305,72 +380,136 @@ class MockerTest(unittest.TestCase):
MyMocker.remove_recorder(obj1)
self.assertEquals(MyMocker.get_recorders(), [obj2])
- def test_obj(self):
- self.mocker = CleanMocker()
- obj = self.mocker.obj()
- self.assertEquals(type(obj), Mock)
+ def test_mock_with_name(self):
+ mock = self.mocker.mock(name="name")
+ self.assertEquals(mock.__mocker_name__, "name")
- def test_obj_with_spec(self):
+ def test_mock_with_spec(self):
class C(object): pass
- self.mocker = CleanMocker()
- obj = self.mocker.obj(C)
- self.assertEquals(obj.__mocker_spec__, C)
+ mock = self.mocker.mock(spec=C)
+ self.assertEquals(mock.__mocker_spec__, C)
+
+ def test_mock_with_type(self):
+ class C(object): pass
+ mock = self.mocker.mock(type=C)
+ self.assertEquals(mock.__mocker_type__, C)
+
+ def test_mock_with_spec_and_type(self):
+ class C(object): pass
+ mock = self.mocker.mock(C)
+ self.assertEquals(mock.__mocker_spec__, C)
+ self.assertEquals(mock.__mocker_type__, C)
def test_proxy(self):
original = object()
- self.mocker = CleanMocker()
- obj = self.mocker.proxy(original)
- self.assertEquals(type(obj), Mock)
- self.assertEquals(obj.__mocker_object__, original)
+ mock = self.mocker.proxy(original)
+ self.assertEquals(type(mock), Mock)
+ self.assertEquals(mock.__mocker_object__, original)
+ self.assertEquals(mock.__mocker_path__.root_object, original)
def test_proxy_with_spec(self):
original = object()
class C(object): pass
- self.mocker = CleanMocker()
- obj = self.mocker.proxy(original, C)
- self.assertEquals(obj.__mocker_object__, original)
- self.assertEquals(obj.__mocker_spec__, C)
+ mock = self.mocker.proxy(original, C)
+ self.assertEquals(mock.__mocker_object__, original)
+ self.assertEquals(mock.__mocker_spec__, C)
+
+ def test_proxy_with_type(self):
+ original = object()
+ class C(object): pass
+ mock = self.mocker.proxy(original, type=C)
+ self.assertEquals(mock.__mocker_type__, C)
+
+ def test_proxy_spec_defaults_to_the_object_itself(self):
+ original = object()
+ mock = self.mocker.proxy(original)
+ self.assertEquals(mock.__mocker_spec__, original)
+
+ def test_proxy_type_defaults_to_the_object_type(self):
+ original = object()
+ mock = self.mocker.proxy(original)
+ self.assertEquals(mock.__mocker_type__, object)
+
+ def test_proxy_with_spec_and_type_none(self):
+ original = object()
+ mock = self.mocker.proxy(original, spec=None, type=None)
+ self.assertEquals(mock.__mocker_spec__, None)
+ self.assertEquals(mock.__mocker_type__, None)
def test_proxy_with_passthrough_false(self):
original = object()
class C(object): pass
- self.mocker = CleanMocker()
- obj = self.mocker.proxy(original, C, passthrough=False)
- self.assertEquals(obj.__mocker_object__, original)
- self.assertEquals(obj.__mocker_spec__, C)
- self.assertEquals(obj.__mocker_passthrough__, False)
+ mock = self.mocker.proxy(original, C, passthrough=False)
+ self.assertEquals(mock.__mocker_object__, original)
+ self.assertEquals(mock.__mocker_spec__, C)
+ self.assertEquals(mock.__mocker_passthrough__, False)
- def test_proxy_install(self):
+ def test_replace(self):
from os import path
obj = object()
- proxy = self.mocker.proxy(obj, install=True)
+ proxy = self.mocker.replace(obj, spec=object, name="obj",
+ passthrough=False)
self.assertEquals(type(proxy), Mock)
self.assertEquals(type(proxy.__mocker_object__), object)
self.assertEquals(proxy.__mocker_object__, obj)
+ self.assertEquals(proxy.__mocker_spec__, object)
+ self.assertEquals(proxy.__mocker_name__, "obj")
(event,) = self.mocker.get_events()
(task,) = event.get_tasks()
- self.assertEquals(type(task), ProxyInstaller)
+ self.assertEquals(type(task), ProxyReplacer)
self.assertTrue(task.mock is proxy)
self.assertTrue(task.mock.__mocker_object__ is obj)
self.assertTrue(proxy is not obj)
- def test_module(self):
+ def test_replace_with_submodule_string(self):
from os import path
- module = self.mocker.module("os.path")
+ module = self.mocker.replace("os.path")
self.assertEquals(type(module), Mock)
self.assertEquals(type(module.__mocker_object__), ModuleType)
self.assertEquals(module.__mocker_name__, "os.path")
self.assertEquals(module.__mocker_object__, path)
(event,) = self.mocker.get_events()
(task,) = event.get_tasks()
- self.assertEquals(type(task), ProxyInstaller)
+ self.assertEquals(type(task), ProxyReplacer)
self.assertTrue(task.mock is module)
self.assertTrue(task.mock.__mocker_object__ is path)
self.assertTrue(module is not path)
- def test_module_with_passthrough_false(self):
- module = self.mocker.module("calendar", passthrough=False)
- self.assertEquals(module.__mocker_passthrough__, False)
+ def test_replace_with_module_function_string(self):
+ mock = self.mocker.replace("os.path.join.func_name")
+ self.assertEquals(mock.__mocker_object__, "join")
+
+ def test_replace_with_string_and_name(self):
+ module = self.mocker.replace("os.path", name="mock")
+ self.assertEquals(module.__mocker_name__, "mock")
+
+ def test_replace_with_type(self):
+ original = object()
+ class C(object): pass
+ mock = self.mocker.replace(original, type=C)
+ self.assertEquals(mock.__mocker_type__, C)
+
+ def test_replace_spec_defaults_to_the_object_itself(self):
+ original = object()
+ mock = self.mocker.replace(original)
+ self.assertEquals(mock.__mocker_spec__, original)
+
+ def test_replace_type_defaults_to_the_object_type(self):
+ original = object()
+ mock = self.mocker.replace(original)
+ self.assertEquals(mock.__mocker_type__, object)
+
+ def test_replace_with_spec_and_type_none(self):
+ original = object()
+ mock = self.mocker.replace(original, spec=None, type=None)
+ self.assertEquals(mock.__mocker_spec__, None)
+ self.assertEquals(mock.__mocker_type__, None)
+
+ def test_replace_with_passthrough_false(self):
+ original = object()
+ class C(object): pass
+ mock = self.mocker.replace(original, passthrough=False)
+ self.assertEquals(mock.__mocker_passthrough__, False)
def test_add_and_get_event(self):
self.mocker.add_event(41)
@@ -378,31 +517,32 @@ class MockerTest(unittest.TestCase):
self.assertEquals(self.mocker.get_events(), [41, 42])
def test_recording(self):
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
obj.attr()
self.assertEquals(len(self.recorded), 2)
- action1 = Action(None, "getattr", ("attr",), {})
- action2 = Action(None, "call", (), {})
+ action1 = Action("getattr", ("attr",), {})
+ action2 = Action("call", (), {})
mocker1, event1 = self.recorded[0]
self.assertEquals(mocker1, self.mocker)
self.assertEquals(type(event1), Event)
- self.assertTrue(event1.path.matches(Path(obj, [action1])))
+ self.assertTrue(event1.path.matches(Path(obj, None, [action1])))
mocker2, event2 = self.recorded[1]
self.assertEquals(mocker2, self.mocker)
self.assertEquals(type(event2), Event)
- self.assertTrue(event2.path.matches(Path(obj, [action1, action2])))
+ self.assertTrue(event2.path.matches(Path(obj, None,
+ [action1, action2])))
self.assertEquals(self.mocker.get_events(), [event1, event2])
def test_recording_result_path(self):
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
result = obj.attr()
- path = Path(obj, [Action(None, "getattr", ("attr",), {}),
- Action(None, "call", (), {})])
+ path = Path(obj, None, [Action("getattr", ("attr",), {}),
+ Action("call", (), {})])
self.assertTrue(result.__mocker_path__.matches(path))
def test_replaying_no_events(self):
@@ -456,7 +596,7 @@ class MockerTest(unittest.TestCase):
def verify(self):
if not self.raised:
self.raised = True
- raise AssertionError()
+ raise AssertionError("An error")
def run(self, path):
return "result2"
event1 = self.mocker.add_event(Event())
@@ -515,10 +655,10 @@ class MockerTest(unittest.TestCase):
self.assertEquals(task.max, 4)
def test_order(self):
- mock1 = self.mocker.obj()
- mock2 = self.mocker.obj()
- mock3 = self.mocker.obj()
- mock4 = self.mocker.obj()
+ mock1 = self.mocker.mock()
+ mock2 = self.mocker.mock()
+ mock3 = self.mocker.mock()
+ mock4 = self.mocker.mock()
result1 = mock1.attr1(1)
result2 = mock2.attr2(2)
result3 = mock3.attr3(3)
@@ -560,9 +700,9 @@ class MockerTest(unittest.TestCase):
self.assertEquals(other_task_, other_task)
def test_after(self):
- mock1 = self.mocker.obj()
- mock2 = self.mocker.obj()
- mock3 = self.mocker.obj()
+ mock1 = self.mocker.mock()
+ mock2 = self.mocker.mock()
+ mock3 = self.mocker.mock()
result1 = mock1.attr1(1)
result2 = mock2.attr2(2)
result3 = mock3.attr3(3)
@@ -596,9 +736,9 @@ class MockerTest(unittest.TestCase):
self.assertEquals(other_task_, other_task)
def test_before(self):
- mock1 = self.mocker.obj()
- mock2 = self.mocker.obj()
- mock3 = self.mocker.obj()
+ mock1 = self.mocker.mock()
+ mock2 = self.mocker.mock()
+ mock3 = self.mocker.mock()
result1 = mock1.attr1(1)
result2 = mock2.attr2(2)
result3 = mock3.attr3(3)
@@ -638,7 +778,7 @@ class MockerTest(unittest.TestCase):
self.mocker.ordered()
self.assertEquals(self.mocker.is_ordering(), True)
- def test_ordered_enter_exit(self):
+ def test_ordered_context_manager(self):
with_manager = self.mocker.ordered()
self.assertEquals(self.mocker.is_ordering(), True)
with_manager.__enter__()
@@ -652,7 +792,7 @@ class MockerTest(unittest.TestCase):
self.assertEquals(self.mocker.is_ordering(), False)
def test_ordered_events(self):
- mock = self.mocker.obj()
+ mock = self.mocker.mock()
# Ensure that the state is correctly reset between
# different ordered blocks.
@@ -691,26 +831,39 @@ class MockerTest(unittest.TestCase):
self.assertEquals(event2.get_tasks(), [task2, task4])
def test_passthrough(self):
- obj = self.mocker.proxy(object())
- event1 = self.mocker.add_event(Event(Path(obj)))
- event2 = self.mocker.add_event(Event(Path(obj)))
+ obj = object()
+ mock = self.mocker.proxy(obj)
+ event1 = self.mocker.add_event(Event(Path(mock, obj)))
+ event2 = self.mocker.add_event(Event(Path(mock, obj)))
self.mocker.passthrough()
self.assertEquals(event1.get_tasks(), [])
(task,) = event2.get_tasks()
- self.assertEquals(type(task), PathApplier)
+ self.assertEquals(type(task), PathExecuter)
def test_passthrough_fails_on_unproxied(self):
- obj = self.mocker.obj()
- event1 = self.mocker.add_event(Event(Path(obj)))
- event2 = self.mocker.add_event(Event(Path(obj)))
+ mock = self.mocker.mock()
+ event1 = self.mocker.add_event(Event(Path(mock)))
+ event2 = self.mocker.add_event(Event(Path(mock)))
self.assertRaises(TypeError, self.mocker.passthrough)
def test_on(self):
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
self.mocker.on(obj.attr).result(123)
self.mocker.replay()
self.assertEquals(obj.attr, 123)
+ def test_patch(self):
+ class C(object): pass
+ mock = self.mocker.patch(C)
+ self.assertEquals(type(C.__mocker_mock__), Mock)
+ self.assertTrue(C.__mocker_mock__ is mock)
+ self.assertTrue(mock.__mocker_object__ is C)
+ self.assertEquals(type(mock.__mocker_patcher__), Patcher)
+ self.assertEquals(mock.__mocker_passthrough__, True)
+ (event,) = self.mocker.get_events()
+ (task,) = event.get_tasks()
+ self.assertTrue(task is mock.__mocker_patcher__)
+
class ActionTest(unittest.TestCase):
@@ -720,32 +873,77 @@ class ActionTest(unittest.TestCase):
def test_create(self):
objects = [object() for i in range(4)]
action = Action(*objects)
- self.assertEquals(action.path, objects[0])
- self.assertEquals(action.kind, objects[1])
- self.assertEquals(action.args, objects[2])
- self.assertEquals(action.kwargs, objects[3])
+ self.assertEquals(action.kind, objects[0])
+ self.assertEquals(action.args, objects[1])
+ self.assertEquals(action.kwargs, objects[2])
+ self.assertEquals(action.path, objects[3])
- def test_apply_getattr(self):
+ def test_execute_getattr(self):
class C(object):
pass
obj = C()
obj.x = C()
- action = Action(None, "getattr", ("x",), {})
- self.assertEquals(action.apply(obj), obj.x)
+ action = Action("getattr", ("x",), {})
+ self.assertEquals(action.execute(obj), obj.x)
- def test_apply_call(self):
+ def test_execute_call(self):
obj = lambda a, b: a+b
- action = Action(None, "call", (1,), {"b": 2})
- self.assertEquals(action.apply(obj), 3)
+ action = Action("call", (1,), {"b": 2})
+ self.assertEquals(action.execute(obj), 3)
- def test_apply_caching(self):
+ def test_execute_caching(self):
values = iter(range(10))
obj = lambda: values.next()
- action = Action(None, "call", (), {})
- self.assertEquals(action.apply(obj), 0)
- self.assertEquals(action.apply(obj), 0)
+ action = Action("call", (), {})
+ self.assertEquals(action.execute(obj), 0)
+ self.assertEquals(action.execute(obj), 0)
obj = lambda: values.next()
- self.assertEquals(action.apply(obj), 1)
+ self.assertEquals(action.execute(obj), 1)
+
+ def test_equals(self):
+ obj1 = object()
+ obj2 = object()
+
+ self.assertEquals(Action("kind", (), {}, obj1),
+ Action("kind", (), {}, obj2))
+ self.assertNotEquals(Action("kind", (), {}, obj1),
+ Action("dnik", (), {}, obj2))
+ self.assertNotEquals(Action("kind", (), {}, obj1),
+ Action("kind", (1,), {}, obj2))
+ self.assertNotEquals(Action("kind", (), {}, obj1),
+ Action("kind", (), {"a": 1}, obj2))
+ self.assertNotEquals(Action("kind", (ANY,), {}, obj1),
+ Action("kind", (1,), {}, obj2))
+ self.assertEquals(Action("kind", (CONTAINS(1),), {}, obj1),
+ Action("kind", (CONTAINS(1),), {}, obj2))
+
+ def test_matches(self):
+ obj1 = object()
+ obj2 = object()
+
+ action1 = Action("kind", (), {}, obj1)
+ action2 = Action("kind", (), {}, obj2)
+ self.assertTrue(action1.matches(action2))
+
+ action1 = Action("kind", (), {}, obj1)
+ action2 = Action("dnik", (), {}, obj2)
+ self.assertFalse(action1.matches(action2))
+
+ action1 = Action("kind", (), {}, obj1)
+ action2 = Action("kind", (1,), {}, obj2)
+ self.assertFalse(action1.matches(action2))
+
+ action1 = Action("kind", (), {}, obj1)
+ action2 = Action("kind", (), {"a": 1}, obj2)
+ self.assertFalse(action1.matches(action2))
+
+ action1 = Action("kind", (ARGS,), {}, obj1)
+ action2 = Action("kind", (), {}, obj2)
+ self.assertTrue(action1.matches(action2))
+
+ action1 = Action("kind", (ARGS,), {"a": 1}, obj1)
+ action2 = Action("kind", (), {}, obj2)
+ self.assertFalse(action1.matches(action2))
class PathTest(unittest.TestCase):
@@ -757,31 +955,41 @@ class PathTest(unittest.TestCase):
pass
self.mocker = StubMocker()
self.mock = Mock(self.mocker, name="obj")
+ self.object = object()
def test_create(self):
mock = object()
path = Path(mock)
self.assertEquals(path.root_mock, mock)
+ self.assertEquals(path.root_object, None)
self.assertEquals(path.actions, ())
+ def test_create_with_object(self):
+ mock = object()
+ path = Path(mock, self.object)
+ self.assertEquals(path.root_mock, mock)
+ self.assertEquals(path.root_object, self.object)
+
def test_create_with_actions(self):
mock = object()
- path = Path(mock, [1,2,3])
+ path = Path(mock, self.object, [1,2,3])
self.assertEquals(path.root_mock, mock)
+ self.assertEquals(path.root_object, self.object)
self.assertEquals(path.actions, (1,2,3))
def test_add(self):
mock = object()
- path = Path(mock, [1,2,3])
+ path = Path(mock, self.object, [1,2,3])
result = path + 4
self.assertTrue(result is not path)
self.assertEquals(result.root_mock, mock)
+ self.assertEquals(result.root_object, self.object)
self.assertEquals(result.actions, (1,2,3,4))
def test_parent_path(self):
path1 = Path(self.mock)
- path2 = path1 + Action(path1, "getattr", ("attr",), {})
- path3 = path2 + Action(path2, "getattr", ("attr",), {})
+ path2 = path1 + Action("getattr", ("attr",), {}, path1)
+ path3 = path2 + Action("getattr", ("attr",), {}, path2)
self.assertEquals(path1.parent_path, None)
self.assertEquals(path2.parent_path, path1)
@@ -789,86 +997,97 @@ class PathTest(unittest.TestCase):
def test_equals(self):
mock = object()
+ obj = object()
obj1 = object()
obj2 = object()
# Not the *same* mock.
- path1 = Path([], [])
- path2 = Path([], [])
+ path1 = Path([], obj, [])
+ path2 = Path([], obj, [])
+ self.assertNotEquals(path1, path2)
+
+ # Not the *same* object.
+ path1 = Path(mock, [], [])
+ path2 = Path(mock, [], [])
self.assertNotEquals(path1, path2)
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(mock, [Action(obj2, "kind", (), {})])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(mock, obj, [Action("kind", (), {}, obj2)])
self.assertEquals(path1, path2)
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(mock, [Action(obj2, "dnik", (), {})])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(mock, obj, [Action("dnik", (), {}, obj2)])
self.assertNotEquals(path1, path2)
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(object(), [Action(obj2, "kind", (), {})])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(object(), obj, [Action("kind", (), {}, obj2)])
self.assertNotEquals(path1, path2)
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(mock, [Action(obj2, "kind", (1,), {})])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(mock, obj, [Action("kind", (1,), {}, obj2)])
self.assertNotEquals(path1, path2)
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(mock, [Action(obj2, "kind", (), {"a": 1})])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(mock, obj, [Action("kind", (), {"a": 1}, obj2)])
self.assertNotEquals(path1, path2)
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(mock, [])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(mock, obj, [])
self.assertNotEquals(path1, path2)
- path1 = Path(mock, [Action(obj1, "kind", (ANY,), {})])
- path2 = Path(mock, [Action(obj2, "kind", (1), {})])
+ path1 = Path(mock, obj, [Action("kind", (ANY,), {}, obj1)])
+ path2 = Path(mock, obj, [Action("kind", (1,), {}, obj2)])
self.assertNotEquals(path1, path2)
- path1 = Path(mock, [Action(obj1, "kind", (CONTAINS(1),), {})])
- path2 = Path(mock, [Action(obj2, "kind", (CONTAINS(1),), {})])
+ path1 = Path(mock, obj, [Action("kind", (CONTAINS(1),), {}, obj1)])
+ path2 = Path(mock, obj, [Action("kind", (CONTAINS(1),), {}, obj2)])
self.assertEquals(path1, path2)
def test_matches(self):
+ obj = object()
mock = object()
obj1 = object()
obj2 = object()
# Not the *same* mock.
- path1 = Path([], [])
- path2 = Path([], [])
+ path1 = Path([], obj, [])
+ path2 = Path([], obj, [])
self.assertFalse(path1.matches(path2))
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(mock, [Action(obj2, "kind", (), {})])
+ path1 = Path(mock, obj1, [])
+ path2 = Path(mock, obj2, [])
+ self.assertTrue(path1.matches(path2))
+
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(mock, obj, [Action("kind", (), {}, obj2)])
self.assertTrue(path1.matches(path2))
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(mock, [Action(obj2, "dnik", (), {})])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(mock, obj, [Action("dnik", (), {}, obj2)])
self.assertFalse(path1.matches(path2))
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(object(), [Action(obj2, "kind", (), {})])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(object(), [Action("kind", (), {}, obj2)])
self.assertFalse(path1.matches(path2))
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(mock, [Action(obj2, "kind", (1,), {})])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(mock, obj, [Action("kind", (1,), {}, obj2)])
self.assertFalse(path1.matches(path2))
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(mock, [Action(obj2, "kind", (), {"a": 1})])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(mock, obj, [Action("kind", (), {"a": 1}, obj2)])
self.assertFalse(path1.matches(path2))
- path1 = Path(mock, [Action(obj1, "kind", (), {})])
- path2 = Path(mock, [])
+ path1 = Path(mock, obj, [Action("kind", (), {}, obj1)])
+ path2 = Path(mock, obj, [])
self.assertFalse(path1.matches(path2))
- path1 = Path(mock, [Action(obj1, "kind", (VARIOUS,), {})])
- path2 = Path(mock, [Action(obj2, "kind", (), {})])
+ path1 = Path(mock, obj, [Action("kind", (ARGS,), {}, obj1)])
+ path2 = Path(mock, obj, [Action("kind", (), {}, obj2)])
self.assertTrue(path1.matches(path2))
- path1 = Path(mock, [Action(obj1, "kind", (VARIOUS,), {"a": 1})])
- path2 = Path(mock, [Action(obj2, "kind", (), {})])
+ path1 = Path(mock, obj, [Action("kind", (ARGS,), {"a": 1}, obj1)])
+ path2 = Path(mock, obj, [Action("kind", (), {}, obj2)])
self.assertFalse(path1.matches(path2))
def test_str(self):
@@ -887,40 +1106,40 @@ class PathTest(unittest.TestCase):
self.assertEquals(str(path), "named_mock")
def test_str_getattr(self):
- path = Path(self.mock, [Action(None, "getattr", ("attr",), {})])
+ path = Path(self.mock, None, [Action("getattr", ("attr",), {})])
self.assertEquals(str(path), "obj.attr")
- path += Action(None, "getattr", ("x",), {})
+ path += Action("getattr", ("x",), {})
self.assertEquals(str(path), "obj.attr.x")
def test_str_call(self):
- path = Path(self.mock, [Action(None, "call", (), {})])
+ path = Path(self.mock, None, [Action("call", (), {})])
self.assertEquals(str(path), "obj()")
- path = Path(self.mock,
- [Action(None, "call", (1, "2"), {"a":3,"b":"4"})])
+ path = Path(self.mock, None,
+ [Action("call", (1, "2"), {"a": 3, "b": "4"})])
self.assertEquals(str(path), "obj(1, '2', a=3, b='4')")
def test_str_getattr_call(self):
- path = Path(self.mock, [Action(None, "getattr", ("x",), {}),
- Action(None, "getattr", ("y",), {}),
- Action(None, "call", ("z",), {})])
+ path = Path(self.mock, None, [Action("getattr", ("x",), {}),
+ Action("getattr", ("y",), {}),
+ Action("call", ("z",), {})])
self.assertEquals(str(path), "obj.x.y('z')")
def test_str_raise_on_unknown(self):
- path = Path(self.mock, [Action(None, "unknown", (), {})])
+ path = Path(self.mock, None, [Action("unknown", (), {})])
self.assertRaises(RuntimeError, str, path)
- def test_apply(self):
+ def test_execute(self):
class C(object):
pass
obj = C()
obj.x = C()
obj.x.y = lambda a, b: a+b
- path = Path(self.mock, [Action(None, "getattr", ("x",), {}),
- Action(None, "getattr", ("y",), {}),
- Action(None, "call", (1,), {"b": 2})])
- self.assertEquals(path.apply(obj), 3)
+ path = Path(self.mock, None, [Action("getattr", ("x",), {}),
+ Action("getattr", ("y",), {}),
+ Action("call", (1,), {"b": 2})])
+ self.assertEquals(path.execute(obj), 3)
class MatchParamsTest(unittest.TestCase):
@@ -935,17 +1154,26 @@ class MatchParamsTest(unittest.TestCase):
self.assertEquals(repr(ANY), "ANY")
def test_any_equals(self):
- self.assertEquals(ANY, 1)
- self.assertEquals(ANY, 42)
self.assertEquals(ANY, ANY)
+ self.assertNotEquals(ANY, ARGS)
+ self.assertNotEquals(ANY, object())
+
+ def test_any_matches(self):
+ self.assertTrue(ANY.matches(1))
+ self.assertTrue(ANY.matches(42))
+ self.assertTrue(ANY.matches(object()))
def test_various_repr(self):
self.assertEquals(repr(VARIOUS), "VARIOUS")
def test_various_equals(self):
self.assertEquals(VARIOUS, VARIOUS)
- self.assertNotEquals(VARIOUS, ANY)
- self.assertNotEquals(ANY, VARIOUS)
+ self.assertNotEquals(VARIOUS, object())
+
+ def test_various_matches(self):
+ self.assertTrue(VARIOUS.matches(1))
+ self.assertTrue(VARIOUS.matches(42))
+ self.assertTrue(VARIOUS.matches(object()))
def test_same_repr(self):
self.assertEquals(repr(SAME("obj")), "SAME('obj')")
@@ -953,96 +1181,126 @@ class MatchParamsTest(unittest.TestCase):
def test_same_equals(self):
l1 = []
l2 = []
- self.assertEquals(SAME(l1), l1)
self.assertNotEquals(SAME(l1), l2)
-
self.assertEquals(SAME(l1), SAME(l1))
self.assertNotEquals(SAME(l1), SAME(l2))
- self.assertNotEquals(ANY, SAME(l1))
- self.assertNotEquals(SAME(l1), ANY)
+ def test_same_matches(self):
+ l1 = []
+ l2 = []
+ self.assertTrue(SAME(l1).matches(l1))
+ self.assertFalse(SAME(l1).matches(l2))
+ self.assertFalse(SAME(l1).matches(ANY))
def test_contains_repr(self):
self.assertEquals(repr(CONTAINS("obj")), "CONTAINS('obj')")
def test_contains_equals(self):
- self.assertEquals(CONTAINS(1), [1])
- self.assertNotEquals(CONTAINS([1]), [1])
-
self.assertEquals(CONTAINS([1]), CONTAINS([1]))
self.assertNotEquals(CONTAINS(1), CONTAINS([1]))
- self.assertNotEquals(ANY, CONTAINS(1))
- self.assertNotEquals(CONTAINS(1), ANY)
+ def test_contains_matches(self):
+ self.assertTrue(CONTAINS(1).matches([1]))
+ self.assertFalse(CONTAINS([1]).matches([1]))
+ self.assertFalse(CONTAINS(1).matches(object()))
+
+ def test_contains_matches_with_contains(self):
+ """Can't be iterated, but has contains hook."""
+ class C(object):
+ def __contains__(self, value):
+ return True
+ self.assertTrue(CONTAINS(1).matches(C()))
def test_normal(self):
- self.assertTrue(match_params((), {}, (), {}))
- self.assertTrue(match_params((1, 2), {"a": 3}, (1, 2), {"a": 3}))
- self.assertFalse(match_params((1,), {}, (), {}))
- self.assertFalse(match_params((), {}, (1,), {}))
- self.assertFalse(match_params((1, 2), {"a": 3}, (1, 2), {"a": 4}))
- self.assertFalse(match_params((1, 2), {"a": 3}, (1, 3), {"a": 3}))
+ self.true((), {}, (), {})
+ self.true((1, 2), {"a": 3}, (1, 2), {"a": 3})
+ self.false((1,), {}, (), {})
+ self.false((), {}, (1,), {})
+ self.false((1, 2), {"a": 3}, (1, 2), {"a": 4})
+ self.false((1, 2), {"a": 3}, (1, 3), {"a": 3})
def test_any(self):
- self.assertTrue(match_params((1, 2), {"a": ANY}, (1, 2), {"a": 4}))
- self.assertTrue(match_params((1, ANY), {"a": 3}, (1, 3), {"a": 3}))
- self.assertFalse(match_params((ANY,), {}, (), {}))
-
- def test_various_alone(self):
- self.true((VARIOUS,), {}, (), {})
- self.true((VARIOUS,), {}, (1, 2), {})
- self.true((VARIOUS,), {}, (1, 2), {"a": 2})
- self.true((VARIOUS,), {}, (), {"a": 2})
- self.true((VARIOUS,), {"a": 1}, (), {"a": 1})
- self.true((VARIOUS,), {"a": 1}, (1, 2), {"a": 1})
- self.true((VARIOUS,), {"a": 1}, (), {"a": 1, "b": 2})
- self.true((VARIOUS,), {"a": 1}, (1, 2), {"a": 1, "b": 2})
- self.false((VARIOUS,), {"a": 1}, (), {})
-
- def test_various_at_start(self):
- self.true((VARIOUS, 3, 4), {}, (3, 4), {})
- self.true((VARIOUS, 3, 4), {}, (1, 2, 3, 4), {})
- self.true((VARIOUS, 3, 4), {"a": 1}, (3, 4), {"a": 1})
- self.true((VARIOUS, 3, 4), {"a": 1}, (1, 2, 3, 4), {"a": 1, "b": 2})
- self.false((VARIOUS, 3, 4), {}, (), {})
- self.false((VARIOUS, 3, 4), {}, (3, 5), {})
- self.false((VARIOUS, 3, 4), {}, (5, 5), {})
- self.false((VARIOUS, 3, 4), {"a": 1}, (), {})
- self.false((VARIOUS, 3, 4), {"a": 1}, (3, 4), {})
- self.false((VARIOUS, 3, 4), {"a": 1}, (3, 4), {"b": 2})
-
- def test_various_at_end(self):
- self.true((1, 2, VARIOUS), {}, (1, 2), {})
- self.true((1, 2, VARIOUS), {}, (1, 2, 3, 4), {})
- self.true((1, 2, VARIOUS), {"a": 1}, (1, 2), {"a": 1})
- self.true((1, 2, VARIOUS), {"a": 1}, (1, 2, 3, 4), {"a": 1, "b": 2})
- self.false((1, 2, VARIOUS), {}, (), {})
- self.false((1, 2, VARIOUS), {}, (1, 3), {})
- self.false((1, 2, VARIOUS), {}, (3, 3), {})
- self.false((1, 2, VARIOUS), {"a": 1}, (), {})
- self.false((1, 2, VARIOUS), {"a": 1}, (1, 2), {})
- self.false((1, 2, VARIOUS), {"a": 1}, (1, 2), {"b": 2})
-
- def test_various_at_middle(self):
- self.true((1, VARIOUS, 4), {}, (1, 4), {})
- self.true((1, VARIOUS, 4), {}, (1, 2, 3, 4), {})
- self.true((1, VARIOUS, 4), {"a": 1}, (1, 4), {"a": 1})
- self.true((1, VARIOUS, 4), {"a": 1}, (1, 2, 3, 4), {"a": 1, "b": 2})
- self.false((1, VARIOUS, 4), {}, (), {})
- self.false((1, VARIOUS, 4), {}, (1, 5), {})
- self.false((1, VARIOUS, 4), {}, (5, 5), {})
- self.false((1, VARIOUS, 4), {"a": 1}, (), {})
- self.false((1, VARIOUS, 4), {"a": 1}, (1, 4), {})
- self.false((1, VARIOUS, 4), {"a": 1}, (1, 4), {"b": 2})
-
- def test_various_multiple(self):
- self.true((VARIOUS, 3, VARIOUS, 6, VARIOUS), {},
+ self.true((1, 2), {"a": ANY}, (1, 2), {"a": 4})
+ self.true((1, ANY), {"a": 3}, (1, 3), {"a": 3})
+ self.false((ANY,), {}, (), {})
+
+ def test_args_alone(self):
+ self.true((ARGS,), {}, (), {})
+ self.true((ARGS,), {}, (1, 2), {})
+ self.false((ARGS,), {}, (1, 2), {"a": 2})
+ self.false((ARGS,), {}, (), {"a": 2})
+ self.true((ARGS,), {"a": 1}, (), {"a": 1})
+ self.true((ARGS,), {"a": 1}, (1, 2), {"a": 1})
+ self.false((ARGS,), {"a": 1}, (), {"a": 1, "b": 2})
+ self.false((ARGS,), {"a": 1}, (1, 2), {"a": 1, "b": 2})
+ self.false((ARGS,), {"a": 1}, (), {})
+
+ def test_kwargs_alone(self):
+ self.true((KWARGS,), {}, (), {})
+ self.false((KWARGS,), {}, (1, 2), {})
+ self.false((KWARGS,), {}, (1, 2), {"a": 2})
+ self.true((KWARGS,), {}, (), {"a": 2})
+ self.true((KWARGS,), {"a": 1}, (), {"a": 1})
+ self.false((KWARGS,), {"a": 1}, (1, 2), {"a": 1})
+ self.true((KWARGS,), {"a": 1}, (), {"a": 1, "b": 2})
+ self.false((KWARGS,), {"a": 1}, (1, 2), {"a": 1, "b": 2})
+ self.false((KWARGS,), {"a": 1}, (), {})
+
+ def test_args_kwargs(self):
+ self.true((ARGS, KWARGS), {}, (), {})
+ self.true((ARGS, KWARGS), {}, (1, 2), {})
+ self.true((ARGS, KWARGS), {}, (1, 2), {"a": 2})
+ self.true((ARGS, KWARGS), {}, (), {"a": 2})
+ self.true((ARGS, KWARGS), {"a": 1}, (), {"a": 1})
+ self.true((ARGS, KWARGS), {"a": 1}, (1, 2), {"a": 1})
+ self.true((ARGS, KWARGS), {"a": 1}, (), {"a": 1, "b": 2})
+ self.true((ARGS, KWARGS), {"a": 1}, (1, 2), {"a": 1, "b": 2})
+ self.false((ARGS, KWARGS), {"a": 1}, (), {})
+
+ def test_args_at_start(self):
+ self.true((ARGS, 3, 4), {}, (3, 4), {})
+ self.true((ARGS, 3, 4), {}, (1, 2, 3, 4), {})
+ self.true((ARGS, 3, 4), {"a": 1}, (3, 4), {"a": 1})
+ self.false((ARGS, 3, 4), {"a": 1}, (1, 2, 3, 4), {"a": 1, "b": 2})
+ self.false((ARGS, 3, 4), {}, (), {})
+ self.false((ARGS, 3, 4), {}, (3, 5), {})
+ self.false((ARGS, 3, 4), {}, (5, 5), {})
+ self.false((ARGS, 3, 4), {"a": 1}, (), {})
+ self.false((ARGS, 3, 4), {"a": 1}, (3, 4), {})
+ self.false((ARGS, 3, 4), {"a": 1}, (3, 4), {"b": 2})
+
+ def test_args_at_end(self):
+ self.true((1, 2, ARGS), {}, (1, 2), {})
+ self.true((1, 2, ARGS), {}, (1, 2, 3, 4), {})
+ self.true((1, 2, ARGS), {"a": 1}, (1, 2), {"a": 1})
+ self.false((1, 2, ARGS), {"a": 1}, (1, 2, 3, 4), {"a": 1, "b": 2})
+ self.false((1, 2, ARGS), {}, (), {})
+ self.false((1, 2, ARGS), {}, (1, 3), {})
+ self.false((1, 2, ARGS), {}, (3, 3), {})
+ self.false((1, 2, ARGS), {"a": 1}, (), {})
+ self.false((1, 2, ARGS), {"a": 1}, (1, 2), {})
+ self.false((1, 2, ARGS), {"a": 1}, (1, 2), {"b": 2})
+
+ def test_args_at_middle(self):
+ self.true((1, ARGS, 4), {}, (1, 4), {})
+ self.true((1, ARGS, 4), {}, (1, 2, 3, 4), {})
+ self.true((1, ARGS, 4), {"a": 1}, (1, 4), {"a": 1})
+ self.false((1, ARGS, 4), {"a": 1}, (1, 2, 3, 4), {"a": 1, "b": 2})
+ self.false((1, ARGS, 4), {}, (), {})
+ self.false((1, ARGS, 4), {}, (1, 5), {})
+ self.false((1, ARGS, 4), {}, (5, 5), {})
+ self.false((1, ARGS, 4), {"a": 1}, (), {})
+ self.false((1, ARGS, 4), {"a": 1}, (1, 4), {})
+ self.false((1, ARGS, 4), {"a": 1}, (1, 4), {"b": 2})
+
+ def test_args_multiple(self):
+ self.true((ARGS, 3, ARGS, 6, ARGS), {},
(1, 2, 3, 4, 5, 6), {})
- self.true((VARIOUS, VARIOUS, VARIOUS), {}, (1, 2, 3, 4, 5, 6), {})
- self.true((VARIOUS, VARIOUS, VARIOUS), {}, (), {})
- self.false((VARIOUS, 3, VARIOUS, 6, VARIOUS), {},
+ self.true((ARGS, ARGS, ARGS), {}, (1, 2, 3, 4, 5, 6), {})
+ self.true((ARGS, ARGS, ARGS), {}, (), {})
+ self.false((ARGS, 3, ARGS, 6, ARGS), {},
(1, 2, 3, 4, 5), {})
- self.false((VARIOUS, 3, VARIOUS, 6, VARIOUS), {},
+ self.false((ARGS, 3, ARGS, 6, ARGS), {},
(1, 2, 4, 5, 6), {})
@@ -1055,95 +1313,150 @@ class MockTest(unittest.TestCase):
def act(path):
self.paths.append(path)
return 42
+ self.StubMocker = StubMocker
self.mocker = StubMocker()
- self.obj = Mock(self.mocker)
-
- def test_mocker(self):
- self.assertEquals(self.obj.__mocker__, self.mocker)
- self.assertEquals(self.obj.__mocker_name__, None)
-
- def test_default_path(self):
- path = self.obj.__mocker_path__
- self.assertEquals(path.root_mock, self.obj)
- self.assertEquals(path.actions, ())
+ self.mock = Mock(self.mocker)
+
+ def test_default_attributes(self):
+ self.assertEquals(self.mock.__mocker__, self.mocker)
+ self.assertEquals(self.mock.__mocker_path__, Path(self.mock))
+ self.assertEquals(self.mock.__mocker_name__, None)
+ self.assertEquals(self.mock.__mocker_spec__, None)
+ self.assertEquals(self.mock.__mocker_type__, None)
+ self.assertEquals(self.mock.__mocker_object__, None)
+ self.assertEquals(self.mock.__mocker_passthrough__, False)
+ self.assertEquals(self.mock.__mocker_patcher__, None)
+ self.assertEquals(self.mock.__mocker_replace__, False)
def test_path(self):
path = object()
self.assertEquals(Mock(self.mocker, path).__mocker_path__, path)
def test_object(self):
- obj = Mock(self.mocker, object="foo")
- self.assertEquals(obj.__mocker_object__, "foo")
+ mock = Mock(self.mocker, object="foo")
+ self.assertEquals(mock.__mocker_object__, "foo")
+ self.assertEquals(mock.__mocker_path__.root_object, "foo")
def test_passthrough(self):
- obj = Mock(self.mocker, object="foo", passthrough=True)
- self.assertEquals(obj.__mocker_object__, "foo")
- self.assertEquals(obj.__mocker_passthrough__, True)
+ mock = Mock(self.mocker, object="foo", passthrough=True)
+ self.assertEquals(mock.__mocker_object__, "foo")
+ self.assertEquals(mock.__mocker_passthrough__, True)
+
+ def test_spec(self):
+ C = object()
+ self.assertEquals(Mock(self.mocker, spec=C).__mocker_spec__, C)
+
+ def test_type(self):
+ def raise_exception(self, path):
+ raise MatchError
+ self.StubMocker.act = raise_exception
+ class C(object): pass
+ mock = Mock(self.mocker, type=C)
+ self.assertEquals(mock.__mocker_type__, C)
+ self.assertEquals(mock.__class__, C)
+ self.assertEquals(isinstance(mock, C), True)
def test_auto_naming(self):
- named_obj = self.obj
- named_obj.attr
- another_name = named_obj
- named_obj = None # Can't find this one anymore.
+ named_mock = self.mock
+ named_mock.attr
+ another_name = named_mock
+ named_mock = None # Can't find this one anymore.
another_name.attr
- self.assertEquals(another_name.__mocker_name__, "named_obj")
+ self.assertEquals(another_name.__mocker_name__, "named_mock")
def test_auto_naming_on_self(self):
- self.named_obj = self.obj
- del self.obj
- self.named_obj.attr
- self.assertEquals(self.named_obj.__mocker_name__, "named_obj")
+ self.named_mock = self.mock
+ del self.mock
+ self.named_mock.attr
+ self.assertEquals(self.named_mock.__mocker_name__, "named_mock")
def test_auto_naming_on_bad_self(self):
self_ = self
self = object() # No __dict__
- self_.named_obj = self_.obj
- self_.named_obj.attr
- self_.assertEquals(self_.named_obj.__mocker_name__, None)
+ self_.named_mock = self_.mock
+ self_.named_mock.attr
+ self_.assertEquals(self_.named_mock.__mocker_name__, None)
def test_auto_naming_without_getframe(self):
getframe = sys._getframe
sys._getframe = None
try:
- self.named_obj = self.obj
- self.named_obj.attr
- self.assertEquals(self.named_obj.__mocker_name__, None)
+ self.named_mock = self.mock
+ self.named_mock.attr
+ self.assertEquals(self.named_mock.__mocker_name__, None)
finally:
sys._getframe = getframe
def test_getattr(self):
- self.assertEquals(self.obj.attr, 42)
+ self.assertEquals(self.mock.attr, 42)
(path,) = self.paths
self.assertEquals(type(path), Path)
- self.assertTrue(path.parent_path is self.obj.__mocker_path__)
- self.assertEquals(path, self.obj.__mocker_path__ +
- Action(None, "getattr", ("attr",), {}))
+ self.assertTrue(path.parent_path is self.mock.__mocker_path__)
+ self.assertEquals(path, self.mock.__mocker_path__ +
+ Action("getattr", ("attr",), {}))
def test_call(self):
- self.obj(1, a=2)
+ self.mock(1, a=2)
(path,) = self.paths
self.assertEquals(type(path), Path)
- self.assertTrue(path.parent_path is self.obj.__mocker_path__)
- self.assertEquals(path, self.obj.__mocker_path__ +
- Action(None, "call", (1,), {"a": 2}))
+ self.assertTrue(path.parent_path is self.mock.__mocker_path__)
+ self.assertEquals(path, self.mock.__mocker_path__ +
+ Action("call", (1,), {"a": 2}))
def test_passthrough_on_unexpected(self):
class StubMocker(object):
def act(self, path):
if path.actions[-1].args == ("x",):
- raise UnexpectedExprError
+ raise MatchError
return 42
class C(object):
x = 123
y = 321
- obj = Mock(StubMocker(), object=C())
- self.assertRaises(UnexpectedExprError, getattr, obj, "x", 42)
- self.assertEquals(obj.y, 42)
+ mock = Mock(StubMocker(), object=C())
+ self.assertRaises(MatchError, getattr, mock, "x", 42)
+ self.assertEquals(mock.y, 42)
+
+ mock = Mock(StubMocker(), passthrough=True)
+ self.assertRaises(MatchError, getattr, mock, "x", 42)
+ self.assertEquals(mock.y, 42)
+
+ mock = Mock(StubMocker(), object=C(), passthrough=True)
+ self.assertEquals(mock.x, 123)
+ self.assertEquals(mock.y, 42)
+
+ mock = Mock(StubMocker(), passthrough=True)
+ act = mock.__mocker_act__
+ self.assertEquals(act("getattr", ("x",), 42, object=C()), 123)
+ self.assertEquals(act("getattr", ("y",), 42, object=C()), 42)
+
+ def test_act_with_object(self):
+ obj = object()
+ self.mock.__mocker_act__("kind", object=obj)
+ (path,) = self.paths
+ self.assertEquals(type(path), Path)
+ self.assertTrue(path.parent_path is self.mock.__mocker_path__)
+ self.assertTrue(path.root_object is obj)
+
+ def test_reraise_assertion(self):
+ class StubMocker(object):
+ def act(self, path):
+ message = os.linesep.join(["An", "- error", "- happened"])
+ raise AssertionError(message)
+ mock = Mock(StubMocker())
+ try:
+ mock.__mocker_act__("kind")
+ except AssertionError, e:
+ message = os.linesep.join(["[Mocker] Unmet expectation:",
+ "",
+ "=> An",
+ " - error",
+ " - happened",
+ ""])
+ self.assertEquals(str(e), message)
+ else:
+ self.fail("AssertionError not raised")
- obj = Mock(StubMocker(), object=C(), passthrough=True)
- self.assertEquals(obj.x, 123)
- self.assertEquals(obj.y, 42)
class EventTest(unittest.TestCase):
@@ -1220,9 +1533,32 @@ class EventTest(unittest.TestCase):
self.assertEquals(self.event.run(42), False)
self.assertEquals(calls, [42, 42, 42])
+ def test_run_errors(self):
+ class MyTask(object):
+ def __init__(self, id, failed):
+ self.id = id
+ self.failed = failed
+ def run(self, path):
+ if self.failed:
+ raise AssertionError("%d failed" % self.id)
+ event = Event("i.am.a.path")
+ event.add_task(MyTask(1, True))
+ event.add_task(MyTask(2, False))
+ event.add_task(MyTask(3, True))
+
+ try:
+ event.run(42)
+ except AssertionError, e:
+ message = os.linesep.join(["i.am.a.path",
+ "- 1 failed",
+ "- 3 failed"])
+ self.assertEquals(str(e), message)
+ else:
+ self.fail("AssertionError not raised")
+
def test_satisfied_false(self):
def raise_error():
- raise AssertionError
+ raise AssertionError("An error")
task1 = self.event.add_task(Task())
task2 = self.event.add_task(Task())
task2.verify = raise_error
@@ -1237,13 +1573,27 @@ class EventTest(unittest.TestCase):
self.assertEquals(self.event.satisfied(), True)
def test_verify(self):
- calls = []
- task1 = self.event.add_task(Task())
- task1.verify = lambda: calls.append(1)
- task2 = self.event.add_task(Task())
- task2.verify = lambda: calls.append(2)
- self.event.verify()
- self.assertEquals(calls, [1, 2])
+ class MyTask(object):
+ def __init__(self, id, failed):
+ self.id = id
+ self.failed = failed
+ def verify(self):
+ if self.failed:
+ raise AssertionError("%d failed" % self.id)
+ event = Event("i.am.a.path")
+ event.add_task(MyTask(1, True))
+ event.add_task(MyTask(2, False))
+ event.add_task(MyTask(3, True))
+
+ try:
+ event.verify()
+ except AssertionError, e:
+ message = os.linesep.join(["i.am.a.path",
+ "- 1 failed",
+ "- 3 failed"])
+ self.assertEquals(str(e), message)
+ else:
+ self.fail("AssertionError not raised")
def test_set_state(self):
calls = []
@@ -1277,7 +1627,7 @@ class PathMatcherTest(unittest.TestCase):
def setUp(self):
self.mocker = CleanMocker()
- self.mock = self.mocker.obj()
+ self.mock = self.mocker.mock()
def test_is_task(self):
self.assertTrue(isinstance(PathMatcher(None), Task))
@@ -1288,15 +1638,15 @@ class PathMatcherTest(unittest.TestCase):
self.assertEquals(task.path, path)
def test_matches(self):
- path = Path(self.mock, [Action(None, "getattr", ("attr1",), {})])
+ path = Path(self.mock, None, [Action("getattr", ("attr1",), {})])
task = PathMatcher(path)
- action = Action(Path(self.mock), "getattr", (), {})
+ action = Action("getattr", (), {}, Path(self.mock))
self.assertFalse(task.matches(action.path + action))
- action = Action(Path(self.mock), "getattr", ("attr1",), {})
+ action = Action("getattr", ("attr1",), {}, Path(self.mock))
self.assertTrue(task.matches(action.path + action))
def test_recorder(self):
- path = Path(self.mock, [Action(None, "call", (), {})])
+ path = Path(self.mock, [Action("call", (), {})])
event = Event(path)
path_matcher_recorder(self.mocker, event)
(task,) = event.get_tasks()
@@ -1311,8 +1661,8 @@ class RunCounterTest(unittest.TestCase):
def setUp(self):
self.mocker = CleanMocker()
- self.mock = self.mocker.obj()
- self.action = Action(Path(self.mock), "getattr", ("attr",), {})
+ self.mock = self.mocker.mock()
+ self.action = Action("getattr", ("attr",), {}, Path(self.mock))
self.path = Path(self.mock, [self.action])
self.event = Event(self.path)
@@ -1387,10 +1737,10 @@ class RunCounterTest(unittest.TestCase):
may be repeated any number of times.
"""
path1 = Path(self.mock)
- path2 = path1 + Action(path1, "getattr", ("attr",), {})
- path3 = path2 + Action(path2, "getattr", ("attr",), {})
- path4 = path3 + Action(path3, "call", (), {})
- path5 = path4 + Action(path4, "call", (), {})
+ path2 = path1 + Action("getattr", ("attr",), {}, path1)
+ path3 = path2 + Action("getattr", ("attr",), {}, path2)
+ path4 = path3 + Action("call", (), {}, path3)
+ path5 = path4 + Action("call", (), {}, path4)
event3 = self.mocker.add_event(Event(path3))
event2 = self.mocker.add_event(Event(path2))
@@ -1437,7 +1787,7 @@ class RunCounterTest(unittest.TestCase):
self.mocker.add_recorder(run_counter_recorder)
self.mocker.add_recorder(run_counter_removal_recorder)
- obj = self.mocker.obj()
+ obj = self.mocker.mock()
obj.x.y()()
@@ -1457,8 +1807,8 @@ class MockReturnerTest(unittest.TestCase):
def setUp(self):
self.mocker = CleanMocker()
- self.mock = self.mocker.obj()
- self.action = Action(Path(self.mock), "getattr", ("attr",), {})
+ self.mock = self.mocker.mock()
+ self.action = Action("getattr", ("attr",), {}, Path(self.mock))
self.path = Path(self.mock, [self.action])
self.event = Event(self.path)
@@ -1474,9 +1824,9 @@ class MockReturnerTest(unittest.TestCase):
def test_recorder(self):
path1 = Path(self.mock)
- path2 = path1 + Action(path1, "getattr", ("attr",), {})
- path3 = path2 + Action(path2, "getattr", ("attr",), {})
- path4 = path3 + Action(path3, "call", (), {})
+ path2 = path1 + Action("getattr", ("attr",), {}, path1)
+ path3 = path2 + Action("getattr", ("attr",), {}, path2)
+ path4 = path3 + Action("call", (), {}, path3)
event2 = self.mocker.add_event(Event(path2))
event3 = self.mocker.add_event(Event(path3))
@@ -1514,9 +1864,9 @@ class FunctionRunnerTest(unittest.TestCase):
def setUp(self):
self.mocker = CleanMocker()
- self.mock = self.mocker.obj()
- self.action = Action(Path(self.mock), "call", (1, 2), {"c": 3})
- self.path = Path(self.mock, [self.action])
+ self.mock = self.mocker.mock()
+ self.action = Action("call", (1, 2), {"c": 3}, Path(self.mock))
+ self.path = Path(self.mock, None, [self.action])
self.event = Event(self.path)
def test_is_task(self):
@@ -1528,13 +1878,13 @@ class FunctionRunnerTest(unittest.TestCase):
self.assertEquals(result, "((1, 2), {'c': 3})")
-class PathApplierTest(unittest.TestCase):
+class PathExecuterTest(unittest.TestCase):
def setUp(self):
self.mocker = CleanMocker()
def test_is_task(self):
- self.assertTrue(isinstance(PathApplier(), Task))
+ self.assertTrue(isinstance(PathExecuter(), Task))
def test_run(self):
class C(object):
@@ -1543,13 +1893,11 @@ class PathApplierTest(unittest.TestCase):
obj.x = C()
obj.x.y = lambda a, b: a+b
- proxy = self.mocker.proxy(obj)
+ path = Path(None, obj, [Action("getattr", ("x",), {}),
+ Action("getattr", ("y",), {}),
+ Action("call", (1,), {"b": 2})])
- path = Path(proxy, [Action(None, "getattr", ("x",), {}),
- Action(None, "getattr", ("y",), {}),
- Action(None, "call", (1,), {"b": 2})])
-
- task = PathApplier()
+ task = PathExecuter()
self.assertEquals(task.run(path), 3)
@@ -1557,8 +1905,8 @@ class OrdererTest(unittest.TestCase):
def setUp(self):
self.mocker = CleanMocker()
- self.mock = self.mocker.obj()
- self.action = Action(Path(self.mock), "call", (1, 2), {"c": 3})
+ self.mock = self.mocker.mock()
+ self.action = Action("call", (1, 2, Path(self.mock)), {"c": 3})
self.path = Path(self.mock, [self.action])
def test_is_task(self):
@@ -1605,10 +1953,10 @@ class SpecCheckerTest(unittest.TestCase):
def staticnoargs(): pass
self.cls = C
self.mocker = CleanMocker()
- self.mock = self.mocker.obj(self.cls)
+ self.mock = self.mocker.mock(self.cls)
def path(self, *args, **kwargs):
- action = Action(Path(self.mock), "call", args, kwargs)
+ action = Action("call", args, kwargs, Path(self.mock))
return action.path + action
def good(self, method_names, args_expr):
@@ -1647,9 +1995,19 @@ class SpecCheckerTest(unittest.TestCase):
def test_is_task(self):
self.assertTrue(isinstance(SpecChecker(self.cls.normal), Task))
+ def test_error_message(self):
+ task = SpecChecker(self.cls.normal)
+ try:
+ task.run(self.path(1))
+ except AssertionError, e:
+ self.assertEquals(str(e), "Specification is normal(a, b, c=3): "
+ "'b' not provided")
+ else:
+ self.fail("AssertionError not raised")
+
def test_recorder(self):
self.mocker.add_recorder(spec_checker_recorder)
- obj = self.mocker.obj(self.cls)
+ obj = self.mocker.mock(spec=self.cls)
obj.noargs()
getattr, call = self.mocker.get_events()
self.assertEquals(getattr.get_tasks(), [])
@@ -1659,7 +2017,7 @@ class SpecCheckerTest(unittest.TestCase):
def test_recorder_with_unexistent_method(self):
self.mocker.add_recorder(spec_checker_recorder)
- obj = self.mocker.obj(self.cls)
+ obj = self.mocker.mock(spec=self.cls)
obj.unexistent()
getattr, call = self.mocker.get_events()
self.assertEquals(getattr.get_tasks(), [])
@@ -1669,7 +2027,7 @@ class SpecCheckerTest(unittest.TestCase):
def test_recorder_second_action_isnt_call(self):
self.mocker.add_recorder(spec_checker_recorder)
- obj = self.mocker.obj(self.cls)
+ obj = self.mocker.mock(spec=self.cls)
obj.noargs.x
event1, event2 = self.mocker.get_events()
self.assertEquals(event1.get_tasks(), [])
@@ -1677,7 +2035,7 @@ class SpecCheckerTest(unittest.TestCase):
def test_recorder_first_action_isnt_getattr(self):
self.mocker.add_recorder(spec_checker_recorder)
- obj = self.mocker.obj(self.cls)
+ obj = self.mocker.mock(spec=self.cls)
obj("noargs").x
event1, event2 = self.mocker.get_events()
self.assertEquals(event1.get_tasks(), [])
@@ -1685,7 +2043,7 @@ class SpecCheckerTest(unittest.TestCase):
def test_recorder_more_than_two_actions(self):
self.mocker.add_recorder(spec_checker_recorder)
- obj = self.mocker.obj(self.cls)
+ obj = self.mocker.mock(spec=self.cls)
obj.noargs().x
event1, event2, event3 = self.mocker.get_events()
self.assertEquals(len(event1.get_tasks()), 0)
@@ -1742,23 +2100,23 @@ class SpecCheckerTest(unittest.TestCase):
self.bad("unexistent", "")
-class ProxyInstallerTest(unittest.TestCase):
+class ProxyReplacerTest(unittest.TestCase):
def setUp(self):
self.mocker = CleanMocker()
import calendar
self.mock = Mock(self.mocker, object=calendar)
- self.task = ProxyInstaller(self.mock)
+ self.task = ProxyReplacer(self.mock)
def tearDown(self):
self.task.set_state(RESTORE)
def test_is_task(self):
- self.assertTrue(isinstance(ProxyInstaller(None), Task))
+ self.assertTrue(isinstance(ProxyReplacer(None), Task))
def test_mock(self):
mock = object()
- task = ProxyInstaller(mock)
+ task = ProxyReplacer(mock)
self.assertEquals(task.mock, mock)
def test_matches_nothing(self):
@@ -1778,11 +2136,27 @@ class ProxyInstallerTest(unittest.TestCase):
self.task.set_state(REPLAY)
self.assertEquals(type(self.mock.__mocker_object__), ModuleType)
+ def test_install_protects_path(self):
+ self.task.set_state(REPLAY)
+ self.assertEquals(type(self.mock.__mocker_path__.root_object),
+ ModuleType)
+
def test_deinstall_protects_task(self):
self.task.set_state(REPLAY)
self.task.set_state(RESTORE)
self.assertEquals(type(self.task.mock), Mock)
+ def test_install_protects_anything_with_mocker_replace_false(self):
+ class C(object):
+ def __init__(self):
+ import calendar
+ self.calendar = calendar
+ self.__mocker_replace__ = False
+ obj = C()
+ self.task.set_state(REPLAY)
+ self.assertEquals(type(self.mock.__mocker_path__.root_object),
+ ModuleType)
+
def test_install_on_object(self):
class C(object):
def __init__(self):
@@ -1796,7 +2170,7 @@ class ProxyInstallerTest(unittest.TestCase):
def test_install_on_submodule(self):
from os import path
mock = Mock(self.mocker, object=path)
- task = ProxyInstaller(mock)
+ task = ProxyReplacer(mock)
task.set_state(REPLAY)
import os
self.assertEquals(type(os.path), Mock)
@@ -1830,12 +2204,315 @@ class ProxyInstallerTest(unittest.TestCase):
def test_deinstall_from_submodule(self):
from os import path
mock = Mock(self.mocker, object=path)
- task = ProxyInstaller(mock)
+ task = ProxyReplacer(mock)
task.set_state(REPLAY)
task.set_state(RESTORE)
import os
self.assertEquals(type(os.path), ModuleType)
+class PatcherTest(unittest.TestCase):
+
+ def setUp(self):
+ self.mocker = Mocker()
+ self.patcher = Patcher()
+ self.C = type("C", (object,), {})
+ self.D = type("D", (self.C,), {})
+ self.E = type("E", (), {})
+
+ class MockStub(object):
+ def __mocker_act__(self, kind, args=(), kwargs={}, object=None):
+ return (kind, args, kwargs, object)
+
+ self.MockStub = MockStub
+
+ def test_is_task(self):
+ self.assertTrue(isinstance(Patcher(), Task))
+
+ def test_matches_nothing(self):
+ self.assertFalse(self.patcher.matches(None))
+
+ def test_is_monitoring_unseen_class_kind(self):
+ self.assertFalse(self.patcher.is_monitoring(self.C, "kind"))
+
+ def test_monitor_class(self):
+ self.patcher.monitor(self.C, "kind")
+ self.assertTrue(self.patcher.is_monitoring(self.C, "kind"))
+
+ def test_monitor_subclass(self):
+ self.patcher.monitor(self.C, "kind")
+ self.assertTrue(self.patcher.is_monitoring(self.D, "kind"))
+
+ def test_monitor_unknown_class(self):
+ self.patcher.monitor(self.C, "kind")
+ self.assertFalse(self.patcher.is_monitoring(self.E, "kind"))
+
+ def test_is_monitoring_unseen_instance(self):
+ obj = self.E()
+ self.patcher.monitor(self.C, "kind")
+ self.assertFalse(self.patcher.is_monitoring(obj, "kind"))
+
+ def test_is_monitoring_instance_explicitly_monitored(self):
+ obj = self.C()
+ self.patcher.monitor(obj, "kind")
+ self.assertTrue(self.patcher.is_monitoring(obj, "kind"))
+
+ def test_is_monitoring_instance_monitored_by_class(self):
+ obj = self.D()
+ self.patcher.monitor(self.D, "kind")
+ self.assertTrue(self.patcher.is_monitoring(obj, "kind"))
+
+ def test_patch_attr(self):
+ self.patcher.patch_attr(self.C, "attr", "patch")
+ self.assertEquals(self.C.__dict__.get("attr"), "patch")
+
+ def test_patch_attr_and_restore(self):
+ self.patcher.patch_attr(self.C, "attr", "patch")
+ self.patcher.set_state(RESTORE)
+ self.assertTrue("attr" not in self.C.__dict__)
+
+ def test_patch_attr_and_restore_to_original(self):
+ self.C.attr = "original"
+ self.patcher.patch_attr(self.C, "attr", "patch")
+ self.patcher.set_state(RESTORE)
+ self.assertEquals(self.C.__dict__.get("attr"), "original")
+
+ def test_get_unpatched_attr_unpatched_undefined(self):
+ self.assertEquals(self.patcher.get_unpatched_attr(self.C, "attr"),
+ Undefined)
+
+ def test_get_unpatched_attr_unpatched(self):
+ self.C.attr = "original"
+ self.assertEquals(self.patcher.get_unpatched_attr(self.C, "attr"),
+ "original")
+
+ def test_get_unpatched_attr_defined_on_superclass(self):
+ self.C.attr = "original"
+ self.assertEquals(self.patcher.get_unpatched_attr(self.D, "attr"),
+ "original")
+
+ def test_get_unpatched_attr_defined_on_superclass_patched_on_sub(self):
+ self.C.attr = "original"
+ self.patcher.patch_attr(self.D, "attr", "patch")
+ self.assertEquals(self.patcher.get_unpatched_attr(self.D, "attr"),
+ "original")
+
+ def test_get_unpatched_attr_patched_originally_undefined(self):
+ self.patcher.patch_attr(self.C, "attr", "patch")
+ self.assertEquals(self.patcher.get_unpatched_attr(self.C, "attr"),
+ Undefined)
+
+ def test_get_unpatched_attr_patched(self):
+ self.C.attr = "original"
+ self.patcher.patch_attr(self.C, "attr", "patch")
+ self.assertEquals(self.patcher.get_unpatched_attr(self.C, "attr"),
+ "original")
+
+ def test_get_unpatched_attr_on_instance_originally_undefined(self):
+ self.assertEquals(self.patcher.get_unpatched_attr(self.C(), "attr"),
+ Undefined)
+
+ def test_get_unpatched_attr_on_instance(self):
+ self.C.attr = "original"
+ self.assertEquals(self.patcher.get_unpatched_attr(self.D(), "attr"),
+ "original")
+
+ def test_get_unpatched_attr_on_instance_defined_on_superclass(self):
+ self.C.attr = "original"
+ self.patcher.patch_attr(self.C, "attr", "patch")
+ self.assertEquals(self.patcher.get_unpatched_attr(self.D(), "attr"),
+ "original")
+
+ def test_get_unpatched_attr_on_instance_with_descriptor(self):
+ self.C.attr = property(lambda self: "original")
+ self.patcher.patch_attr(self.C, "attr", "patch")
+ self.assertEquals(self.patcher.get_unpatched_attr(self.D(), "attr"),
+ "original")
+
+ def test_get_unpatched_attr_on_instance_with_fake_descriptor(self):
+ class BadProperty(object):
+ def __init__(self):
+ # On real, __get__ must be on the class, not on the instance.
+ self.__get__ = lambda self, obj, cls=None: "original"
+ prop = BadProperty()
+ self.C.attr = prop
+ self.patcher.patch_attr(self.C, "attr", "patch")
+ self.assertEquals(self.patcher.get_unpatched_attr(self.D(), "attr"),
+ prop)
+
+ def test_replay_with_monitored_class(self):
+ self.patcher.monitor(self.C, "call")
+ self.patcher.set_state(REPLAY)
+ self.assertEquals(type(self.C.__dict__["__call__"]), PatchedMethod)
+
+ def test_replay_with_monitored_instance(self):
+ self.patcher.monitor(self.C(), "call")
+ self.patcher.set_state(REPLAY)
+ self.assertEquals(type(self.C.__dict__["__call__"]), PatchedMethod)
+
+ def test_replay_getattr(self):
+ self.patcher.monitor(self.C, "getattr")
+ self.patcher.set_state(REPLAY)
+ self.assertEquals(type(self.C.__dict__["__getattribute__"]),
+ PatchedMethod)
+
+ def test_restore(self):
+ self.patcher.monitor(self.C, "call")
+ self.patcher.set_state(REPLAY)
+ self.patcher.set_state(RESTORE)
+ self.assertTrue("__call__" not in self.C.__dict__)
+
+ def test_restore_twice_does_nothing(self):
+ self.patcher.monitor(self.C, "call")
+ self.patcher.set_state(REPLAY)
+ self.patcher.set_state(RESTORE)
+ self.C.__call__ = "original"
+ self.patcher.set_state(RESTORE)
+ self.assertTrue(self.C.__dict__.get("__call__"), "original")
+
+ def test_patched_call_on_instance(self):
+ self.patcher.monitor(self.C, "call")
+ obj = self.C()
+ obj.__mocker_mock__ = self.MockStub()
+ self.patcher.set_state(REPLAY)
+ result = obj(1, a=2)
+ self.assertEquals(result, ("call", (1,), {"a": 2}, obj))
+
+ def test_patched_call_on_class(self):
+ self.patcher.monitor(self.C, "call")
+ self.C.__mocker_mock__ = self.MockStub()
+ self.patcher.set_state(REPLAY)
+ obj = self.C()
+ result = obj(1, a=2)
+ self.assertEquals(result, ("call", (1,), {"a": 2}, obj))
+
+ def test_patched_call_on_class_edge_case(self):
+ """Only "getattr" kind should passthrough on __mocker_* arguments."""
+ self.patcher.monitor(self.C, "call")
+ self.C.__mocker_mock__ = self.MockStub()
+ self.patcher.set_state(REPLAY)
+ obj = self.C()
+ result = obj("__mocker_mock__")
+ self.assertEquals(result, ("call", ("__mocker_mock__",), {}, obj))
+
+ def test_patched_getattr_on_class(self):
+ self.patcher.monitor(self.C, "getattr")
+ self.C.__mocker_mock__ = self.MockStub()
+ self.patcher.set_state(REPLAY)
+ obj = self.C()
+ result = obj.attr
+ self.assertEquals(result, ("getattr", ("attr",), {}, obj))
+
+ def test_patched_getattr_on_unmonitored_object(self):
+ obj1 = self.C()
+ obj1.__mocker_mock__ = self.MockStub()
+ self.patcher.monitor(obj1, "getattr")
+ obj2 = self.C()
+ obj2.attr = "original"
+ self.patcher.set_state(REPLAY)
+ self.assertEquals(obj1.attr, ("getattr", ("attr",), {}, obj1))
+ self.assertEquals(obj2.attr, "original")
+
+ def test_patched_getattr_on_different_instances(self):
+ def build_getattr(original):
+ def __getattribute__(self, name):
+ if name == "attr":
+ return original
+ return object.__getattribute__(self, name)
+ return __getattribute__
+ self.C.__getattribute__ = build_getattr("originalC")
+ self.D.__getattribute__ = build_getattr("originalD")
+
+ class MockStub(object):
+ def __init__(self, id):
+ self.id = id
+ def __mocker_act__(self, kind, args=(), kwargs={}, object=None):
+ return self.id
+
+ obj1, obj2, obj3, obj4, obj5, obj6 = [self.C() for i in range(6)]
+ obj7, obj8, obj9 = [self.D() for i in range(3)]
+
+ obj2.__mocker_mock__ = MockStub(2)
+ self.patcher.monitor(obj2, "getattr")
+ obj5.__mocker_mock__ = MockStub(5)
+ self.patcher.monitor(obj5, "getattr")
+ obj8.__mocker_mock__ = MockStub(8)
+ self.patcher.monitor(obj8, "getattr")
+
+ self.patcher.set_state(REPLAY)
+ self.assertEquals(obj1.attr, "originalC")
+ self.assertEquals(obj2.attr, 2)
+ self.assertEquals(obj3.attr, "originalC")
+ self.assertEquals(obj4.attr, "originalC")
+ self.assertEquals(obj5.attr, 5)
+ self.assertEquals(obj6.attr, "originalC")
+ self.assertEquals(obj7.attr, "originalD")
+ self.assertEquals(obj8.attr, 8)
+ self.assertEquals(obj9.attr, "originalD")
+
+ def test_execute_getattr(self):
+ class C(object):
+ def __getattribute__(self, attr):
+ if attr == "attr":
+ return "original"
+ action = Action("getattr", ("attr",), {})
+ obj = C()
+ self.patcher.monitor(obj, "getattr")
+ self.patcher.set_state(REPLAY)
+ self.assertEquals(self.patcher.execute(action, obj), "original")
+
+ def test_execute_getattr_on_unexistent(self):
+ action = Action("getattr", ("attr",), {})
+ obj = self.C()
+ self.patcher.monitor(obj, "getattr")
+ self.patcher.set_state(REPLAY)
+ self.assertRaises(AttributeError, self.patcher.execute, action, obj)
+
+ def test_execute_call(self):
+ class C(object):
+ def __call__(self, *args, **kwargs):
+ return (args, kwargs)
+ action = Action("call", (1,), {"a": 2})
+ obj = C()
+ self.patcher.monitor(obj, "call")
+ self.patcher.set_state(REPLAY)
+ self.assertEquals(self.patcher.execute(action, obj), ((1,), {"a": 2}))
+
+ def test_recorder_class_getattr(self):
+ mock = self.mocker.patch(self.C)
+ mock.method()
+ self.mocker.result("mocked")
+ self.mocker.replay()
+ self.assertEquals(self.C().method(), "mocked")
+ self.assertRaises(AssertionError, self.C().method)
+
+ def test_recorder_instance_getattr(self):
+ self.C.attr = "original"
+ obj1 = self.C()
+ obj2 = self.C()
+ mock = self.mocker.patch(obj1)
+ mock.attr
+ self.mocker.result("mocked")
+ self.mocker.replay()
+ self.assertEquals(obj1.attr, "mocked")
+ self.assertRaises(AssertionError, getattr, obj1, "attr")
+ self.assertEquals(obj2.attr, "original")
+ self.assertRaises(AttributeError, getattr, obj1, "unexistent")
+
+ def test_recorder_passthrough(self):
+ class C(object):
+ def __init__(self):
+ self.result = "original" # Value on object's dictionary.
+ def method(self):
+ return self.result
+ mock = self.mocker.patch(C)
+ mock.method()
+ self.mocker.passthrough()
+ self.mocker.replay()
+ obj = C()
+ self.assertEquals(obj.method(), "original")
+ self.assertRaises(AssertionError, obj.method)
+
+
if __name__ == "__main__":
unittest.main()