1 # Copyright 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4 """A very very simple mock object harness."""
5 from types import ModuleType
9 class MockFunctionCall(object):
10 def __init__(self, name):
13 self.return_value = None
14 self.when_called_handlers = []
16 def WithArgs(self, *args):
20 def WillReturn(self, value):
21 self.return_value = value
24 def WhenCalled(self, handler):
25 self.when_called_handlers.append(handler)
27 def VerifyEquals(self, got):
28 if self.name != got.name:
29 raise Exception('Self %s, got %s' % (repr(self), repr(got)))
30 if len(self.args) != len(got.args):
31 raise Exception('Self %s, got %s' % (repr(self), repr(got)))
32 for i in range(len(self.args)):
35 if self_a == DONT_CARE:
38 raise Exception('Self %s, got %s' % (repr(self), repr(got)))
45 args_text = ', '.join([arg_to_text(a) for a in self.args])
46 if self.return_value in (None, DONT_CARE):
47 return '%s(%s)' % (self.name, args_text)
48 return '%s(%s)->%s' % (self.name, args_text, repr(self.return_value))
50 class MockTrace(object):
52 self.expected_calls = []
53 self.next_call_index = 0
55 class MockObject(object):
56 def __init__(self, parent_mock = None):
58 self._trace = parent_mock._trace # pylint: disable=W0212
60 self._trace = MockTrace()
62 def __setattr__(self, name, value):
63 if (not hasattr(self, '_trace') or
64 hasattr(value, 'is_hook')):
65 object.__setattr__(self, name, value)
67 assert isinstance(value, MockObject)
68 object.__setattr__(self, name, value)
70 def SetAttribute(self, name, value):
71 setattr(self, name, value)
73 def ExpectCall(self, func_name, *args):
74 assert self._trace.next_call_index == 0
75 if not hasattr(self, func_name):
76 self._install_hook(func_name)
78 call = MockFunctionCall(func_name)
79 self._trace.expected_calls.append(call)
83 def _install_hook(self, func_name):
84 def handler(*args, **_):
85 got_call = MockFunctionCall(
86 func_name).WithArgs(*args).WillReturn(DONT_CARE)
87 if self._trace.next_call_index >= len(self._trace.expected_calls):
89 'Call to %s was not expected, at end of programmed trace.' %
91 expected_call = self._trace.expected_calls[
92 self._trace.next_call_index]
93 expected_call.VerifyEquals(got_call)
94 self._trace.next_call_index += 1
95 for h in expected_call.when_called_handlers:
97 return expected_call.return_value
98 handler.is_hook = True
99 setattr(self, func_name, handler)
102 class MockTimer(object):
103 """ A mock timer to fake out the timing for a module.
105 module: module to fake out the time
107 def __init__(self, module=None):
108 self._elapsed_time = 0
109 self._module = module
110 self._actual_time = None
112 assert isinstance(module, ModuleType)
113 self._actual_time = module.time
114 self._module.time = self
116 def sleep(self, time):
117 self._elapsed_time += time
120 return self._elapsed_time
122 def SetTime(self, time):
123 self._elapsed_time = time
130 self._module.time = self._actual_time
132 self._actual_time = None