75 lines
2.8 KiB
Objective-C
75 lines
2.8 KiB
Objective-C
#import "EXPExpect.h"
|
|
#import "EXPBlockDefinedMatcher.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
id _EXPObjectify(const char *type, ...);
|
|
EXPExpect *_EXP_expect(id testCase, int lineNumber, const char *fileName, EXPIdBlock actualBlock);
|
|
|
|
void EXPFail(id testCase, int lineNumber, const char *fileName, NSString *message);
|
|
NSString *EXPDescribeObject(id obj);
|
|
|
|
void EXP_prerequisite(EXPBoolBlock block);
|
|
void EXP_match(EXPBoolBlock block);
|
|
void EXP_failureMessageForTo(EXPStringBlock block);
|
|
void EXP_failureMessageForNotTo(EXPStringBlock block);
|
|
|
|
#if __has_feature(objc_arc)
|
|
#define _EXP_release(x)
|
|
#define _EXP_autorelease(x) (x)
|
|
|
|
#else
|
|
#define _EXP_release(x) [x release]
|
|
#define _EXP_autorelease(x) [x autorelease]
|
|
#endif
|
|
|
|
// workaround for the categories bug: http://developer.apple.com/library/mac/#qa/qa1490/_index.html
|
|
#define EXPFixCategoriesBug(name) \
|
|
__attribute__((constructor)) static void EXPFixCategoriesBug##name() {}
|
|
|
|
#define _EXPMatcherInterface(matcherName, matcherArguments) \
|
|
@interface EXPExpect (matcherName##Matcher) \
|
|
@property (nonatomic, readonly) void(^ matcherName) matcherArguments; \
|
|
@end
|
|
|
|
#define _EXPMatcherImplementationBegin(matcherName, matcherArguments) \
|
|
EXPFixCategoriesBug(EXPMatcher##matcherName##Matcher); \
|
|
@implementation EXPExpect (matcherName##Matcher) \
|
|
@dynamic matcherName;\
|
|
- (void(^) matcherArguments) matcherName { \
|
|
EXPBlockDefinedMatcher *matcher = [[EXPBlockDefinedMatcher alloc] init]; \
|
|
[[[NSThread currentThread] threadDictionary] setObject:matcher forKey:@"EXP_currentMatcher"]; \
|
|
__block id actual = self.actual; \
|
|
__block void (^prerequisite)(EXPBoolBlock block) = ^(EXPBoolBlock block) { EXP_prerequisite(block); }; \
|
|
__block void (^match)(EXPBoolBlock block) = ^(EXPBoolBlock block) { EXP_match(block); }; \
|
|
__block void (^failureMessageForTo)(EXPStringBlock block) = ^(EXPStringBlock block) { EXP_failureMessageForTo(block); }; \
|
|
__block void (^failureMessageForNotTo)(EXPStringBlock block) = ^(EXPStringBlock block) { EXP_failureMessageForNotTo(block); }; \
|
|
prerequisite(nil); match(nil); failureMessageForTo(nil); failureMessageForNotTo(nil); \
|
|
void (^matcherBlock) matcherArguments = [^ matcherArguments { \
|
|
{
|
|
|
|
#define _EXPMatcherImplementationEnd \
|
|
} \
|
|
[self applyMatcher:matcher to:&actual]; \
|
|
[[[NSThread currentThread] threadDictionary] removeObjectForKey:@"EXP_currentMatcher"]; \
|
|
} copy]; \
|
|
_EXP_release(matcher); \
|
|
return _EXP_autorelease(matcherBlock); \
|
|
} \
|
|
@end
|
|
|
|
#define _EXPMatcherAliasImplementation(newMatcherName, oldMatcherName, matcherArguments) \
|
|
EXPFixCategoriesBug(EXPMatcher##newMatcherName##Matcher); \
|
|
@implementation EXPExpect (newMatcherName##Matcher) \
|
|
@dynamic newMatcherName;\
|
|
- (void(^) matcherArguments) newMatcherName { \
|
|
return [self oldMatcherName]; \
|
|
}\
|
|
@end
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|