vim/sadness/bike/bike/mock.py @ c285337f1a8a
ttytter: add the ttytterrc file
author |
Steve Losh <steve@stevelosh.com> |
date |
Tue, 14 Dec 2010 20:43:02 -0500 |
parents |
cfd5d659d737 |
children |
(none) |
#
# (c) Dave Kirby 2001
# dkirby@bigfoot.com
#
# Call interceptor code by Phil Dawes (pdawes@users.sourceforge.net)
'''
The Mock class emulates any other class for testing purposes.
All method calls are stored for later examination.
The class constructor takes a dictionary of method names and the values
they return. Methods that are not in the dictionary will return None.
'''
import inspect
class Mock:
def __init__(self, returnValues=None ):
self.mockCalledMethods = {}
self.mockAllCalledMethods = []
self.mockReturnValues = returnValues or {}
self.setupMethodInterceptors()
def setupMethodInterceptors(self):
if self.__class__ != Mock: # check we've been subclassed
methods = inspect.getmembers(self.__class__,inspect.ismethod)
for m in methods:
name = m[0]
self.__dict__[name] = MethodCallInterceptor(name,self)
def __getattr__( self, name ):
return MockCaller( name, self )
def getAllCalls(self):
'''return a list of MockCall objects,
representing all the methods in the order they were called'''
return self.mockAllCalledMethods
def getNamedCalls(self, methodName ):
'''return a list of MockCall objects,
representing all the calls to the named method in the order they were called'''
return self.mockCalledMethods.get(methodName, [] )
def assertNamedCall(self,methodName,*args):
# assert call was made once
assert(len(self.getNamedCalls(methodName)) == 1)
# assert args are correct
argsdict = inspect.getargvalues(inspect.currentframe())[3]
i=0
for arg in argsdict['args']:
assert(self.getNamedCalls(methodName)[0].getParam(i) == arg)
i += 1
def assertCallInOrder(self,methodName,*args):
''' Convenience method to allow client to check that calls were
made in the right order. Call once for each methodcall'''
# initialise callIndex. (n.b. __getattr__ method complicates
# this since attrs are MockCaller instances by default)
if type(self.callIndex) != type(1):
self.callIndex=0
call = self.getAllCalls()[self.callIndex]
# assert method name is correct
assert(call.getName() == methodName)
# assert args are correct
argsdict = inspect.getargvalues(inspect.currentframe())[3]
i=0
for arg in argsdict['args']:
assert(call.getParam(i) == arg)
i += 1
# assert num args are correct
assert(call.getNumParams() == i)
self.callIndex += 1
def assertNoMoreCalls(self):
assert(len(self.getAllCalls()) == self.callIndex)
class MockCall:
def __init__(self, name, params, kwparams ):
self.name = name
self.params = params
self.kwparams = kwparams
def getParam( self, n ):
if type(n) == type(1):
return self.params[n]
elif type(n) == type(''):
return self.kwparams[n]
else:
raise IndexError, 'illegal index type for getParam'
def getNumParams(self):
return len(self.params)
def getName(self):
return self.name
#pretty-print the method call
def __str__(self):
s = self.name + "("
sep = ''
for p in self.params:
s = s + sep + repr(p)
sep = ', '
for k,v in self.kwparams.items():
s = s + sep + k+ '='+repr(v)
sep = ', '
s = s + ')'
return s
def __repr__(self):
return self.__str__()
class MockCaller:
def __init__( self, name, mock):
self.name = name
self.mock = mock
def __call__(self, *params, **kwparams ):
self.recordCall(params,kwparams)
return self.mock.mockReturnValues.get(self.name)
def recordCall(self,params,kwparams):
thisCall = MockCall( self.name, params, kwparams )
calls = self.mock.mockCalledMethods.get(self.name, [] )
if calls == []:
self.mock.mockCalledMethods[self.name] = calls
calls.append(thisCall)
self.mock.mockAllCalledMethods.append(thisCall)
# intercepts the call and records it, then delegates to the real call
class MethodCallInterceptor(MockCaller):
def __call__(self, *params, **kwparams ):
self.recordCall(params,kwparams)
return self.makeCall(params)
def makeCall(self,params):
argsstr="(self.mock"
for i in range(len(params)):
argsstr += ",params["+`i`+"]"
argsstr+=")"
return eval("self.mock.__class__."+self.name+argsstr)