PageRenderTime 12ms CodeModel.GetById 2ms app.highlight 4ms RepoModel.GetById 2ms app.codeStats 0ms

/Frameworks/OJMoq/OJMoq.j

http://github.com/hammerdr/OJTest
Unknown | 307 lines | 270 code | 37 blank | 0 comment | 0 complexity | f8698a52275ba3d30b398768dbf82e4d MD5 | raw file
  1@import <Foundation/CPObject.j>
  2@import "OJMoqSelector.j"
  3@import "CPInvocation+Arguments.j"
  4@import "OJMoqAssert.j"
  5
  6var DEPRECATED_METHOD = "%@ is deprecated and will be removed in a future release. Please use %@. Thanks!";
  7
  8// Create a mock object based on a given object.
  9function moq(baseObject)
 10{
 11    if(!baseObject)
 12    {
 13        baseObject = nil;
 14    }
 15       
 16	return [OJMoq mockBaseObject:baseObject];
 17}
 18
 19/*!
 20 * A mocking library for Cappuccino applications
 21 */
 22@implementation OJMoq : CPObject
 23{
 24	CPObject	_baseObject		@accessors(readonly);
 25	CPArray		selectors;
 26	CPArray		expectations;
 27}
 28
 29/*!
 30    Creates an OJMoq object based on the base object. If the base object is nil, then a benign
 31    stub is created. If the base object is non-nil, it creates a spy mock that allows all of
 32    the messages to go through to the base object.
 33    
 34    \param aBaseObject A nil or non-nil base object that will be wrapped by OJMoq
 35    \returns An instance of OJMoq that wraps the given base object
 36 */
 37+ (id)mockBaseObject:(CPObject)aBaseObject
 38{
 39	return [[OJMoq alloc] initWithBaseObject:aBaseObject];
 40}
 41
 42
 43/*!
 44   Creates an OJMoq object based on the base object. If the base object is nil, then a benign
 45   stub is created. If the base object is non-nil, it creates a spy mock that allows all of
 46   the messages to go through to the base object.
 47   
 48   \param aBaseObject A nil or non-nil base object that will be wrapped by OJMoq
 49   \returns An instance of OJMoq that wraps the given base object
 50 */
 51- (id)initWithBaseObject:(CPObject)aBaseObject
 52{
 53	if(self = [super init])
 54	{
 55		_baseObject = aBaseObject;
 56		expectations = [[CPArray alloc] init];
 57		selectors = [[CPArray alloc] init];
 58	}
 59	return self;
 60}
 61
 62/*!
 63   **DEPRECATED**
 64   @param selector The selector which should be called
 65   @param times The number of times that selector should be called
 66 */
 67- (OJMoq)expectSelector:(SEL)selector times:(int)times
 68{
 69    CPLog.warn([[CPString alloc] initWithFormat:DEPRECATED_METHOD, @"expectSelector:times:", @"selector:times:"]);
 70	return [self selector:selector times:times arguments:[CPArray array]];
 71}
 72
 73/*!
 74   **DEPRECATED**
 75   @param selector The selector which should be called
 76   @param times The number of times that selector should be called
 77   @param arguments Arguments for the selector. If an empty array of arguments is passed in, 
 78        then the selector matches all arguments.
 79 */
 80- (OJMoq)expectSelector:(SEL)selector times:(int)times arguments:(CPArray)arguments
 81{
 82    CPLog.warn([[CPString alloc] initWithFormat:DEPRECATED_METHOD, @"expectSelector:times:arguments:", @"selector:times:arguments:"]);
 83    [self selector:selector times:times arguments:[CPArray array]];
 84}
 85
 86/*!
 87   Expect that selector is called times on the base object. The selector here will match all
 88     arguments.
 89   @param selector The selector which should be called
 90   @param times The number of times that selector should be called
 91 */
 92- (OJMoq)selector:(SEL)selector times:(CPNumber)times
 93{
 94    [self selector:selector times:times arguments:[CPArray array]];
 95}
 96 
 97/*!
 98   Expect that selector is called times with arguments on the base object. The selector here
 99     will match the arguments that you pass it. If an empty array is passed then the selector
100     will match all arguments!
101
102     @param selector The selector which should be called
103     @param times The number of times that selector should be called
104     @param arguments Arguments for the selector. If an empty array of arguments is passed in, 
105          then the selector matches all arguments.
106 */
107- (OJMoq)selector:(SEL)selector times:(CPNumber)times arguments:(CPArray)arguments   
108{
109    var theSelector = __ojmoq_findSelector(aSelector, arguments, selectors);
110    if(theSelector)
111    {
112    	var expectationFunction = function(){[OJMoqAssert selector:theSelector hasBeenCalled:times];};
113        [expectations addObject:expectationFunction];
114    }
115    else
116    {
117    	var aSelector = [[OJMoqSelector alloc] initWithName:sel_getName(selector) withArguments:arguments];
118    	var expectationFunction = function(){[OJMoqAssert selector:aSelector hasBeenCalled:times];};
119        [expectations addObject:expectationFunction];
120    	[selectors addObject:aSelector];
121    }
122	return self;
123}
124
125/*!
126   Ensure that selector returns value when selector is called. Selector will match all arguments.
127   @param aSelector The selector on the base object that will be called
128   @param value The value that the selector should return
129 */
130- (OJMoq)selector:(SEL)aSelector returns:(CPObject)value
131{
132	[self selector:aSelector returns:value arguments:[CPArray array]];
133}
134
135/*!
136   DEPRECATED
137   @param aSelector The selector on the base object that will be called
138   @param arguments The arguments that must be passed to selector for this to work
139   @param value The value that the selector should return
140 */
141- (OJMoq)selector:(SEL)aSelector withArguments:(CPArray)arguments returns:(CPObject)value
142{
143    CPLog.warn([[CPString alloc] initWithFormat:DEPRECATED_METHOD, @"selector:withArguments:returns:", @"selector:returns:arguments:"]);
144    [self selector:aSelector returns:value arguments:arguments];
145}
146
147/*!
148   Ensure that the selector, when called with the specified arguments, will return the given
149     value. If you pass an empty array of arguments, then the selector will match all calls.
150     
151     @param aSelector The selector on the base object that will be called
152     @param arguments The arguments that must be passed to selector for this to work
153     @param value The value that the selector should return
154 */
155- (OJMoq)selector:(SEL)aSelector returns:(CPObject)value arguments:(CPArray)arguments
156{
157    var theSelector = __ojmoq_findSelector(aSelector, arguments, selectors);
158	if(theSelector)
159	{
160		[theSelector setReturnValue:value];
161	}
162	else
163	{
164		var aNewSelector = [[OJMoqSelector alloc] initWithName:sel_getName(aSelector) withArguments:arguments];
165		[aNewSelector setReturnValue:value];
166		[selectors addObject:aNewSelector];
167	}
168	
169	return self;
170}
171
172/*!
173   Provides a callback with the parameters that were passed in to the specified selector
174   
175   @param aSelector The selector on the base object that will be called
176   @param aCallback A single-argument function that is passed the array of arguments
177 */
178- (OJMoq)selector:(SEL)aSelector callback:(Function)aCallback
179{
180    [self selector:aSelector callback:aCallback arguments:[CPArray array]];
181}
182
183/*!
184   Provides a callback with the parameters that were passed in to the specified selector and
185      match the given arguments
186
187      @param aSelector The selector on the base object that will be called
188      @param aCallback A single-argument function that is passed the array of arguments
189      @param arguments The arguments that the selector must match
190 */
191- (OJMoq)selector:(SEL)aSelector callback:(Function)aCallback arguments:(CPArray)arguments
192{
193    var theSelector = __ojmoq_findSelector(aSelector, arguments, selectors);
194    
195    if(theSelector)
196    {
197        [theSelector setCallback:aCallback];
198    }
199    else
200    {
201        var aNewSelector = [[OJMoqSelector alloc] initWithName:sel_getName(aSelector) withArguments:arguments];
202        [aNewSelector setCallback:aCallback];
203        [selectors addObject:aNewSelector];
204    }
205}
206
207/*!
208   Verifies all of the expectations that were set on the OJMoq and fails the test if any of
209     the expectations fail.
210 */
211- (OJMoq)verifyThatAllExpectationsHaveBeenMet
212{
213	for(var i = 0; i < [expectations count]; i++)
214	{
215		expectations[i]();
216	}
217	
218	return self;
219}
220
221// Ignore the following interface unless you know what you are doing! 
222// These are here to intercept calls to the underlying object and 
223// should be handled automatically.
224
225/*!
226   @ignore
227 */
228- (CPMethodSignature)methodSignatureForSelector:(SEL)aSelector
229{
230	return YES;
231}
232
233/* @ignore */
234- (void)forwardInvocation:(CPInvocation)anInvocation
235{		
236    var selector = __ojmoq_findSelectorFromInvocation(anInvocation, selectors);
237	__ojmoq_incrementNumberOfCalls(anInvocation, selectors);
238	
239	if(_baseObject !== nil && !selector)
240	{
241	    return [anInvocation invokeWithTarget:_baseObject];
242	}
243	else
244	{
245		__ojmoq_setReturnValue(anInvocation, selectors);
246		__ojmoq_startCallback(anInvocation, selectors);
247	}
248}
249
250/*!
251   @ignore
252 */
253- (BOOL)respondsToSelector:(SEL)aSelector
254{
255    return __ojmoq_findSelector(aSelector, [CPArray array], selectors);
256}
257
258@end
259
260function __ojmoq_findSelector(selector, selectorArguments, selectors)
261{
262    return [OJMoqSelector find:[[OJMoqSelector alloc] initWithName:sel_getName(selector)
263        withArguments:selectorArguments] in:selectors];
264}
265
266function __ojmoq_findSelectorFromInvocation(anInvocation, selectors)
267{
268    return __ojmoq_findSelector([anInvocation selector], [anInvocation userArguments], selectors);
269}
270
271function __ojmoq_incrementNumberOfCalls(anInvocation, selectors)
272{
273	var theSelector = __ojmoq_findSelectorFromInvocation(anInvocation, selectors);
274	if(theSelector)
275	{
276		[theSelector call];
277	}
278    else
279    {
280        var aNewSelector = [[OJMoqSelector alloc] initWithName:sel_getName([anInvocation selector]) 
281            withArguments:[anInvocation userArguments]];
282        [aNewSelector call];
283        [selectors addObject:aNewSelector];
284    }
285}
286
287function __ojmoq_setReturnValue(anInvocation, selectors)
288{
289    var theSelector = __ojmoq_findSelectorFromInvocation(anInvocation, selectors);
290	if(theSelector)
291	{
292		[anInvocation setReturnValue:[theSelector returnValue]];
293	}
294	else
295	{
296		[anInvocation setReturnValue:[[CPObject alloc] init]];
297	}
298}
299
300function __ojmoq_startCallback(anInvocation, selectors)
301{
302    var theSelector = __ojmoq_findSelectorFromInvocation(anInvocation, selectors);
303	if(theSelector)
304	{
305		[theSelector callback]([anInvocation userArguments]);
306	}
307}