Permalink
Browse files

WIP: fix for issue #64, ensuring beforeAll and afterAll work as expec…

…ted.
  • Loading branch information...
1 parent 4e47c33 commit 51ad11fe3b0f40acea8c6819629d6a23c5405d5a @lukeredpath lukeredpath committed Oct 18, 2011
View
@@ -37,4 +37,21 @@
});
});
+describe(@"beforeAll", ^{
+ __block NSInteger calls = 0;
+
+ beforeAll(^{
+ calls++;
+ });
+
+ it(@"will be called before this spec", ^{
+ [[theValue(calls) should] equal:theValue(1)];
+ });
+
+ it(@"will not be called again before this spec", ^{
+ [[theValue(calls) should] equal:theValue(1)];
+ });
+
+});
+
SPEC_END
@@ -113,6 +113,8 @@
A3B1655D1399694900E9CC6E /* SpaceShip.m in Sources */ = {isa = PBXBuildFile; fileRef = F59E248A1188177800D008C2 /* SpaceShip.m */; };
A3B1655E1399694900E9CC6E /* Robot.m in Sources */ = {isa = PBXBuildFile; fileRef = A3A1754012E4966F004DFD70 /* Robot.m */; };
A3B1655F1399695000E9CC6E /* StringPrefixMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = A3A1754312E496CA004DFD70 /* StringPrefixMatcher.m */; };
+ A3CB75E2144C3479002D1F7A /* KWExampleSuite.h in Headers */ = {isa = PBXBuildFile; fileRef = A3CB75E0144C3479002D1F7A /* KWExampleSuite.h */; };
+ A3CB75E3144C3479002D1F7A /* KWExampleSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = A3CB75E1144C3479002D1F7A /* KWExampleSuite.m */; };
A3EB7FF1131EA219001860F5 /* KWBeNilMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = A3A1757312E498CD004DFD70 /* KWBeNilMatcher.m */; };
A3EB7FF3131EA21A001860F5 /* KWBeNonNilMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = A3A1757612E49900004DFD70 /* KWBeNonNilMatcher.m */; };
A3EB7FF7131EA224001860F5 /* KWHamcrestMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = A352EA1812EDC8160049C691 /* KWHamcrestMatcher.m */; };
@@ -276,6 +278,8 @@
A3A1757512E498D8004DFD70 /* KWBeNonNilMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KWBeNonNilMatcher.h; sourceTree = "<group>"; };
A3A1757612E49900004DFD70 /* KWBeNonNilMatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KWBeNonNilMatcher.m; sourceTree = "<group>"; };
A3B16542139967B800E9CC6E /* KiwiExamples.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KiwiExamples.octest; sourceTree = BUILT_PRODUCTS_DIR; };
+ A3CB75E0144C3479002D1F7A /* KWExampleSuite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KWExampleSuite.h; sourceTree = "<group>"; };
+ A3CB75E1144C3479002D1F7A /* KWExampleSuite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KWExampleSuite.m; sourceTree = "<group>"; };
A3FABFAE13CBB187002003F7 /* KiwiBlockMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KiwiBlockMacros.h; sourceTree = "<group>"; };
F5015B501158398E002E9A98 /* Kiwi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Kiwi.h; sourceTree = "<group>"; };
F5015B571158398E002E9A98 /* KWCallSite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KWCallSite.h; sourceTree = "<group>"; };
@@ -853,6 +857,8 @@
F50C74A011BE835C005BB3E2 /* KWPendingNode.m */,
F579D0CC11BE6FD700FC86CB /* KWRegisterMatchersNode.h */,
F579D0CD11BE6FD700FC86CB /* KWRegisterMatchersNode.m */,
+ A3CB75E0144C3479002D1F7A /* KWExampleSuite.h */,
+ A3CB75E1144C3479002D1F7A /* KWExampleSuite.m */,
);
name = "Example Groups";
sourceTree = "<group>";
@@ -975,6 +981,7 @@
A34FADAB13BBF4A4003968B2 /* KiwiConfiguration.h in Headers */,
A34FADAC13BBF4A4003968B2 /* KiwiMacros.h in Headers */,
A3FABFAF13CBB187002003F7 /* KiwiBlockMacros.h in Headers */,
+ A3CB75E2144C3479002D1F7A /* KWExampleSuite.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1206,6 +1213,7 @@
A3EB8065131EA574001860F5 /* KWHamrestMatchingAdditions.m in Sources */,
A385CAEC13AA7EDD00DCA951 /* KWUserDefinedMatcher.m in Sources */,
A385CAF013AAC9B800DCA951 /* KWMatchers.m in Sources */,
+ A3CB75E3144C3479002D1F7A /* KWExampleSuite.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -14,12 +14,15 @@
#import "KWExampleGroupDelegate.h"
@class KWCallSite;
+@class KWExampleSuite;
@class KWContextNode;
@class KWSpec;
@class KWMatcherFactory;
@interface KWExampleGroup : NSObject <KWExampleNodeVisitor, KWReporting>
+@property (nonatomic, assign) KWExampleSuite *suite;
+
- (id)initWithExampleNode:(id<KWExampleNode>)node contextNodeStack:(NSArray *)stack;
#pragma mark - Adding Verifiers
View
@@ -23,6 +23,7 @@
#import "KWWorkarounds.h"
#import "KWIntercept.h"
#import "KWExampleNode.h"
+#import "KWExampleSuite.h"
@interface KWExampleGroup ()
@@ -44,6 +45,7 @@ @implementation KWExampleGroup {
@synthesize verifiers;
@synthesize exampleNodeStack;
@synthesize delegate = _delegate;
+@synthesize suite;
- (id)initWithExampleNode:(id<KWExampleNode>)node contextNodeStack:(NSArray *)stack;
{
@@ -153,12 +155,12 @@ - (void)visitContextNode:(KWContextNode *)aNode {
@try {
[aNode.registerMatchersNode acceptExampleNodeVisitor:self];
- [aNode.beforeAllNode acceptExampleNodeVisitor:self];
+ [aNode.beforeAllNode acceptExampleNodeVisitor:self.suite];
for (id<KWExampleNode> node in aNode.nodes)
[node acceptExampleNodeVisitor:self];
- [aNode.afterAllNode acceptExampleNodeVisitor:self];
+ [aNode.afterAllNode acceptExampleNodeVisitor:self.suite];
} @catch (NSException *exception) {
KWFailure *failure = [KWFailure failureWithCallSite:aNode.callSite format:@"%@ \"%@\" raised",
[exception name],
@@ -174,20 +176,6 @@ - (void)visitRegisterMatchersNode:(KWRegisterMatchersNode *)aNode {
[self.matcherFactory registerMatcherClassesWithNamespacePrefix:aNode.namespacePrefix];
}
-- (void)visitBeforeAllNode:(KWBeforeAllNode *)aNode {
- if (aNode.block == nil)
- return;
-
- aNode.block();
-}
-
-- (void)visitAfterAllNode:(KWAfterAllNode *)aNode {
- if (aNode.block == nil)
- return;
-
- aNode.block();
-}
-
- (void)visitBeforeEachNode:(KWBeforeEachNode *)aNode {
if (aNode.block == nil)
return;
@@ -9,10 +9,12 @@
@class KWCallSite;
@class KWExampleGroup;
+@class KWExampleSuite;
@interface KWExampleGroupBuilder : NSObject {
@private
NSMutableArray *contextNodeStack;
+ NSMutableSet *suites;
}
#pragma mark -
@@ -24,10 +26,10 @@
#pragma mark Building Example Groups
@property (nonatomic, readonly) BOOL isBuildingExampleGroup;
-@property (nonatomic, retain, readonly) NSMutableArray *exampleGroups;
+@property (nonatomic, retain, readonly) KWExampleSuite *exampleSuite;
@property (nonatomic, retain) KWExampleGroup *currentExampleGroup;
-- (NSArray *)buildExampleGroups:(void (^)(void))buildingBlock;
+- (KWExampleSuite *)buildExampleGroups:(void (^)(void))buildingBlock;
- (KWExampleGroup *)currentExampleGroup;
- (void)pushContextNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription;
@@ -14,20 +14,22 @@
#import "KWItNode.h"
#import "KWPendingNode.h"
#import "KWRegisterMatchersNode.h"
+#import "KWExampleSuite.h"
+
@interface KWExampleGroupBuilder()
#pragma mark -
#pragma mark Building Example Groups
-@property (nonatomic, retain, readwrite) NSMutableArray *exampleGroups;
+@property (nonatomic, retain, readwrite) KWExampleSuite *exampleSuite;
@property (nonatomic, readonly) NSMutableArray *contextNodeStack;
@end
@implementation KWExampleGroupBuilder
-@synthesize exampleGroups;
+@synthesize exampleSuite;
@synthesize currentExampleGroup;
#pragma mark -
@@ -38,13 +40,15 @@ @implementation KWExampleGroupBuilder
- (id)init {
if ((self = [super init])) {
contextNodeStack = [[NSMutableArray alloc] init];
+ suites = [[NSMutableSet alloc] init];
}
return self;
}
- (void)dealloc {
- [exampleGroups release];
+ [suites release];
+ [exampleSuite release];
[contextNodeStack release];
[super dealloc];
}
@@ -89,21 +93,19 @@ - (BOOL)isBuildingExampleGroup {
return [self.contextNodeStack count] > 0;
}
-- (NSArray *)buildExampleGroups:(void (^)(void))buildingBlock
+- (KWExampleSuite *)buildExampleGroups:(void (^)(void))buildingBlock
{
- self.exampleGroups = [NSMutableArray array];
-
KWContextNode *rootNode = [KWContextNode contextNodeWithCallSite:nil description:nil];
+
+ self.exampleSuite = [[[KWExampleSuite alloc] initWithRootNode:rootNode] autorelease];
+
+ [suites addObject:self.exampleSuite];
[self.contextNodeStack addObject:rootNode];
buildingBlock();
[self.contextNodeStack removeAllObjects];
- NSArray *_exampleGroups = [self.exampleGroups copy];
-
- self.exampleGroups = nil;
-
- return [_exampleGroups autorelease];
+ return self.exampleSuite;
}
- (void)pushContextNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription {
@@ -174,7 +176,7 @@ - (void)addItNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aD
[contextNode addItNode:itNode];
KWExampleGroup *exampleGroup = [[KWExampleGroup alloc] initWithExampleNode:itNode contextNodeStack:self.contextNodeStack];
- [self.exampleGroups addObject:exampleGroup];
+ [self.exampleSuite addExampleGroup:exampleGroup];
[exampleGroup release];
}
@@ -187,7 +189,7 @@ - (void)addPendingNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString
[contextNode addPendingNode:pendingNode];
KWExampleGroup *exampleGroup = [[KWExampleGroup alloc] initWithExampleNode:pendingNode contextNodeStack:self.contextNodeStack];
- [self.exampleGroups addObject:exampleGroup];
+ [self.exampleSuite addExampleGroup:exampleGroup];
[exampleGroup release];
}
@@ -20,6 +20,8 @@
#pragma mark -
#pragma mark Visiting Nodes
+@optional
+
- (void)visitContextNode:(KWContextNode *)aNode;
- (void)visitRegisterMatchersNode:(KWRegisterMatchersNode *)aNode;
- (void)visitBeforeAllNode:(KWBeforeAllNode *)aNode;
View
@@ -0,0 +1,26 @@
+//
+// KWExampleSuite.h
+// Kiwi
+//
+// Created by Luke Redpath on 17/10/2011.
+// Copyright (c) 2011 Allen Ding. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "KWExampleNodeVisitor.h"
+
+@class KWContextNode;
+@class KWExampleGroup;
+@class SenTestCase;
+
+#define kKWINVOCATION_EXAMPLE_GROUP_KEY @"__KWExampleGroupKey"
+
+@interface KWExampleSuite : NSObject <KWExampleNodeVisitor> {
+ KWContextNode *rootNode;
+ NSMutableSet *exampleGroups;
+ NSMutableSet *visitedNodes;
+}
+- (id)initWithRootNode:(KWContextNode *)contextNode;
+- (void)addExampleGroup:(KWExampleGroup *)exampleGroup;
+- (NSArray *)invocationsForTestCase;
+@end
View
@@ -0,0 +1,83 @@
+//
+// KWExampleSuite.m
+// Kiwi
+//
+// Created by Luke Redpath on 17/10/2011.
+// Copyright (c) 2011 Allen Ding. All rights reserved.
+//
+
+#import "KWExampleSuite.h"
+#import "KWExampleGroup.h"
+#import "KWStringUtilities.h"
+#import "KWBeforeAllNode.h"
+#import "KWAfterAllNode.h"
+#import "NSMethodSignature+KiwiAdditions.h"
+#import <objc/runtime.h>
+
+
+@implementation KWExampleSuite
+
+- (id)initWithRootNode:(KWContextNode *)contextNode
+{
+ if ((self = [super init])) {
+ rootNode = [contextNode retain];
+ exampleGroups = [[NSMutableSet alloc] init];
+ visitedNodes = [[NSMutableSet alloc] init];
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [visitedNodes release];
+ [exampleGroups release];
+ [rootNode release];
+ [super dealloc];
+}
+
+- (void)addExampleGroup:(KWExampleGroup *)exampleGroup
+{
+ [exampleGroups addObject:exampleGroup];
+ [exampleGroup setSuite:self];
+}
+
+- (NSArray *)invocationsForTestCase;
+{
+ NSMutableArray *invocations = [NSMutableArray array];
+
+ for (KWExampleGroup *exampleGroup in exampleGroups) {
+ // Add a single dummy invocation for each example group
+ NSMethodSignature *methodSignature = [NSMethodSignature signatureWithObjCTypes:[KWEncodingForVoidMethod() UTF8String]];
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
+
+ [invocations addObject:invocation];
+
+ // because SenTest will modify the invocation target, we'll have to store
+ // another reference to the example group so we can retrieve it later
+ objc_setAssociatedObject(invocation, kKWINVOCATION_EXAMPLE_GROUP_KEY, exampleGroup, OBJC_ASSOCIATION_RETAIN);
+ }
+
+ return invocations;
+}
+
+#pragma mark - Node visiting
+
+- (void)visitBeforeAllNode:(KWBeforeAllNode *)aNode {
+ if (aNode.block == nil || [visitedNodes containsObject:aNode])
+ return;
+
+ [visitedNodes addObject:aNode];
+
+ aNode.block();
+}
+
+- (void)visitAfterAllNode:(KWAfterAllNode *)aNode {
+ if (aNode.block == nil || [visitedNodes containsObject:aNode])
+ return;
+
+ [visitedNodes addObject:aNode];
+
+ aNode.block();
+}
+
+@end
Oops, something went wrong.

0 comments on commit 51ad11f

Please sign in to comment.