--- /dev/null
+import sys
+
+def pprint(*args):
+ if False:
+ for a in args:
+ try:
+ sys.stdout.write(a.__str__())
+ except:
+ try:
+ sys.stdout.write(a.__doc__)
+ except:
+ sys.stdout.write('BUG - FIXME')
+ sys.stdout.write(' ')
+ sys.stdout.write('\n')
+ sys.stdout.flush()
+
+class Mock():
+ def __init__(self):
+ pprint("Mock.__init__")
+ self._methods = {}
+ self._replay = False
+
+ def __getattr__(self, value):
+ pprint("Mock.__getattr__", value)
+ if self._methods.has_key(value):
+ pprint("returning mocked method")
+ return self._methods[value]
+ if self._replay:
+ class inner():
+ def __init__(self, method_name):
+ self._method_name = method_name
+ self._recorded_calls = []
+ self._args = None
+ self._kwargs = None
+ def __call__(self, *args, **kwargs):
+ pprint("REPLAYING", self.getName(), args, kwargs)
+ self._recorded_calls.append((args, kwargs))
+ self._args = args
+ self._kwargs = kwargs
+ def getName(self):
+ return self._method_name
+ def getNumberOfInvocations(self):
+ return len(self._recorded_calls)
+ def verify(self, args, kwargs):
+ if args != self._args or kwargs != self._kwargs:
+ raise Exception("No call for %s with arguments %s - actual: %s" % (value, args, self._args))
+ return True
+
+ pprint("returning 'empty' method", value)
+ empty = inner(value)
+ self.register(value, empty)
+ return empty
+ raise AttributeError("Mock doesn't contain attribute", value)
+ pprint("returning super method")
+ return Object.__getattr__.call(self, value)
+
+ def replay(self):
+ pprint("Mock.__replay__")
+ self._replay = True
+
+ def register(self, methodName, mock):
+ pprint("Mock.__register__", methodName)
+ self._methods[methodName] = mock
+
+ def getMethodMock(self, methodName):
+ pprint("Mock.getMethodMock", methodName)
+ if self._methods.has_key(methodName):
+ return self._methods[methodName]
+ return None
+
+class MethodMock():
+ def __init__(self, mock, args, kwargs):
+ pprint("MethodMock.__init__", args, kwargs)
+ self.target = mock
+ self._method_name = args[0]
+ mock.register(self._method_name, self)
+ self.args = args[1:]
+ self.kwargs = kwargs
+ self._recorded_calls = []
+ self._canned_response = None
+ self._canned_args = None
+ self._canned_args_set = False
+
+ def willReturn(self, args):
+ pprint(self.getName(), "willReturn", args)
+ self._canned_response = args
+
+ def verify(self, args, kwargs):
+ pprint("MethodMock.verify", args, kwargs)
+ recorded_args, recorded_kwargs = self._recorded_calls.pop()
+ pprint(" .verify", recorded_args, recorded_kwargs)
+ return args == recorded_args and kwargs == recorded_kwargs
+
+ def getName(self):
+ return self._method_name
+
+ def getNumberOfInvocations(self):
+ return len(self._recorded_calls)
+
+ def __call__(self, *args, **kwargs):
+ if self._canned_args_set: # replay
+ pprint("MethodMock.__call__ REPLAYING", self.getName(), args, kwargs, "returning", self._canned_response)
+ self._recorded_calls.append((args, kwargs))
+ return self._canned_response
+ else:
+ pprint("MethodMock.__call__ RECORDING", self.getName(), args, kwargs)
+ self._canned_args_set = True
+ self._canned_args = args
+ return self
+
+class given():
+ def __init__(self, mock):
+ pprint("given.__init__")
+ self.target = mock
+
+ def __getattr__(self, *args, **kwargs):
+ pprint("given.__getattr__", args, kwargs)
+ return MethodMock(self.target, args, kwargs)
+
+
+class MethodCallVerifier():
+ def __init__(self, methodMock, times):
+ self.method = methodMock
+ self.times = times
+ def __call__(self, *args, **kwargs):
+ pprint("MethodCallVerifier.__call__", self.method, args, kwargs)
+ # FIXME: verify times times
+ calls = self.method.getNumberOfInvocations()
+ min_calls = self.times.getMinimumNumberOfTimes()
+ max_calls = self.times.getMaximumNumberOfTimes()
+ if calls < min_calls:
+ raise Exception("Expected at least %s calls to %s, got %s" % (min_calls, self.method.getName(), calls))
+ if calls > max_calls:
+ raise Exception("Expected at most %s calls to %s, got %s" % (max_calls, self.method.getName(), calls))
+ if calls == 0:
+ return
+
+ match = self.method.verify(args, kwargs)
+ if match:
+ pprint("Yes, call for", self.method.getName(), "matched arguments", args, kwargs)
+ else:
+ pprint("Nope, call for", self.method.getName(), "didn't match arguments", args, kwargs)
+ raise Exception("mock verification failed")
+
+def empty(*args, **kwargs):
+ pass
+
+class once():
+ def __call__(self):
+ pass
+ def getMinimumNumberOfTimes(self):
+ return 1
+ def getMaximumNumberOfTimes(self):
+ return 1
+
+class never():
+ def __call__(self):
+ pass
+ def getMinimumNumberOfTimes(self):
+ return 0
+ def getMaximumNumberOfTimes(self):
+ return 0
+
+class verify():
+ def __init__(self, mock, times=None):
+ pprint("verify.__init__")
+ self.target = mock
+ self.times = times
+ if self.times is None:
+ self.times = once()
+
+ def __getattr__(self, methodName):
+ pprint("verify.__getattr__", methodName)
+ method_mock = self.target.getMethodMock(methodName)
+ if method_mock is None:
+ if self.times.getMinimumNumberOfTimes() > 0:
+ raise Exception("method " + methodName + " was never called")
+ return empty
+ return MethodCallVerifier(method_mock, self.times)
+
+