Skip to content

Commit

Permalink
shared examples support. closes #4
Browse files Browse the repository at this point in the history
  • Loading branch information
petejkim committed Jun 2, 2012
1 parent 433a0df commit 2aa3cd9
Show file tree
Hide file tree
Showing 14 changed files with 358 additions and 4 deletions.
22 changes: 18 additions & 4 deletions README.md
Expand Up @@ -45,9 +45,24 @@ Standard OCUnit matchers such as `STAssertEqualObjects` and `STAssertNil` work,
```objective-c ```objective-c
#import "Specta.h" #import "Specta.h"


SharedExamplesBegin(MySharedExamples)
// Global shared examples are shared across all spec files.

sharedExamplesFor(@"a shared behavior", ^(NSDictionary *data) {
it(@"should do some stuff", ^{
// ...
});
});

SharedExamplesEnd

SpecBegin(Thing) SpecBegin(Thing)


describe(@"Thing", ^{ describe(@"Thing", ^{
sharedExamplesFor(@"another shared behavior", ^(NSDictionary *data) {
// Locally defined shared examples can override global shared examples within its scope.
});

beforeAll(^{ beforeAll(^{
// This is run once and only once before all of the examples // This is run once and only once before all of the examples
// in this group and before any beforeEach blocks. // in this group and before any beforeEach blocks.
Expand All @@ -65,6 +80,8 @@ describe(@"Thing", ^{
// ... // ...
}); });


itShouldBehaveLike(@"a shared behavior", [NSDictionary dictionaryWithObjectsAndKeys:@"obj", @"key", nil]);

describe(@"Nested examples", ^{ describe(@"Nested examples", ^{
it(@"should do even more stuff", ^{ it(@"should do even more stuff", ^{
// ... // ...
Expand Down Expand Up @@ -93,6 +110,7 @@ SpecEnd
* `beforeEach` and `afterEach` are also aliased as `before` and `after` respectively. * `beforeEach` and `afterEach` are also aliased as `before` and `after` respectively.
* `describe` is also aliased as `context`. * `describe` is also aliased as `context`.
* `it` is also aliased as `example` and `specify`. * `it` is also aliased as `example` and `specify`.
* `itShouldBehaveLike` is also aliased as `itBehavesLike`.
* Use `pending` or prepend `x` to `describe`, `context`, `example, `it`, and `specify` to mark examples or groups as pending. * Use `pending` or prepend `x` to `describe`, `context`, `example, `it`, and `specify` to mark examples or groups as pending.
* Do `#define SPT_CEDAR_SYNTAX` if you prefer to write `SPEC_BEGIN` and `SPEC_END` instead of `SpecBegin` and `SpecEnd`. * Do `#define SPT_CEDAR_SYNTAX` if you prefer to write `SPEC_BEGIN` and `SPEC_END` instead of `SpecBegin` and `SpecEnd`.
Expand All @@ -103,10 +121,6 @@ Refer to
on how to run specs from command line or in continuous integration on how to run specs from command line or in continuous integration
servers. servers.
### FEATURES COMING SOON
* Shared Examples
### CONTRIBUTION GUIDELINES ### CONTRIBUTION GUIDELINES
* Please use only spaces and indent 2 spaces at a time. * Please use only spaces and indent 2 spaces at a time.
Expand Down
30 changes: 30 additions & 0 deletions Specta.xcodeproj/project.pbxproj
Expand Up @@ -66,6 +66,16 @@
E9B777FD14BA329400D8DC76 /* SPTExampleGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = E9D9420914B8B42A00CD833A /* SPTExampleGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; E9B777FD14BA329400D8DC76 /* SPTExampleGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = E9D9420914B8B42A00CD833A /* SPTExampleGroup.h */; settings = {ATTRIBUTES = (Public, ); }; };
E9B777FE14BA329400D8DC76 /* SPTSenTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = E9B7777F14B9E15300D8DC76 /* SPTSenTestCase.h */; settings = {ATTRIBUTES = (Public, ); }; }; E9B777FE14BA329400D8DC76 /* SPTSenTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = E9B7777F14B9E15300D8DC76 /* SPTSenTestCase.h */; settings = {ATTRIBUTES = (Public, ); }; };
E9BDBAB914BE2F3A00102FB5 /* MiscTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E9BDBAB814BE2F3A00102FB5 /* MiscTest.m */; }; E9BDBAB914BE2F3A00102FB5 /* MiscTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E9BDBAB814BE2F3A00102FB5 /* MiscTest.m */; };
E9D3DED6157A385C0054978E /* SharedExamplesTest1.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D3DED5157A385C0054978E /* SharedExamplesTest1.m */; };
E9D3DED7157A385C0054978E /* SharedExamplesTest1.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D3DED5157A385C0054978E /* SharedExamplesTest1.m */; };
E9D3DEDA157A3F3D0054978E /* SPTSharedExampleGroups.h in Headers */ = {isa = PBXBuildFile; fileRef = E9D3DED9157A3F340054978E /* SPTSharedExampleGroups.h */; settings = {ATTRIBUTES = (Public, ); }; };
E9D3DEDB157A3F3D0054978E /* SPTSharedExampleGroups.h in Headers */ = {isa = PBXBuildFile; fileRef = E9D3DED9157A3F340054978E /* SPTSharedExampleGroups.h */; settings = {ATTRIBUTES = (Public, ); }; };
E9D3DEDD157A3F470054978E /* SPTSharedExampleGroups.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D3DEDC157A3F470054978E /* SPTSharedExampleGroups.m */; };
E9D3DEDE157A3F470054978E /* SPTSharedExampleGroups.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D3DEDC157A3F470054978E /* SPTSharedExampleGroups.m */; };
E9D3DEE0157A45550054978E /* SharedExamplesTest2.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D3DEDF157A45540054978E /* SharedExamplesTest2.m */; };
E9D3DEE1157A45550054978E /* SharedExamplesTest2.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D3DEDF157A45540054978E /* SharedExamplesTest2.m */; };
E9D3DEE3157A55F50054978E /* SharedExamplesTest3.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D3DEE2157A55F40054978E /* SharedExamplesTest3.m */; };
E9D3DEE4157A55F50054978E /* SharedExamplesTest3.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D3DEE2157A55F40054978E /* SharedExamplesTest3.m */; };
E9D9420E14B8B42A00CD833A /* Specta-Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = E9D9420414B8B42A00CD833A /* Specta-Prefix.pch */; settings = {ATTRIBUTES = (Public, ); }; }; E9D9420E14B8B42A00CD833A /* Specta-Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = E9D9420414B8B42A00CD833A /* Specta-Prefix.pch */; settings = {ATTRIBUTES = (Public, ); }; };
E9D9420F14B8B42A00CD833A /* Specta.h in Headers */ = {isa = PBXBuildFile; fileRef = E9D9420514B8B42A00CD833A /* Specta.h */; settings = {ATTRIBUTES = (Public, ); }; }; E9D9420F14B8B42A00CD833A /* Specta.h in Headers */ = {isa = PBXBuildFile; fileRef = E9D9420514B8B42A00CD833A /* Specta.h */; settings = {ATTRIBUTES = (Public, ); }; };
E9D9421014B8B42A00CD833A /* Specta.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D9420614B8B42A00CD833A /* Specta.m */; }; E9D9421014B8B42A00CD833A /* Specta.m in Sources */ = {isa = PBXBuildFile; fileRef = E9D9420614B8B42A00CD833A /* Specta.m */; };
Expand Down Expand Up @@ -134,6 +144,11 @@
E9B777B314BA294C00D8DC76 /* Specta-iOSTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Specta-iOSTests.octest"; sourceTree = BUILT_PRODUCTS_DIR; }; E9B777B314BA294C00D8DC76 /* Specta-iOSTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Specta-iOSTests.octest"; sourceTree = BUILT_PRODUCTS_DIR; };
E9B777DE14BA30F600D8DC76 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; E9B777DE14BA30F600D8DC76 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
E9BDBAB814BE2F3A00102FB5 /* MiscTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MiscTest.m; sourceTree = "<group>"; }; E9BDBAB814BE2F3A00102FB5 /* MiscTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MiscTest.m; sourceTree = "<group>"; };
E9D3DED5157A385C0054978E /* SharedExamplesTest1.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SharedExamplesTest1.m; sourceTree = "<group>"; };
E9D3DED9157A3F340054978E /* SPTSharedExampleGroups.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPTSharedExampleGroups.h; sourceTree = "<group>"; };
E9D3DEDC157A3F470054978E /* SPTSharedExampleGroups.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPTSharedExampleGroups.m; sourceTree = "<group>"; };
E9D3DEDF157A45540054978E /* SharedExamplesTest2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SharedExamplesTest2.m; sourceTree = "<group>"; };
E9D3DEE2157A55F40054978E /* SharedExamplesTest3.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SharedExamplesTest3.m; sourceTree = "<group>"; };
E9D9420414B8B42A00CD833A /* Specta-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Specta-Prefix.pch"; sourceTree = "<group>"; }; E9D9420414B8B42A00CD833A /* Specta-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Specta-Prefix.pch"; sourceTree = "<group>"; };
E9D9420514B8B42A00CD833A /* Specta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Specta.h; sourceTree = "<group>"; }; E9D9420514B8B42A00CD833A /* Specta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Specta.h; sourceTree = "<group>"; };
E9D9420614B8B42A00CD833A /* Specta.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Specta.m; sourceTree = "<group>"; }; E9D9420614B8B42A00CD833A /* Specta.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Specta.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -266,6 +281,8 @@
E9D9420814B8B42A00CD833A /* SPTExample.m */, E9D9420814B8B42A00CD833A /* SPTExample.m */,
E9D9420914B8B42A00CD833A /* SPTExampleGroup.h */, E9D9420914B8B42A00CD833A /* SPTExampleGroup.h */,
E9D9420A14B8B42A00CD833A /* SPTExampleGroup.m */, E9D9420A14B8B42A00CD833A /* SPTExampleGroup.m */,
E9D3DED9157A3F340054978E /* SPTSharedExampleGroups.h */,
E9D3DEDC157A3F470054978E /* SPTSharedExampleGroups.m */,
E9B7777F14B9E15300D8DC76 /* SPTSenTestCase.h */, E9B7777F14B9E15300D8DC76 /* SPTSenTestCase.h */,
E9B7778114B9E15A00D8DC76 /* SPTSenTestCase.m */, E9B7778114B9E15A00D8DC76 /* SPTSenTestCase.m */,
E944CA2814C4B5E300821DED /* SPTSenTestInvocation.h */, E944CA2814C4B5E300821DED /* SPTSenTestInvocation.h */,
Expand Down Expand Up @@ -299,6 +316,9 @@
E910177414B9114A0087CD46 /* FailingSpecTest.m */, E910177414B9114A0087CD46 /* FailingSpecTest.m */,
E9A204C814C79F81006E4A66 /* PendingSpecTest1.m */, E9A204C814C79F81006E4A66 /* PendingSpecTest1.m */,
E9A204CC14C7A487006E4A66 /* PendingSpecTest2.m */, E9A204CC14C7A487006E4A66 /* PendingSpecTest2.m */,
E9D3DED5157A385C0054978E /* SharedExamplesTest1.m */,
E9D3DEDF157A45540054978E /* SharedExamplesTest2.m */,
E9D3DEE2157A55F40054978E /* SharedExamplesTest3.m */,
E96187B114C4AC690021D7CE /* UnexpectedExceptionTest.m */, E96187B114C4AC690021D7CE /* UnexpectedExceptionTest.m */,
E9BDBAB814BE2F3A00102FB5 /* MiscTest.m */, E9BDBAB814BE2F3A00102FB5 /* MiscTest.m */,
E9D96A2814B6B8AB007D9521 /* frameworks */, E9D96A2814B6B8AB007D9521 /* frameworks */,
Expand Down Expand Up @@ -411,6 +431,7 @@
E9B777FB14BA329400D8DC76 /* SPTSpec.h in Headers */, E9B777FB14BA329400D8DC76 /* SPTSpec.h in Headers */,
E9B777FC14BA329400D8DC76 /* SPTExample.h in Headers */, E9B777FC14BA329400D8DC76 /* SPTExample.h in Headers */,
E9B777FD14BA329400D8DC76 /* SPTExampleGroup.h in Headers */, E9B777FD14BA329400D8DC76 /* SPTExampleGroup.h in Headers */,
E9D3DEDB157A3F3D0054978E /* SPTSharedExampleGroups.h in Headers */,
E9B777FE14BA329400D8DC76 /* SPTSenTestCase.h in Headers */, E9B777FE14BA329400D8DC76 /* SPTSenTestCase.h in Headers */,
E944CA2A14C4B5E300821DED /* SPTSenTestInvocation.h in Headers */, E944CA2A14C4B5E300821DED /* SPTSenTestInvocation.h in Headers */,
E944CA3014C4B70000821DED /* SpectaTypes.h in Headers */, E944CA3014C4B70000821DED /* SpectaTypes.h in Headers */,
Expand All @@ -426,6 +447,7 @@
E9D9420E14B8B42A00CD833A /* Specta-Prefix.pch in Headers */, E9D9420E14B8B42A00CD833A /* Specta-Prefix.pch in Headers */,
E9D9421114B8B42A00CD833A /* SPTExample.h in Headers */, E9D9421114B8B42A00CD833A /* SPTExample.h in Headers */,
E9D9421314B8B42A00CD833A /* SPTExampleGroup.h in Headers */, E9D9421314B8B42A00CD833A /* SPTExampleGroup.h in Headers */,
E9D3DEDA157A3F3D0054978E /* SPTSharedExampleGroups.h in Headers */,
E9D9421614B8B42A00CD833A /* SPTSpec.h in Headers */, E9D9421614B8B42A00CD833A /* SPTSpec.h in Headers */,
E9B7778014B9E15300D8DC76 /* SPTSenTestCase.h in Headers */, E9B7778014B9E15300D8DC76 /* SPTSenTestCase.h in Headers */,
E944CA2914C4B5E300821DED /* SPTSenTestInvocation.h in Headers */, E944CA2914C4B5E300821DED /* SPTSenTestInvocation.h in Headers */,
Expand Down Expand Up @@ -596,6 +618,7 @@
E9B777D814BA308B00D8DC76 /* SPTExampleGroup.m in Sources */, E9B777D814BA308B00D8DC76 /* SPTExampleGroup.m in Sources */,
E9B777D914BA308B00D8DC76 /* SPTSenTestCase.m in Sources */, E9B777D914BA308B00D8DC76 /* SPTSenTestCase.m in Sources */,
E944CA2D14C4B5F600821DED /* SPTSenTestInvocation.m in Sources */, E944CA2D14C4B5F600821DED /* SPTSenTestInvocation.m in Sources */,
E9D3DEDE157A3F470054978E /* SPTSharedExampleGroups.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
Expand Down Expand Up @@ -625,6 +648,9 @@
E96187C714C4AFA70021D7CE /* MiscTest.m in Sources */, E96187C714C4AFA70021D7CE /* MiscTest.m in Sources */,
E9A204CA14C79F81006E4A66 /* PendingSpecTest1.m in Sources */, E9A204CA14C79F81006E4A66 /* PendingSpecTest1.m in Sources */,
E9A204CE14C7A487006E4A66 /* PendingSpecTest2.m in Sources */, E9A204CE14C7A487006E4A66 /* PendingSpecTest2.m in Sources */,
E9D3DED7157A385C0054978E /* SharedExamplesTest1.m in Sources */,
E9D3DEE1157A45550054978E /* SharedExamplesTest2.m in Sources */,
E9D3DEE4157A55F50054978E /* SharedExamplesTest3.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
Expand All @@ -638,6 +664,7 @@
E9D9421414B8B42A00CD833A /* SPTExampleGroup.m in Sources */, E9D9421414B8B42A00CD833A /* SPTExampleGroup.m in Sources */,
E9B7778214B9E15A00D8DC76 /* SPTSenTestCase.m in Sources */, E9B7778214B9E15A00D8DC76 /* SPTSenTestCase.m in Sources */,
E944CA2C14C4B5F600821DED /* SPTSenTestInvocation.m in Sources */, E944CA2C14C4B5F600821DED /* SPTSenTestInvocation.m in Sources */,
E9D3DEDD157A3F470054978E /* SPTSharedExampleGroups.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
Expand Down Expand Up @@ -667,6 +694,9 @@
E96187B214C4AC690021D7CE /* UnexpectedExceptionTest.m in Sources */, E96187B214C4AC690021D7CE /* UnexpectedExceptionTest.m in Sources */,
E9A204C914C79F81006E4A66 /* PendingSpecTest1.m in Sources */, E9A204C914C79F81006E4A66 /* PendingSpecTest1.m in Sources */,
E9A204CD14C7A487006E4A66 /* PendingSpecTest2.m in Sources */, E9A204CD14C7A487006E4A66 /* PendingSpecTest2.m in Sources */,
E9D3DED6157A385C0054978E /* SharedExamplesTest1.m in Sources */,
E9D3DEE0157A45550054978E /* SharedExamplesTest2.m in Sources */,
E9D3DEE3157A55F50054978E /* SharedExamplesTest3.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
Expand Down
2 changes: 2 additions & 0 deletions src/SPTExampleGroup.h
Expand Up @@ -14,6 +14,7 @@
NSMutableArray *_afterAllArray; NSMutableArray *_afterAllArray;
NSMutableArray *_beforeEachArray; NSMutableArray *_beforeEachArray;
NSMutableArray *_afterEachArray; NSMutableArray *_afterEachArray;
NSMutableDictionary *_sharedExamples;
unsigned int _exampleCount; unsigned int _exampleCount;
unsigned int _ranExampleCount; unsigned int _ranExampleCount;
} }
Expand All @@ -26,6 +27,7 @@
@property (nonatomic, retain) NSMutableArray *afterAllArray; @property (nonatomic, retain) NSMutableArray *afterAllArray;
@property (nonatomic, retain) NSMutableArray *beforeEachArray; @property (nonatomic, retain) NSMutableArray *beforeEachArray;
@property (nonatomic, retain) NSMutableArray *afterEachArray; @property (nonatomic, retain) NSMutableArray *afterEachArray;
@property (nonatomic, retain) NSMutableDictionary *sharedExamples;
@property (nonatomic) unsigned int exampleCount; @property (nonatomic) unsigned int exampleCount;
@property (nonatomic) unsigned int ranExampleCount; @property (nonatomic) unsigned int ranExampleCount;


Expand Down
3 changes: 3 additions & 0 deletions src/SPTExampleGroup.m
Expand Up @@ -22,6 +22,7 @@ @implementation SPTExampleGroup
, afterAllArray=_afterAllArray , afterAllArray=_afterAllArray
, beforeEachArray=_beforeEachArray , beforeEachArray=_beforeEachArray
, afterEachArray=_afterEachArray , afterEachArray=_afterEachArray
, sharedExamples=_sharedExamples
, exampleCount=_exampleCount , exampleCount=_exampleCount
, ranExampleCount=_ranExampleCount , ranExampleCount=_ranExampleCount
; ;
Expand All @@ -35,6 +36,7 @@ - (void)dealloc {
self.afterAllArray = nil; self.afterAllArray = nil;
self.beforeEachArray = nil; self.beforeEachArray = nil;
self.afterEachArray = nil; self.afterEachArray = nil;
self.sharedExamples = nil;
[super dealloc]; [super dealloc];
} }


Expand All @@ -49,6 +51,7 @@ - (id)init {
self.afterAllArray = [NSMutableArray array]; self.afterAllArray = [NSMutableArray array];
self.beforeEachArray = [NSMutableArray array]; self.beforeEachArray = [NSMutableArray array];
self.afterEachArray = [NSMutableArray array]; self.afterEachArray = [NSMutableArray array];
self.sharedExamples = [NSMutableDictionary dictionary];
self.exampleCount = 0; self.exampleCount = 0;
self.ranExampleCount = 0; self.ranExampleCount = 0;
} }
Expand Down
2 changes: 2 additions & 0 deletions src/SPTSenTestCase.m
Expand Up @@ -2,6 +2,7 @@
#import "SPTSpec.h" #import "SPTSpec.h"
#import "SPTExample.h" #import "SPTExample.h"
#import "SPTSenTestInvocation.h" #import "SPTSenTestInvocation.h"
#import "SPTSharedExampleGroups.h"
#import <objc/runtime.h> #import <objc/runtime.h>


@interface NSObject (SPTSenTestCase) @interface NSObject (SPTSenTestCase)
Expand All @@ -24,6 +25,7 @@ - (void)dealloc {
} }


+ (void)initialize { + (void)initialize {
[SPTSharedExampleGroups initialize];
SPTSpec *spec = [[SPTSpec alloc] init]; SPTSpec *spec = [[SPTSpec alloc] init];
SPTSenTestCase *testCase = [[[self class] alloc] init]; SPTSenTestCase *testCase = [[[self class] alloc] init];
objc_setAssociatedObject(self, "SPT_spec", spec, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(self, "SPT_spec", spec, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
Expand Down
15 changes: 15 additions & 0 deletions src/SPTSharedExampleGroups.h
@@ -0,0 +1,15 @@
#import <Foundation/Foundation.h>
#import "SpectaTypes.h"

@class
SPTExampleGroup
;

@interface SPTSharedExampleGroups : NSObject

+ (void)addSharedExampleGroupWithName:(NSString *)name block:(SPTDictionaryBlock)block exampleGroup:(SPTExampleGroup *)exampleGroup;
+ (SPTDictionaryBlock)sharedExampleGroupWithName:(NSString *)name exampleGroup:(SPTExampleGroup *)exampleGroup;
+ (void)defineSharedExampleGroups;

@end

58 changes: 58 additions & 0 deletions src/SPTSharedExampleGroups.m
@@ -0,0 +1,58 @@
#import "SPTSharedExampleGroups.h"
#import "SPTExampleGroup.h"
#import <objc/runtime.h>

NSMutableDictionary *globalSharedExampleGroups = nil;
BOOL initialized = NO;

@implementation SPTSharedExampleGroups

+ (void)initialize {
@synchronized(self) {
Class SPTSharedExampleGroupsClass = [SPTSharedExampleGroups class];
if([self class] == SPTSharedExampleGroupsClass) {
if(!initialized) {
initialized = YES;
globalSharedExampleGroups = [[NSMutableDictionary alloc] init];

Class *classes = NULL;
int numClasses = objc_getClassList(NULL, 0);

if(numClasses > 0) {
classes = malloc(sizeof(Class) * numClasses);
numClasses = objc_getClassList(classes, numClasses);

Class klass, superClass;
for(uint i = 0; i < numClasses; i++) {
klass = classes[i];
superClass = class_getSuperclass(klass);
if(superClass == SPTSharedExampleGroupsClass) {
[klass defineSharedExampleGroups];
}
}

free(classes);
}
}
}
}
}

+ (void)addSharedExampleGroupWithName:(NSString *)name block:(SPTDictionaryBlock)block exampleGroup:(SPTExampleGroup *)exampleGroup {
[(exampleGroup == nil ? globalSharedExampleGroups : exampleGroup.sharedExamples) setObject:[[block copy] autorelease] forKey:name];
}

+ (SPTDictionaryBlock)sharedExampleGroupWithName:(NSString *)name exampleGroup:(SPTExampleGroup *)exampleGroup {
SPTDictionaryBlock sharedExampleGroup = nil;
while(exampleGroup != nil) {
if((sharedExampleGroup = [exampleGroup.sharedExamples objectForKey:name])) {
return sharedExampleGroup;
}
exampleGroup = exampleGroup.parent;
}
return [globalSharedExampleGroups objectForKey:name];
}

+ (void)defineSharedExampleGroups {}

@end
14 changes: 14 additions & 0 deletions src/Specta.h
Expand Up @@ -3,16 +3,24 @@
#import "SPTSenTestCase.h" #import "SPTSenTestCase.h"
#import "SPTSpec.h" #import "SPTSpec.h"
#import "SPTExampleGroup.h" #import "SPTExampleGroup.h"
#import "SPTSharedExampleGroups.h"


@interface Specta : NSObject @interface Specta : NSObject
@end @end


#define SpecBegin(name) _SPT_SpecBegin(name, __FILE__, __LINE__) #define SpecBegin(name) _SPT_SpecBegin(name, __FILE__, __LINE__)
#define SpecEnd _SPT_SpecEnd #define SpecEnd _SPT_SpecEnd


#define SharedExamplesBegin(name) _SPT_SharedExampleGroupsBegin(name)
#define SharedExamplesEnd _SPT_SharedExampleGroupsEnd
#define SharedExampleGroupsBegin(name) _SPT_SharedExampleGroupsBegin(name)
#define SharedExampleGroupsEnd _SPT_SharedExampleGroupsEnd

#ifdef SPT_CEDAR_SYNTAX #ifdef SPT_CEDAR_SYNTAX
# define SPEC_BEGIN(name) SpecBegin(name) # define SPEC_BEGIN(name) SpecBegin(name)
# define SPEC_END SpecEnd # define SPEC_END SpecEnd
# define SHARED_EXAMPLE_GROUPS_BEGIN(name) SharedExamplesBegin(name)
# define SHARED_EXAMPLE_GROUPS_END SharedExamplesEnd
#endif #endif


void describe(NSString *name, void (^block)()); void describe(NSString *name, void (^block)());
Expand All @@ -36,3 +44,9 @@ void beforeEach(void (^block)());
void afterEach(void (^block)()); void afterEach(void (^block)());
void before(void (^block)()); void before(void (^block)());
void after(void (^block)()); void after(void (^block)());

void sharedExamplesFor(NSString *name, void (^block)(NSDictionary *data));
void sharedExamples(NSString *name, void (^block)(NSDictionary *data));

void itShouldBehaveLike(NSString *name, NSDictionary *data);
void itBehavesLike(NSString *name, NSDictionary *data);
20 changes: 20 additions & 0 deletions src/Specta.m
@@ -1,4 +1,5 @@
#import "Specta.h" #import "Specta.h"
#import "SpectaTypes.h"


@implementation Specta @implementation Specta
@end @end
Expand Down Expand Up @@ -60,3 +61,22 @@ void before(void (^block)()) {
void after(void (^block)()) { void after(void (^block)()) {
afterEach(block); afterEach(block);
} }

void sharedExamplesFor(NSString *name, void (^block)(NSDictionary *data)) {
[SPTSharedExampleGroups addSharedExampleGroupWithName:name block:block exampleGroup:SPT_currentGroup];
}

void sharedExamples(NSString *name, void (^block)(NSDictionary *data)) {
sharedExamplesFor(name, block);
}

void itShouldBehaveLike(NSString *name, NSDictionary *data) {
SPTDictionaryBlock block = [SPTSharedExampleGroups sharedExampleGroupWithName:name exampleGroup:SPT_currentGroup];
if(block) {
block(data);
}
}

void itBehavesLike(NSString *name, NSDictionary *data) {
itShouldBehaveLike(name, data);
}
10 changes: 10 additions & 0 deletions src/SpectaSupport.h
Expand Up @@ -9,3 +9,13 @@
[self SPT_unsetCurrentSpec]; \ [self SPT_unsetCurrentSpec]; \
} \ } \
@end @end

#define _SPT_SharedExampleGroupsBegin(name) \
@interface name##SharedExampleGroups : SPTSharedExampleGroups \
@end \
@implementation name##SharedExampleGroups \
+ (void)defineSharedExampleGroups {

#define _SPT_SharedExampleGroupsEnd \
} \
@end
1 change: 1 addition & 0 deletions src/SpectaTypes.h
@@ -1 +1,2 @@
typedef void (^SPTVoidBlock)(); typedef void (^SPTVoidBlock)();
typedef void (^SPTDictionaryBlock)();

0 comments on commit 2aa3cd9

Please sign in to comment.