5 // Created by Wincent Colaiuta on 10 February 2006.
7 // Copyright 2006-2007 Wincent Colaiuta.
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #import "WOObjectStub.h"
27 #import "NSInvocation+WOTest.h"
28 #import "NSObject+WOTest.h"
30 @implementation WOObjectStub
35 + (id)stubForClass:(Class)aClass withDelegate:(id)aDelegate
37 NSParameterAssert(aClass != NULL);
38 return [[self alloc] initWithClass:aClass delegate:aDelegate];
41 - (id)initWithClass:(Class)aClass delegate:(id)aDelegate
43 NSParameterAssert(aClass != NULL);
44 if ((self = [super init]))
55 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
57 // avoid an infinite loop (docs warn "Be sure to avoid an infinite loop when necessary by checking that aSelector isn't the
58 // selector for this method itself and by not sending any message that might invoke this method.")
59 if (([self mockedClass] == [self class]) && (aSelector == _cmd)) return nil;
61 // see if method really exists in mocked class, if not forward:: will have to do something special
62 return [[self mockedClass] instanceMethodSignatureForSelector:aSelector];
66 #pragma mark NSObject protocol
68 - (BOOL)isEqual:(id)anObject
70 if (anObject == self) return YES;
73 if ([NSObject WOTest_object:anObject isKindOfClass:[self class]])
75 BOOL invocationsAreEqual = NO;
76 BOOL returnValuesAreEqual = NO;
77 BOOL exceptionsAreEqual = NO;
78 NSInvocation *thisInvocation = [self invocation];
79 NSInvocation *otherInvocation = [anObject invocation];
80 NSValue *thisValue = [self returnValue];
81 NSValue *otherValue = [anObject returnValue];
82 id thisException = [self exception];
83 id otherException = [anObject exception];
85 if ([self mockedClass] != [anObject mockedClass])
88 if ([self acceptsAnyArguments] != [anObject acceptsAnyArguments])
91 if (!thisInvocation && !otherInvocation) // both nil
92 invocationsAreEqual = YES;
93 else if (thisInvocation && otherInvocation) // both non-nil
95 if ([self acceptsAnyArguments])
96 invocationsAreEqual = [thisInvocation WOTest_isEqualToInvocationIgnoringArguments:otherInvocation];
98 invocationsAreEqual = [thisInvocation WOTest_isEqualToInvocation:otherInvocation];
101 if (!thisValue && !otherValue) // both nil
102 returnValuesAreEqual = YES;
103 else if (thisValue && otherValue) // both non-nil
104 returnValuesAreEqual = [thisValue isEqual:otherValue];
106 if (!thisException && !otherException) // both nil
107 exceptionsAreEqual = YES;
108 else if (thisException && otherException) // both non-nil
109 exceptionsAreEqual = [thisException isEqual:otherException];
111 if (invocationsAreEqual && returnValuesAreEqual &&
122 // hash must not rely on the object's internal state information (see docs)
123 // hash must not change while in a collection
124 return (unsigned)mockedClass;
128 #pragma mark Accessors