main
  1//
  2// Licensed under the terms in License.txt
  3//
  4// Copyright 2010 Allen Ding. All rights reserved.
  5//
  6
  7#import "KWExampleGroupBuilder.h"
  8#import "KWExample.h"
  9#import "KWAfterAllNode.h"
 10#import "KWAfterEachNode.h"
 11#import "KWBeforeAllNode.h"
 12#import "KWBeforeEachNode.h"
 13#import "KWContextNode.h"
 14#import "KWItNode.h"
 15#import "KWPendingNode.h"
 16#import "KWRegisterMatchersNode.h"
 17#import "KWExampleSuite.h"
 18
 19
 20@interface KWExampleGroupBuilder()
 21
 22#pragma mark -
 23#pragma mark Building Example Groups
 24
 25@property (nonatomic, retain, readwrite) KWExampleSuite *exampleSuite;
 26@property (nonatomic, readonly) NSMutableArray *contextNodeStack;
 27
 28@end
 29
 30@implementation KWExampleGroupBuilder
 31
 32@synthesize exampleSuite;
 33@synthesize currentExample;
 34
 35#pragma mark -
 36#pragma mark Initializing
 37
 38static KWExampleGroupBuilder *sharedExampleGroupBuilder = nil;
 39
 40- (id)init {
 41    if ((self = [super init])) {
 42        contextNodeStack = [[NSMutableArray alloc] init];
 43        suites = [[NSMutableSet alloc] init];
 44    }
 45
 46    return self;
 47}
 48
 49- (void)dealloc {
 50    [suites release];
 51    [exampleSuite release];
 52    [contextNodeStack release];
 53    [super dealloc];
 54}
 55
 56+ (id)sharedExampleGroupBuilder {
 57    if (sharedExampleGroupBuilder == nil) {
 58        sharedExampleGroupBuilder = [[super allocWithZone:nil] init];
 59    }
 60
 61    return sharedExampleGroupBuilder;
 62}
 63
 64+ (id)allocWithZone:(NSZone *)zone {
 65    return [[self sharedExampleGroupBuilder] retain];
 66}
 67
 68- (id)copyWithZone:(NSZone *)zone {
 69    return self;
 70}
 71
 72- (id)retain {
 73    return self;
 74}
 75
 76- (NSUInteger)retainCount {
 77    return NSUIntegerMax;
 78}
 79
 80- (oneway void)release {
 81}
 82
 83- (id)autorelease {
 84    return self;
 85}
 86
 87#pragma mark -
 88#pragma mark Building Example Groups
 89
 90@synthesize contextNodeStack;
 91
 92- (BOOL)isBuildingExampleGroup {
 93    return [self.contextNodeStack count] > 0;
 94}
 95
 96- (KWExampleSuite *)buildExampleGroups:(void (^)(void))buildingBlock
 97{
 98    KWContextNode *rootNode = [KWContextNode contextNodeWithCallSite:nil parentContext:nil description:nil];
 99   
100    self.exampleSuite = [[[KWExampleSuite alloc] initWithRootNode:rootNode] autorelease];
101    
102    [suites addObject:self.exampleSuite];
103
104    [self.contextNodeStack addObject:rootNode];
105    buildingBlock();
106    [self.contextNodeStack removeAllObjects];
107    
108    return self.exampleSuite;
109}
110
111- (void)pushContextNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription {
112    KWContextNode *contextNode = [self.contextNodeStack lastObject];
113    KWContextNode *node = [KWContextNode contextNodeWithCallSite:aCallSite parentContext:contextNode description:aDescription];
114    [contextNode addContextNode:node];
115    [self.contextNodeStack addObject:node];
116}
117
118- (void)popContextNode {
119    KWContextNode *contextNode = [self.contextNodeStack lastObject];
120    
121    [self.exampleSuite markLastExampleAsLastInContext:contextNode];
122    
123    if ([self.contextNodeStack count] == 1)
124        [NSException raise:@"KWExampleGroupBuilderException" format:@"there is no open context to pop"];
125
126    [self.contextNodeStack removeLastObject];
127}
128
129- (void)setRegisterMatchersNodeWithCallSite:(KWCallSite *)aCallSite namespacePrefix:(NSString *)aNamespacePrefix {
130    if ([self.contextNodeStack count] == 0)
131        [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"];
132
133    KWContextNode *contextNode = [self.contextNodeStack lastObject];
134    KWRegisterMatchersNode *registerMatchersNode = [KWRegisterMatchersNode registerMatchersNodeWithCallSite:aCallSite namespacePrefix:aNamespacePrefix];
135    [contextNode setRegisterMatchersNode:registerMatchersNode];
136}
137
138- (void)setBeforeAllNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock {
139    if ([self.contextNodeStack count] == 0)
140        [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"];
141
142    KWContextNode *contextNode = [self.contextNodeStack lastObject];
143    KWBeforeAllNode *beforeAllNode = [KWBeforeAllNode beforeAllNodeWithCallSite:aCallSite block:aBlock];
144    [contextNode setBeforeAllNode:beforeAllNode];
145}
146
147- (void)setAfterAllNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock {
148    if ([self.contextNodeStack count] == 0)
149        [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"];
150
151    KWContextNode *contextNode = [self.contextNodeStack lastObject];
152    KWAfterAllNode *afterAllNode = [KWAfterAllNode afterAllNodeWithCallSite:aCallSite block:aBlock];
153    [contextNode setAfterAllNode:afterAllNode];
154}
155
156- (void)setBeforeEachNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock {
157    if ([self.contextNodeStack count] == 0)
158        [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"];
159
160    KWContextNode *contextNode = [self.contextNodeStack lastObject];
161    KWBeforeEachNode *beforeEachNode = [KWBeforeEachNode beforeEachNodeWithCallSite:aCallSite block:aBlock];
162    [contextNode setBeforeEachNode:beforeEachNode];
163}
164
165- (void)setAfterEachNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock {
166    if ([self.contextNodeStack count] == 0)
167        [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"];
168
169    KWContextNode *contextNode = [self.contextNodeStack lastObject];
170    KWAfterEachNode *afterEachNode = [KWAfterEachNode afterEachNodeWithCallSite:aCallSite block:aBlock];
171    [contextNode setAfterEachNode:afterEachNode];
172}
173
174- (void)addItNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription block:(KWVoidBlock)aBlock {
175    if ([self.contextNodeStack count] == 0)
176        [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"];
177
178    KWContextNode *contextNode = [self.contextNodeStack lastObject];
179    KWItNode* itNode = [KWItNode itNodeWithCallSite:aCallSite description:aDescription context:contextNode block:aBlock];
180    [contextNode addItNode:itNode];
181    
182    KWExample *example = [[KWExample alloc] initWithExampleNode:itNode];
183    [self.exampleSuite addExample:example];
184    [example release];
185}
186
187- (void)addPendingNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription {
188    if ([self.contextNodeStack count] == 0)
189        [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"];
190
191    KWContextNode *contextNode = [self.contextNodeStack lastObject];
192    KWPendingNode *pendingNode = [KWPendingNode pendingNodeWithCallSite:aCallSite context:contextNode description:aDescription];
193    [contextNode addPendingNode:pendingNode];
194    
195    KWExample *example = [[KWExample alloc] initWithExampleNode:pendingNode];
196    [self.exampleSuite addExample:example];
197    [example release];
198}
199
200@end