Skip to content

Commit

Permalink
Added ability to run focused specs. fdescribe, fcontext, and fit mark…
Browse files Browse the repository at this point in the history
… examples as focused.
  • Loading branch information
cppforlife committed Oct 13, 2011
1 parent 8eb940b commit 0d6d16e
Show file tree
Hide file tree
Showing 19 changed files with 466 additions and 82 deletions.
14 changes: 7 additions & 7 deletions Cedar.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,14 @@
AEEE1FB611DC271300029872 /* Cedar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cedar.framework; sourceTree = BUILT_PRODUCTS_DIR; };
AEEE1FB811DC271300029872 /* Cedar-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Cedar-Info.plist"; sourceTree = "<group>"; };
AEEE1FC411DC27B800029872 /* CDRDefaultReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRDefaultReporter.m; sourceTree = "<group>"; };
AEEE1FC511DC27B800029872 /* CDRExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRExample.m; sourceTree = "<group>"; };
AEEE1FC611DC27B800029872 /* CDRExampleBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRExampleBase.m; sourceTree = "<group>"; };
AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRExampleGroup.m; sourceTree = "<group>"; };
AEEE1FC811DC27B800029872 /* CDRFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRFunctions.m; sourceTree = "<group>"; };
AEEE1FC511DC27B800029872 /* CDRExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRExample.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
AEEE1FC611DC27B800029872 /* CDRExampleBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRExampleBase.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRExampleGroup.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
AEEE1FC811DC27B800029872 /* CDRFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRFunctions.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
AEEE1FC911DC27B800029872 /* CDRSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRSpec.m; sourceTree = "<group>"; };
AEEE1FCB11DC27B800029872 /* CDRDefaultReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRDefaultReporter.h; sourceTree = "<group>"; };
AEEE1FCC11DC27B800029872 /* CDRExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExample.h; sourceTree = "<group>"; };
AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleBase.h; sourceTree = "<group>"; };
AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CDRExampleBase.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
AEEE1FCE11DC27B800029872 /* CDRExampleGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleGroup.h; sourceTree = "<group>"; };
AEEE1FCF11DC27B800029872 /* CDRExampleParent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleParent.h; sourceTree = "<group>"; };
AEEE1FD011DC27B800029872 /* CDRExampleReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleReporter.h; sourceTree = "<group>"; };
Expand All @@ -299,8 +299,8 @@
AEEE1FE111DC27B800029872 /* CDRSpecStatusViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRSpecStatusViewController.m; sourceTree = "<group>"; };
AEEE1FE211DC27B800029872 /* CedarApplicationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CedarApplicationDelegate.m; sourceTree = "<group>"; };
AEEE1FE611DC27B800029872 /* SpecHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpecHelper.m; sourceTree = "<group>"; };
AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRExampleGroupSpec.mm; sourceTree = "<group>"; };
AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRExampleSpec.mm; sourceTree = "<group>"; };
AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRExampleGroupSpec.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRExampleSpec.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
AEEE1FEC11DC27B800029872 /* CDRExampleStateMapSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRExampleStateMapSpec.mm; sourceTree = "<group>"; };
AEEE1FED11DC27B800029872 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
AEEE1FEE11DC27B800029872 /* SlowSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlowSpec.m; sourceTree = "<group>"; };
Expand Down
11 changes: 10 additions & 1 deletion Source/CDRColorizedReporter.m
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#import "CDRColorizedReporter.h"

static const char * const ANSI_NORMAL = "\033[0m";
static const char * const ANSI_GREEN = "\033[0;40;32m";
static const char * const ANSI_RED = "\033[0;40;31m";
static const char * const ANSI_GREEN = "\033[0;40;32m";
static const char * const ANSI_YELLOW = "\033[0;40;33m";
static const char * const ANSI_CYAN = "\033[0;40;36m";

@implementation CDRColorizedReporter

Expand All @@ -20,6 +21,14 @@ - (NSString *)pendingMessageForExample:(CDRExample *)example {
return [NSString stringWithFormat:@"%s%@%s", ANSI_YELLOW, [super pendingMessageForExample:example], ANSI_NORMAL];
}

- (NSString *)skippedToken {
return [NSString stringWithFormat:@"%s%@%s", ANSI_CYAN, [super skippedToken], ANSI_NORMAL];
}

- (NSString *)skippedMessageForExample:(CDRExample *)example {
return [NSString stringWithFormat:@"%s%@%s", ANSI_CYAN, [super skippedMessageForExample:example], ANSI_NORMAL];
}

- (NSString *)failureToken {
return [NSString stringWithFormat:@"%s%@%s", ANSI_RED, [super failureToken], ANSI_NORMAL];
}
Expand Down
23 changes: 22 additions & 1 deletion Source/CDRDefaultReporter.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "CDRDefaultReporter.h"
#import "CDRExample.h"
#import "CDRExampleGroup.h"
#import "SpecHelper.h"

@interface CDRDefaultReporter (private)
- (void)printMessages:(NSArray *)messages;
Expand All @@ -16,6 +17,7 @@ @implementation CDRDefaultReporter
- (id)init {
if (self = [super init]) {
pendingMessages_ = [[NSMutableArray alloc] init];
skippedMessages_ = [[NSMutableArray alloc] init];
failureMessages_ = [[NSMutableArray alloc] init];
}
return self;
Expand All @@ -25,6 +27,7 @@ - (void)dealloc {
[rootGroups_ release];
[startTime_ release];
[failureMessages_ release];
[skippedMessages_ release];
[pendingMessages_ release];
[super dealloc];
}
Expand Down Expand Up @@ -52,7 +55,7 @@ - (void)runDidComplete {
}

- (int)result {
if ([failureMessages_ count]) {
if ([SpecHelper specHelper].shouldOnlyRunFocused || [failureMessages_ count]) {
return 1;
} else {
return 0;
Expand All @@ -72,6 +75,14 @@ - (NSString *)pendingMessageForExample:(CDRExample *)example {
return [NSString stringWithFormat:@"PENDING %@", [example fullText]];
}

- (NSString *)skippedToken {
return @">";
}

- (NSString *)skippedMessageForExample:(CDRExample *)example {
return [NSString stringWithFormat:@"SKIPPED %@", [example fullText]];
}

- (NSString *)failureToken {
return @"F";
}
Expand Down Expand Up @@ -127,6 +138,10 @@ - (void)reportOnExample:(CDRExample *)example {
printf("%s", [[self pendingToken] cStringUsingEncoding:NSUTF8StringEncoding]);
[pendingMessages_ addObject:[self pendingMessageForExample:example]];
break;
case CDRExampleStateSkipped:
printf("%s", [[self skippedToken] cStringUsingEncoding:NSUTF8StringEncoding]);
[skippedMessages_ addObject:[self skippedMessageForExample:example]];
break;
case CDRExampleStateFailed:
printf("%s", [[self failureToken] cStringUsingEncoding:NSUTF8StringEncoding]);
[failureMessages_ addObject:[self failureMessageForExample:example]];
Expand All @@ -143,9 +158,15 @@ - (void)reportOnExample:(CDRExample *)example {
- (void)printStats {
printf("\nFinished in %.4f seconds\n\n", [[NSDate date] timeIntervalSinceDate:startTime_]);
printf("%u examples, %u failures", exampleCount_, (unsigned int)failureMessages_.count);

if (pendingMessages_.count) {
printf(", %u pending", (unsigned int)pendingMessages_.count);
}

if (skippedMessages_.count) {
printf(", %u skipped", (unsigned int)skippedMessages_.count);
}

printf("\n");
}

Expand Down
5 changes: 4 additions & 1 deletion Source/CDRExample.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "CDRExample.h"
#import "CDRExampleReporter.h"
#import "CDRSpecFailure.h"
#import "SpecHelper.h"

const CDRSpecBlock PENDING = nil;

Expand Down Expand Up @@ -51,7 +52,9 @@ - (float)progress {
}

- (void)run {
if (block_) {
if (!self.shouldRun) {
self.state = CDRExampleStateSkipped;
} else if (block_) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@try {
[parent_ setUp];
Expand Down
25 changes: 18 additions & 7 deletions Source/CDRExampleBase.m
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
#import "CDRExampleBase.h"
#import "SpecHelper.h"

@implementation CDRExampleBase

@synthesize text = text_, parent = parent_;
@synthesize text = text_, parent = parent_, focused = focused_;

- (id)initWithText:(NSString *)text {
if (self = [super init]) {
text_ = [text retain];
}
return self;
if (self = [super init]) {
text_ = [text retain];
focused_ = NO;
}
return self;
}

- (void)dealloc {
[text_ release];
[super dealloc];
[text_ release];
[super dealloc];
}

- (void)setUp {
Expand All @@ -25,6 +27,15 @@ - (void)tearDown {
- (void)run {
}

- (BOOL)shouldRun {
BOOL shouldOnlyRunFocused = [SpecHelper specHelper].shouldOnlyRunFocused;
return !shouldOnlyRunFocused || (shouldOnlyRunFocused && (self.isFocused || parent_.shouldRun));
}

- (BOOL)hasFocusedExamples {
return self.isFocused;
}

- (BOOL)hasChildren {
return NO;
}
Expand Down
12 changes: 12 additions & 0 deletions Source/CDRExampleGroup.m
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ - (void)run {
[self stopObservingExamples];
}

- (BOOL)hasFocusedExamples {
if (self.isFocused) {
return YES;
}
for (CDRExampleBase *example in examples_) {
if ([example hasFocusedExamples]) {
return YES;
}
}
return NO;
}

- (BOOL)hasChildren {
return [examples_ count] > 0;
}
Expand Down
4 changes: 4 additions & 0 deletions Source/CDRFunctions.m
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ int runSpecsWithCustomExampleReporter(NSArray *specClasses, id<CDRExampleReporte
CDRDefineGlobalBeforeAndAfterEachBlocks();
NSArray *groups = CDRCreateRootGroupsFromSpecClasses(specClasses);

for (CDRExampleGroup *group in groups) {
[SpecHelper specHelper].shouldOnlyRunFocused |= [group hasFocusedExamples];
}

[reporter runWillStartWithGroups:groups];
[groups makeObjectsPerformSelector:@selector(run)];
[reporter runDidComplete];
Expand Down
59 changes: 40 additions & 19 deletions Source/CDRSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,67 @@

CDRSpec *currentSpec;

void describe(NSString *text, CDRSpecBlock block) {
void beforeEach(CDRSpecBlock block) {
[currentSpec.currentGroup addBefore:block];
}

void afterEach(CDRSpecBlock block) {
[currentSpec.currentGroup addAfter:block];
}

CDRExampleGroup * describe(NSString *text, CDRSpecBlock block) {
CDRExampleGroup *parentGroup = currentSpec.currentGroup;
currentSpec.currentGroup = [CDRExampleGroup groupWithText:text];
[parentGroup add:currentSpec.currentGroup];

CDRExampleGroup *group = [CDRExampleGroup groupWithText:text];
[parentGroup add:group];

currentSpec.currentGroup = group;
block();
currentSpec.currentGroup = parentGroup;
}

void beforeEach(CDRSpecBlock block) {
[currentSpec.currentGroup addBefore:block];
return group;
}

void afterEach(CDRSpecBlock block) {
[currentSpec.currentGroup addAfter:block];
CDRExampleGroup * context(NSString *text, CDRSpecBlock block) {
return describe(text, block);
}

void it(NSString *text, CDRSpecBlock block) {
CDRExample * it(NSString *text, CDRSpecBlock block) {
CDRExample *example = [CDRExample exampleWithText:text andBlock:block];
[currentSpec.currentGroup add:example];
return example;
}

void fail(NSString *reason) {
[[CDRSpecFailure specFailureWithReason:[NSString stringWithFormat:@"Failure: %@", reason]] raise];
CDRExampleGroup * xdescribe(NSString *text, CDRSpecBlock block) {
return describe(text, ^{});
}

void context(NSString *text, CDRSpecBlock block) {
describe(text, block);
CDRExampleGroup * xcontext(NSString *text, CDRSpecBlock block) {
return xdescribe(text, block);
}

void xcontext(NSString *text, CDRSpecBlock block) {
it(text, PENDING);
CDRExample * xit(NSString *text, CDRSpecBlock block) {
return it(text, PENDING);
}

void xdescribe(NSString *text, CDRSpecBlock block) {
it(text, PENDING);
CDRExampleGroup * fdescribe(NSString *text, CDRSpecBlock block) {
CDRExampleGroup *group = describe(text, block);
group.focused = YES;
return group;
}

void xit(NSString *text, CDRSpecBlock block) {
it(text, PENDING);
CDRExampleGroup * fcontext(NSString *text, CDRSpecBlock block) {
return fdescribe(text, block);
}

CDRExample * fit(NSString *text, CDRSpecBlock block) {
CDRExample *example = it(text, block);
example.focused = YES;
return example;
}

void fail(NSString *reason) {
[[CDRSpecFailure specFailureWithReason:[NSString stringWithFormat:@"Failure: %@", reason]] raise];
}

@implementation CDRSpec
Expand Down
8 changes: 8 additions & 0 deletions Source/CDRTeamCityReporter.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ - (NSString *)pendingMessageForExample:(CDRExample *)example{
return [NSString stringWithFormat:@"##teamcity[testIgnored name='%@']", [self escapeText:example.fullText]];
}

- (NSString *)skippedMessageForExample:(CDRExample *)example{
return [NSString stringWithFormat:@"##teamcity[testIgnored name='%@']", [self escapeText:example.fullText]];
}

- (NSString *)failureMessageForExample:(CDRExample *)example{
return [NSString stringWithFormat:@"##teamcity[testFailed name='%@' message='%@']",
[self escapeText:example.fullText],
Expand All @@ -47,6 +51,10 @@ - (void)reportOnExample:(CDRExample *)example {
printf("%s\n", [[self pendingMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding]);
[pendingMessages_ addObject:[super pendingMessageForExample:example]];
break;
case CDRExampleStateSkipped:
printf("%s\n", [[self skippedMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding]);
[skippedMessages_ addObject:[super skippedMessageForExample:example]];
break;
case CDRExampleStateError:
case CDRExampleStateFailed:
printf("%s\n%s\n%s\n",
Expand Down
3 changes: 3 additions & 0 deletions Source/Headers/CDRDefaultReporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
NSArray *rootGroups_;

NSMutableArray *pendingMessages_;
NSMutableArray *skippedMessages_;
NSMutableArray *failureMessages_;

NSDate *startTime_;
Expand All @@ -17,6 +18,8 @@
- (NSString *)successToken;
- (NSString *)pendingToken;
- (NSString *)pendingMessageForExample:(CDRExample *)example;
- (NSString *)skippedToken;
- (NSString *)skippedMessageForExample:(CDRExample *)example;
- (NSString *)failureToken;
- (NSString *)failureMessageForExample:(CDRExample *)example;
- (NSString *)errorToken;
Expand Down
15 changes: 11 additions & 4 deletions Source/Headers/CDRExampleBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,32 @@ typedef void (^CDRSpecBlock)(void);

enum CDRExampleState {
CDRExampleStateIncomplete = 0x00,
CDRExampleStatePassed = 0x01,
CDRExampleStatePending = 0x03,
CDRExampleStateFailed = 0x07,
CDRExampleStateError = 0x0F
CDRExampleStateSkipped = 0x01,
CDRExampleStatePassed = 0x03,
CDRExampleStatePending = 0x07,
CDRExampleStateFailed = 0x0F,
CDRExampleStateError = 0x1F
};
typedef enum CDRExampleState CDRExampleState;

@interface CDRExampleBase : NSObject {
NSString *text_;
id<CDRExampleParent> parent_;
BOOL focused_;
}

@property (nonatomic, readonly) NSString *text;
@property (nonatomic, assign) id<CDRExampleParent> parent;
@property (nonatomic, assign, getter=isFocused) BOOL focused;

- (id)initWithText:(NSString *)text;

- (void)run;
- (BOOL)shouldRun;

- (BOOL)hasChildren;
- (BOOL)hasFocusedExamples;

- (NSString *)message;
- (NSString *)fullText;
@end
Expand Down
2 changes: 2 additions & 0 deletions Source/Headers/CDRExampleParent.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

@protocol CDRExampleParent

- (BOOL)shouldRun;

- (void)setUp;
- (void)tearDown;

Expand Down
Loading

0 comments on commit 0d6d16e

Please sign in to comment.