-
Notifications
You must be signed in to change notification settings - Fork 140
/
CDRFunctions.m
107 lines (88 loc) · 3.75 KB
/
CDRFunctions.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>
#import "CDRSpec.h"
#import "CDRExampleReporter.h"
#import "CDRDefaultReporter.h"
#import "SpecHelper.h"
BOOL CDRClassIsOfType(Class class, const char * const className) {
if (strcmp(className, class_getName(class))) {
while (class) {
if (class_conformsToProtocol(class, NSProtocolFromString([NSString stringWithCString:className encoding:NSUTF8StringEncoding]))) {
return YES;
}
class = class_getSuperclass(class);
}
}
return NO;
}
NSArray *CDRSelectClasses(BOOL (^classSelectionPredicate)(Class class)) {
unsigned int numberOfClasses = objc_getClassList(NULL, 0);
Class classes[numberOfClasses];
numberOfClasses = objc_getClassList(classes, numberOfClasses);
NSMutableArray *selectedClasses = [NSMutableArray array];
for (unsigned int i = 0; i < numberOfClasses; ++i) {
Class class = classes[i];
if (classSelectionPredicate(class)) {
[selectedClasses addObject:class];
}
}
return selectedClasses;
}
NSArray *CDRCreateRootGroupsFromSpecClasses(NSArray *specClasses) {
NSMutableArray *rootGroups = [[NSMutableArray alloc] initWithCapacity:[specClasses count]];
for (Class class in specClasses) {
CDRSpec *spec = [[class alloc] init];
[spec defineBehaviors];
[rootGroups addObject:spec.rootGroup];
[spec release];
}
return rootGroups;
}
void CDRDefineSharedExampleGroups() {
NSArray *sharedExampleGroupPoolClasses = CDRSelectClasses(^(Class class) { return CDRClassIsOfType(class, "CDRSharedExampleGroupPool"); });
for (Class class in sharedExampleGroupPoolClasses) {
CDRSharedExampleGroupPool *sharedExampleGroupPool = [[class alloc] init];
[sharedExampleGroupPool declareSharedExampleGroups];
[sharedExampleGroupPool release];
}
}
void CDRDefineGlobalBeforeAndAfterEachBlocks() {
[SpecHelper specHelper].globalBeforeEachClasses = CDRSelectClasses(^BOOL(Class class) { return !!class_getClassMethod(class, @selector(beforeEach)); });
[SpecHelper specHelper].globalAfterEachClasses = CDRSelectClasses(^BOOL(Class class) { return !!class_getClassMethod(class, @selector(afterEach)); });
}
int runSpecsWithCustomExampleReporter(NSArray *specClasses, id<CDRExampleReporter> reporter) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (!specClasses) {
specClasses = CDRSelectClasses(^(Class class) { return CDRClassIsOfType(class, "CDRSpec"); });
}
CDRDefineSharedExampleGroups();
CDRDefineGlobalBeforeAndAfterEachBlocks();
NSArray *groups = CDRCreateRootGroupsFromSpecClasses(specClasses);
for (CDRExampleGroup *group in groups) {
[SpecHelper specHelper].shouldOnlyRunFocused |= [group hasFocusedExamples];
}
[reporter runWillStartWithGroups:groups];
[groups makeObjectsPerformSelector:@selector(run)];
[reporter runDidComplete];
int result = [reporter result];
[groups release];
[pool drain];
return result;
}
int runAllSpecs() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
char *reporterClassName = getenv("CEDAR_REPORTER_CLASS");
if (!reporterClassName) {
reporterClassName = "CDRDefaultReporter";
}
Class reporterClass = NSClassFromString([NSString stringWithCString:reporterClassName encoding:NSUTF8StringEncoding]);
if (!reporterClass) {
printf("***** The specified reporter class \"%s\" does not exist. *****\n", reporterClassName);
return -999;
}
id<CDRExampleReporter> reporter = [[[reporterClass alloc] init] autorelease];
int result = runSpecsWithCustomExampleReporter(NULL, reporter);
[pool drain];
return result;
}