Frameworks/OJMoq/OJMoq.j
Go to the documentation of this file.

    00001 @import <Foundation/CPObject.j>
    00002 @import "OJMoqSelector.j"
    00003 @import "CPInvocation+Arguments.j"
    00004 @import "OJMoqAssert.j"
    00005
    00006 // New stuff
    00007 @import "OJMoqMock.j"
    00008 @import "OJMoqSpy.j"
    00009 @import "OJMoqStub.j"
    00010
    00011 var DEPRECATED_METHOD = "%@ is deprecated and will be removed in a future release. Please use %@. Thanks!";
    00012
    00013 // Create a mock object based on a given object.
    00014 function moq(baseObject)
    00015 {
    00016     if(!baseObject)
    00017     {
    00018         baseObject = nil;
    00019     }
    00020
    00021     return [OJMoq mockBaseObject:baseObject];
    00022 }
    00023
    00027 @implementation OJMoq : CPObject
    00028 {
    00029     CPObject    _baseObject             @accessors(readonly);
    00030     CPArray     selectors;
    00031     CPArray     expectations;
    00032 }
    00033
    00042 + (id)mockBaseObject:(CPObject)aBaseObject
    00043 {
    00044     return [[OJMoq alloc] initWithBaseObject:aBaseObject];
    00045 }
    00046
    00047
    00056 - (id)initWithBaseObject:(CPObject)aBaseObject
    00057 {
    00058     if(self = [super init])
    00059     {
    00060         _baseObject = aBaseObject;
    00061         expectations = [[CPArray alloc] init];
    00062         selectors = [[CPArray alloc] init];
    00063     }
    00064     return self;
    00065 }
    00066
    00073 - (OJMoq)selector:(SEL)selector times:(CPNumber)times
    00074 {
    00075     [self selector:selector times:times arguments:[CPArray array]];
    00076 }
    00077
    00088 - (OJMoq)selector:(SEL)selector times:(CPNumber)times arguments:(CPArray)arguments
    00089 {
    00090     theSelector = __ojmoq_findUniqueSelector(selector, arguments, selectors);
    00091     if(theSelector)
    00092     {
    00093         var expectationFunction = function(){[OJMoqAssert selector:theSelector hasBeenCalled:times];};
    00094         [expectations addObject:expectationFunction];
    00095     }
    00096     else
    00097     {
    00098         var aSelector = [[OJMoqSelector alloc] initWithName:sel_getName(selector) withArguments:arguments];
    00099         var expectationFunction = function(){[OJMoqAssert selector:aSelector hasBeenCalled:times];};
    00100         [expectations addObject:expectationFunction];
    00101         [selectors addObject:aSelector];
    00102     }
    00103     return self;
    00104 }
    00105
    00111 - (OJMoq)selector:(SEL)aSelector returns:(CPObject)value
    00112 {
    00113     [self selector:aSelector returns:value arguments:[CPArray array]];
    00114 }
    00115
    00124 - (OJMoq)selector:(SEL)aSelector returns:(CPObject)value arguments:(CPArray)arguments
    00125 {
    00126     var theSelector = __ojmoq_findUniqueSelector(aSelector, arguments, selectors);
    00127     if(theSelector)
    00128     {
    00129         [theSelector setReturnValue:value];
    00130     }
    00131     else
    00132     {
    00133         var aNewSelector = [[OJMoqSelector alloc] initWithName:sel_getName(aSelector) withArguments:arguments];
    00134         [aNewSelector setReturnValue:value];
    00135         [selectors addObject:aNewSelector];
    00136     }
    00137     return self;
    00138 }
    00139
    00146 - (OJMoq)selector:(SEL)aSelector callback:(Function)aCallback
    00147 {
    00148     [self selector:aSelector callback:aCallback arguments:[CPArray array]];
    00149 }
    00150
    00159 - (OJMoq)selector:(SEL)aSelector callback:(Function)aCallback arguments:(CPArray)arguments
    00160 {
    00161     var theSelector = __ojmoq_findUniqueSelector(aSelector, arguments, selectors);
    00162
    00163     if(theSelector)
    00164     {
    00165         [theSelector setCallback:aCallback];
    00166     }
    00167     else
    00168     {
    00169         var aNewSelector = [[OJMoqSelector alloc] initWithName:sel_getName(aSelector) withArguments:arguments];
    00170         [aNewSelector setCallback:aCallback];
    00171         [selectors addObject:aNewSelector];
    00172     }
    00173 }
    00174
    00179 - (OJMoq)verifyThatAllExpectationsHaveBeenMet
    00180 {
    00181     for(var i = 0; i < [expectations count]; i++)
    00182     {
    00183         expectations[i]();
    00184     }
    00185
    00186     return self;
    00187 }
    00188
    00189 // Ignore the following interface unless you know what you are doing!
    00190 // These are here to intercept calls to the underlying object and
    00191 // should be handled automatically.
    00192
    00196 - (CPMethodSignature)methodSignatureForSelector:(SEL)aSelector
    00197 {
    00198     return YES;
    00199 }
    00200
    00201 /* @ignore */
    00202 - (void)forwardInvocation:(CPInvocation)anInvocation
    00203 {
    00204     var theSelector = __ojmoq_findSelectorFromInvocation(anInvocation, selectors);
    00205     __ojmoq_incrementNumberOfCalls(anInvocation, selectors);
    00206
    00207         // We forward to the baseObject when:
    00208         // 1. A baseObject exists and
    00209         // 2. No one has added this selector to our selector list or it is a selector the baseobject responds to and no one has tried
    00210         //    to override the baseObject's implementation
    00211     if (_baseObject !== nil &&
    00212         (!theSelector || ([_baseObject respondsToSelector:CPSelectorFromString([theSelector name])]
    00213         && ([theSelector returnValue] === undefined && [theSelector callback] === undefined))))
    00214     {
    00215         return [anInvocation invokeWithTarget:_baseObject];
    00216     }
    00217     else
    00218     {
    00219         __ojmoq_setReturnValue(anInvocation, selectors);
    00220         __ojmoq_startCallback(anInvocation, selectors);
    00221     }
    00222 }
    00223
    00227 - (BOOL)respondsToSelector:(SEL)aSelector
    00228 {
    00229     return [__ojmoq_findSelectors(aSelector, [CPArray array], selectors, NO) count] > 0;
    00230 }
    00231
    00232 @end
    00233
    00234 function __ojmoq_findUniqueSelector(selector, selectorArguments, selectors)
    00235 {
    00236     var foundSelectors = __ojmoq_findSelectors(selector, selectorArguments, selectors, YES);
    00237     if ([foundSelectors count] > 1)
    00238         [CPException raise:CPInternalInconsistencyException reason:"Multiple selectors found with the exact same name and arguments"];
    00239     else if ([foundSelectors count] === 1)
    00240         return foundSelectors[0];
    00241     else
    00242         return nil;
    00243 }
    00244
    00245 function __ojmoq_findSelectors(selector, selectorArguments, selectors, shouldIgnoreWildcards)
    00246 {
    00247     return [OJMoqSelector find:[[OJMoqSelector alloc] initWithName:sel_getName(selector)
    00248                                                      withArguments:selectorArguments] in:selectors ignoreWildcards:shouldIgnoreWildcards];
    00249 }
    00250
    00251 function __ojmoq_findSelectorFromInvocation(anInvocation, selectors)
    00252 {
    00253     var foundSelectors = __ojmoq_findSelectors([anInvocation selector], [anInvocation userArguments], selectors, NO);
    00254     // We don't find the unique selector first, since if you did [mock selector:@selector(aSelector:) returns:5],
    00255     // doing [mock aSelector:5] should still return the selector you set up
    00256     if ([foundSelectors count] === 1)
    00257         return foundSelectors[0];
    00258     else if ([foundSelectors count] === 0)
    00259         return nil;
    00260     // More than one selector found - for example, if you did [mock selector:@selector(aSelector:) returns:5] and
    00261     // [mock selector:@selector(aSelector:) returns:6 arguments:[5]] and then call [mock aSelector:5];, should only
    00262     // call the selector that was set up with args.
    00263     else
    00264         return __ojmoq_findUniqueSelector([anInvocation selector], [anInvocation userArguments], selectors);
    00265 }
    00266
    00267 function __ojmoq_incrementNumberOfCalls(anInvocation, selectors)
    00268 {
    00269     var foundSelectors = __ojmoq_findSelectors([anInvocation selector], [anInvocation userArguments], selectors, NO),
    00270         count = [foundSelectors count];
    00271
    00272     while (count--)
    00273         [foundSelectors[count] call];
    00274
    00275     // Make sure we didn't just find the wildcard selector and increment only that.
    00276     // Taking this out for now - it causes this bug: https://github.com/280north/OJTest/issues#issue/3
    00277 //     var uniqueSelector = __ojmoq_findUniqueSelector([anInvocation selector], [anInvocation userArguments], selectors);
    00278 //     if (!uniqueSelector)
    00279 //     {
    00280 //         var aNewSelector = [[OJMoqSelector alloc] initWithName:sel_getName([anInvocation selector])
    00281 //                                                  withArguments:[anInvocation userArguments]];
    00282 //         [aNewSelector call];
    00283 //         [selectors addObject:aNewSelector];
    00284 //     }
    00285 }
    00286
    00287 function __ojmoq_setReturnValue(anInvocation, selectors)
    00288 {
    00289     var theSelector = __ojmoq_findSelectorFromInvocation(anInvocation, selectors);
    00290     if(theSelector)
    00291     {
    00292         [anInvocation setReturnValue:[theSelector returnValue]];
    00293     }
    00294     else
    00295     {
    00296         [anInvocation setReturnValue:[[CPObject alloc] init]];
    00297     }
    00298 }
    00299
    00300 function __ojmoq_startCallback(anInvocation, selectors)
    00301 {
    00302     var theSelector = __ojmoq_findSelectorFromInvocation(anInvocation, selectors);
    00303     if(theSelector && [theSelector callback] !== undefined)
    00304     {
    00305         [theSelector callback]([anInvocation userArguments]);
    00306     }
    00307 }
    00308

All Classes Files Functions Variables