diff --git a/Cedar.xcodeproj/project.pbxproj b/Cedar.xcodeproj/project.pbxproj index 95f9872b..db953546 100644 --- a/Cedar.xcodeproj/project.pbxproj +++ b/Cedar.xcodeproj/project.pbxproj @@ -266,13 +266,16 @@ 34ADD2EE19220F9300B057AC /* AnyInstanceConformingToProtocolArgument.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 34ADD2E41921F2F600B057AC /* AnyInstanceConformingToProtocolArgument.h */; }; 34ADE41818F23C8E00BD1E99 /* NSMethodSignature+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ADE41618F23C8E00BD1E99 /* NSMethodSignature+Cedar.m */; }; 34ADE41918F23E6B00BD1E99 /* NSMethodSignature+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ADE41618F23C8E00BD1E99 /* NSMethodSignature+Cedar.m */; }; + 34AF814E1C53339300DB5249 /* TestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 34AF814D1C53339300DB5249 /* TestReporter.m */; }; + 34AF814F1C53A06500DB5249 /* TestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 34AF814D1C53339300DB5249 /* TestReporter.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 34AF81501C53A06600DB5249 /* TestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 34AF814D1C53339300DB5249 /* TestReporter.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34C95F501C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34C95F511C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34C95F521C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34C95F531C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34C95F541C2DD7B30055F089 /* CDRNullabilityCompat.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */; }; 34C95F551C2E57A90055F089 /* SwiftSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DB67481C2B4D6A00206663 /* SwiftSpec.swift */; }; - 34C95F561C2F16900055F089 /* CDRXCTestSuiteSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 34C95F561C2F16900055F089 /* CDRXCTestSuiteSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */; }; 34D1819C1BC7F0E60087EC0D /* BlockMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 346F64681B82D01700F64156 /* BlockMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D1819D1BC7F0E70087EC0D /* BlockMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 346F64681B82D01700F64156 /* BlockMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D1819E1BC7F0FD0087EC0D /* BlockMatcherSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 346F646D1B82D3C900F64156 /* BlockMatcherSpec.mm */; }; @@ -448,7 +451,7 @@ 34D7C4831BB9C61A00E8E523 /* ObjectWithValueEquality.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D28051818E2321D00887CC4 /* ObjectWithValueEquality.m */; }; 34D7C4841BB9C61E00E8E523 /* FooSuperclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AED10EBB18F46C0E00950904 /* FooSuperclass.m */; }; 34D7C4851BB9C62400E8E523 /* DeallocNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 343FAFE9190FDAEC0085AFEC /* DeallocNotifier.m */; }; - 34D7C4861BB9C65700E8E523 /* CDRXCTestSuiteSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */; }; + 34D7C4861BB9C65700E8E523 /* CDRXCTestSuiteSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34D7C4871BB9C66000E8E523 /* CedarApplicationDelegateSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE7DD11117296CB20058EB3B /* CedarApplicationDelegateSpec.mm */; }; 34D7C4881BB9C67100E8E523 /* WeakReferenceCompatibilitySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE5218D4175979D900A656BC /* WeakReferenceCompatibilitySpec.mm */; }; 34D7C4891BB9C67400E8E523 /* CDRSpyiOSSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 228F3FA617E3ECD10000C8AF /* CDRSpyiOSSpec.mm */; }; @@ -763,7 +766,7 @@ AE34723719C12534005CA6F1 /* FibonacciCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = E32861311604F287001FA77E /* FibonacciCalculator.m */; }; AE34723919C12588005CA6F1 /* SimpleKeyValueObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788C183C71950078C608 /* SimpleKeyValueObserver.m */; }; AE34723D19C22547005CA6F1 /* CDRDefaultReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBCDD7E173ACD6700B42B58 /* CDRDefaultReporterSpec.mm */; }; - AE34724619C225A1005CA6F1 /* CDRXCTestSuiteSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */; }; + AE34724619C225A1005CA6F1 /* CDRXCTestSuiteSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE34724B19C37ECF005CA6F1 /* CDRXCTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = AE34724919C37ECF005CA6F1 /* CDRXCTestCase.h */; }; AE34724D19C37ECF005CA6F1 /* CDRXCTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = AE34724A19C37ECF005CA6F1 /* CDRXCTestCase.m */; }; AE34724E19C37ECF005CA6F1 /* CDRXCTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = AE34724A19C37ECF005CA6F1 /* CDRXCTestCase.m */; }; @@ -1427,6 +1430,8 @@ 34ADD2E41921F2F600B057AC /* AnyInstanceConformingToProtocolArgument.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnyInstanceConformingToProtocolArgument.h; sourceTree = ""; }; 34ADD2E51921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AnyInstanceConformingToProtocolArgument.mm; sourceTree = ""; }; 34ADE41618F23C8E00BD1E99 /* NSMethodSignature+Cedar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMethodSignature+Cedar.m"; sourceTree = ""; }; + 34AF814C1C53339300DB5249 /* TestReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestReporter.h; sourceTree = ""; }; + 34AF814D1C53339300DB5249 /* TestReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestReporter.m; sourceTree = ""; }; 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRNullabilityCompat.h; sourceTree = ""; }; 34D1E67A18F7A2E6005161AD /* AnInstanceOf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AnInstanceOf.h; path = ../Comparators/AnInstanceOf.h; sourceTree = ""; }; 34D4B5C118F3ADFF00FB2C3B /* UIKitContainSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UIKitContainSpec.mm; sourceTree = ""; }; @@ -2504,6 +2509,8 @@ AED10EBB18F46C0E00950904 /* FooSuperclass.m */, 343FAFE8190FDAEC0085AFEC /* DeallocNotifier.h */, 343FAFE9190FDAEC0085AFEC /* DeallocNotifier.m */, + 34AF814C1C53339300DB5249 /* TestReporter.h */, + 34AF814D1C53339300DB5249 /* TestReporter.m */, ); path = Support; sourceTree = ""; @@ -3506,6 +3513,7 @@ 1F45A3D0180E4796003C1E36 /* CDRSymbolicatorSpec.mm in Sources */, AE34723919C12588005CA6F1 /* SimpleKeyValueObserver.m in Sources */, F78FDA1B1B43AB540054C768 /* SimpleIncrementer.m in Sources */, + 34AF814F1C53A06500DB5249 /* TestReporter.m in Sources */, AE34723419C124D6005CA6F1 /* ObjCHeadersSpec.mm in Sources */, 34322B0C1BA7471B00D0CFBD /* TestObservationHelper.m in Sources */, AE34723D19C22547005CA6F1 /* CDRDefaultReporterSpec.mm in Sources */, @@ -3766,6 +3774,7 @@ 34D7C4861BB9C65700E8E523 /* CDRXCTestSuiteSpec.mm in Sources */, 34D7C4931BB9C67C00E8E523 /* BeSameInstanceAs_ARCSpec.mm in Sources */, 34D7C47F1BB9C60A00E8E523 /* SimpleIncrementer.m in Sources */, + 34AF81501C53A06600DB5249 /* TestReporter.m in Sources */, 34D7C4B11BB9C6C400E8E523 /* SpecSpec.mm in Sources */, 34D7C47C1BB9C5FD00E8E523 /* ObjectWithProperty.m in Sources */, 34D1819E1BC7F0FD0087EC0D /* BlockMatcherSpec.mm in Sources */, @@ -3907,6 +3916,7 @@ 34757E261BA4A48E0047BC8D /* TestObservationHelper.m in Sources */, 346D1A971BBB37F400BECD4B /* SpecBundleApplicationTestsWithXCTest.m in Sources */, 345B1E8F1C31DA6E009BB77D /* XCTAssertSpec.swift in Sources */, + 34AF814E1C53339300DB5249 /* TestReporter.m in Sources */, 34C95F561C2F16900055F089 /* CDRXCTestSuiteSpec.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Source/Headers/Project/XCTest/NSInvocation+CDRXExample.h b/Source/Headers/Project/XCTest/NSInvocation+CDRXExample.h index 96b522de..1cfa9529 100644 --- a/Source/Headers/Project/XCTest/NSInvocation+CDRXExample.h +++ b/Source/Headers/Project/XCTest/NSInvocation+CDRXExample.h @@ -6,7 +6,9 @@ @interface NSInvocation (CDRXExample) @property (nonatomic, retain, setter=cdr_setDispatcher:) CDRReportDispatcher *cdr_dispatcher; -@property (nonatomic, retain, setter=cdr_setExample:) CDRExample *cdr_example; +@property (nonatomic, retain, setter=cdr_setExamples:) NSArray *cdr_examples; @property (nonatomic, retain, setter=cdr_setSpecClassName:) NSString *cdr_specClassName; +- (void)cdr_addSupplementaryExample:(CDRExample *)example; + @end diff --git a/Source/XCTest/CDRSpec+XCTestSupport.m b/Source/XCTest/CDRSpec+XCTestSupport.m index 07b353c9..624f104f 100644 --- a/Source/XCTest/CDRSpec+XCTestSupport.m +++ b/Source/XCTest/CDRSpec+XCTestSupport.m @@ -46,8 +46,15 @@ - (id)testSuiteWithRandomSeed:(unsigned int)seed dispatcher:(CDRReportDispatcher NSArray *examples = [self allExamplesToRun]; NSMutableArray *testInvocations = [NSMutableArray array]; + NSMutableArray *unusedPendingExamples = [NSMutableArray array]; for (CDRExample *example in examples) { - if (!example.isPending) { + if (example.isPending) { + if (testInvocations.count > 0) { + [[testInvocations lastObject] cdr_addSupplementaryExample:example]; + } else { + [unusedPendingExamples addObject:example]; + } + } else { NSString *methodName = [namer methodNameForExample:example withClassName:NSStringFromClass([self class])]; SEL selector = NSSelectorFromString(methodName); NSMethodSignature *methodSignature = [newXCTestSubclass instanceMethodSignatureForSelector:selector]; @@ -60,9 +67,11 @@ - (id)testSuiteWithRandomSeed:(unsigned int)seed dispatcher:(CDRReportDispatcher NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; invocation.selector = selector; invocation.cdr_dispatcher = dispatcher; - invocation.cdr_example = example; + invocation.cdr_examples = [unusedPendingExamples arrayByAddingObject:example]; invocation.cdr_specClassName = className; [testInvocations addObject:invocation]; + + [unusedPendingExamples removeAllObjects]; } } @@ -109,13 +118,17 @@ - (NSArray *)allExamplesToRun { return examples; } -- (void)createTestMethodForSelector:(SEL)selector onClass:(Class)aClass { - IMP imp = imp_implementationWithBlock(^(id instance){ - CDRExample *example = [[instance invocation] cdr_example]; +static void testMethodImplementation(id instance, SEL _cmd) { + NSMutableSet *alreadyReportedExampleGroups = [NSMutableSet set]; + CDRReportDispatcher *theDispatcher = [[instance invocation] cdr_dispatcher]; + + for (CDRExample *example in [[instance invocation] cdr_examples]) { CDRExampleGroup *parentGroup = (CDRExampleGroup *)example.parent; - CDRReportDispatcher *theDispatcher = [[instance invocation] cdr_dispatcher]; while (![parentGroup isEqual:example.spec.rootGroup]) { - [theDispatcher runWillStartExampleGroup:parentGroup]; + if (![alreadyReportedExampleGroups containsObject:parentGroup]) { + [theDispatcher runWillStartExampleGroup:parentGroup]; + } + parentGroup = (CDRExampleGroup *)[parentGroup parent]; } @@ -133,14 +146,20 @@ - (void)createTestMethodForSelector:(SEL)selector onClass:(Class)aClass { parentGroup = (CDRExampleGroup *)example.parent; while (![parentGroup isEqual:example.spec.rootGroup]) { - [theDispatcher runDidFinishExampleGroup:parentGroup]; + if (![alreadyReportedExampleGroups containsObject:parentGroup]) { + [theDispatcher runDidFinishExampleGroup:parentGroup]; + [alreadyReportedExampleGroups addObject:parentGroup]; + } + parentGroup = (CDRExampleGroup *)[parentGroup parent]; } - }); - Method m = class_getInstanceMethod([self class], @selector(defineBehaviors)); + } +} +- (void)createTestMethodForSelector:(SEL)selector onClass:(Class)aClass { + Method m = class_getInstanceMethod([self class], @selector(defineBehaviors)); const char *encoding = method_getTypeEncoding(m); - class_addMethod(aClass, selector, imp, encoding); + class_addMethod(aClass, selector, (IMP)testMethodImplementation, encoding); } @end diff --git a/Source/XCTest/CDRXCTestCase.m b/Source/XCTest/CDRXCTestCase.m index e156b75f..92d20ad5 100644 --- a/Source/XCTest/CDRXCTestCase.m +++ b/Source/XCTest/CDRXCTestCase.m @@ -52,7 +52,8 @@ + (void)setTestInvocations:(NSArray *)array { } while(0); - (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filename atLine:(NSUInteger)lineNumber expected:(BOOL)expected { - if (self.invocation.cdr_example.state == CDRExampleStateIncomplete) { + CDRExample *example = self.invocation.cdr_examples.firstObject; + if (example.state == CDRExampleStateIncomplete) { [[CDRSpecFailure specFailureWithReason:description fileName:filename lineNumber:(int)lineNumber] raise]; } else { super_recordFailure(description, filename, lineNumber, expected); diff --git a/Source/XCTest/NSInvocation+CDRXExample.m b/Source/XCTest/NSInvocation+CDRXExample.m index 808a231c..72c192d7 100644 --- a/Source/XCTest/NSInvocation+CDRXExample.m +++ b/Source/XCTest/NSInvocation+CDRXExample.m @@ -2,7 +2,7 @@ #import const char *CDRXDispatcherKey; -const char *CDRXExampleKey; +const char *CDRXExamplesKey; const char *CDRXSpecClassNameKey; @@ -16,12 +16,12 @@ - (void)cdr_setDispatcher:(CDRReportDispatcher *)dispatcher { objc_setAssociatedObject(self, &CDRXDispatcherKey, dispatcher, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -- (CDRExample *)cdr_example { - return objc_getAssociatedObject(self, &CDRXExampleKey); +- (NSArray *)cdr_examples { + return objc_getAssociatedObject(self, &CDRXExamplesKey); } -- (void)cdr_setExample:(CDRExample *)example { - objc_setAssociatedObject(self, &CDRXExampleKey, example, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +- (void)cdr_setExamples:(NSArray *)examples { + objc_setAssociatedObject(self, &CDRXExamplesKey, examples, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSString *)cdr_specClassName { @@ -32,4 +32,9 @@ - (void)cdr_setSpecClassName:(NSString *)specClassName { objc_setAssociatedObject(self, &CDRXSpecClassNameKey, specClassName, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } +- (void)cdr_addSupplementaryExample:(CDRExample *)example { + NSArray *existingExamples = self.cdr_examples ?: @[]; + self.cdr_examples = [existingExamples arrayByAddingObject:example]; +} + @end diff --git a/Spec/Support/TestReporter.h b/Spec/Support/TestReporter.h new file mode 100644 index 00000000..0b59e9bc --- /dev/null +++ b/Spec/Support/TestReporter.h @@ -0,0 +1,17 @@ +#import +#import "Cedar.h" +#import "CDRNullabilityCompat.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface TestReporter : NSObject + +@property (nonatomic, readonly) NSArray *startedExamples; +@property (nonatomic, readonly) NSArray *finishedExamples; + +@property (nonatomic, readonly) NSArray *startedExampleGroups; +@property (nonatomic, readonly) NSArray *finishedExampleGroups; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Spec/Support/TestReporter.m b/Spec/Support/TestReporter.m new file mode 100644 index 00000000..1c458155 --- /dev/null +++ b/Spec/Support/TestReporter.m @@ -0,0 +1,47 @@ +#import "TestReporter.h" + +#if !__has_feature(objc_arc) +#error This class must be compiled with ARC. +#endif + +@implementation TestReporter { + NSMutableArray *_startedExamples; + NSMutableArray *_finishedExamples; + NSMutableArray *_startedExampleGroups; + NSMutableArray *_finishedExampleGroups; +} + +- (instancetype)init { + if (self = [super init]) { + _startedExamples = [NSMutableArray array]; + _finishedExamples = [NSMutableArray array]; + _startedExampleGroups = [NSMutableArray array]; + _finishedExampleGroups = [NSMutableArray array]; + } + return self; +} + +- (void)runWillStartWithGroups:(NSArray *)groups andRandomSeed:(unsigned int)seed {} +- (void)runDidComplete {} +- (int)result { + return 0; +} + +- (void)runWillStartExample:(CDRExample *)example { + [_startedExamples addObject:example]; +} +- (void)runDidFinishExample:(CDRExample *)example { + [_finishedExamples addObject:example]; +} + +- (void)runWillStartExampleGroup:(CDRExampleGroup *)exampleGroup { + [_startedExampleGroups addObject:exampleGroup]; +} +- (void)runDidFinishExampleGroup:(CDRExampleGroup *)exampleGroup { + [_finishedExampleGroups addObject:exampleGroup]; +} + +- (void)runWillStartSpec:(CDRSpec *)spec {} +- (void)runDidFinishSpec:(CDRSpec *)spec {} + +@end diff --git a/Spec/XCTest/CDRXCTestSuiteSpec.mm b/Spec/XCTest/CDRXCTestSuiteSpec.mm index 9f1d1f6c..824d8401 100644 --- a/Spec/XCTest/CDRXCTestSuiteSpec.mm +++ b/Spec/XCTest/CDRXCTestSuiteSpec.mm @@ -1,16 +1,12 @@ -#if TARGET_OS_IPHONE -// Normally you would include this file out of the framework. However, we're -// testing the framework here, so including the file from the framework will -// conflict with the compiler attempting to include the file from the project. -#import "CDRSpecHelper.h" -#else -#import -#endif - -#import "CDRSpec.h" +#import "Cedar.h" #import "CDRXCTestSuite.h" #import "CDRReportDispatcher.h" #import "CDRXCTestSupport.h" +#import "TestReporter.h" + +#if !__has_feature(objc_arc) +#error This class must be compiled with ARC. +#endif using namespace Cedar::Matchers; using namespace Cedar::Doubles; @@ -19,30 +15,30 @@ describe(@"CDRXCTestSuite", ^{ __block id subject; + __block TestReporter *reporter; __block CDRReportDispatcher *dispatcher; - static NSUInteger willStartExampleGroupCount; - static NSUInteger didFinishExampleGroupCount; - - it(@"should report that each parent example group has started and ended to the dispatcher", ^{ - willStartExampleGroupCount = 0; - didFinishExampleGroupCount = 0; - - dispatcher = nice_fake_for([CDRReportDispatcher class]); - dispatcher stub_method(@selector(runWillStartExampleGroup:)).and_do_block(^(CDRExampleGroup *group){ - ++willStartExampleGroupCount; - }); - dispatcher stub_method(@selector(runDidFinishExampleGroup:)).and_do_block(^(CDRExampleGroup *group){ - ++didFinishExampleGroupCount; - }); + beforeEach(^{ + reporter = [TestReporter new]; + dispatcher = [[CDRReportDispatcher alloc] initWithReporters:@[reporter]]; - CDRSpec *simulatedSpec = [[[NSClassFromString(@"CDRXCSimulatedTestSuiteSpec") alloc] init] autorelease]; + CDRSpec *simulatedSpec = [[NSClassFromString(@"CDRXCSimulatedTestSuiteSpec") alloc] init]; [simulatedSpec defineBehaviors]; subject = [simulatedSpec testSuiteWithRandomSeed:0 dispatcher:dispatcher]; [subject performTest:nil]; + }); + + it(@"should report that each parent example group has started and ended", ^{ + reporter.startedExampleGroups.count should equal(4); + reporter.finishedExampleGroups.count should equal(4); + }); - willStartExampleGroupCount should equal(4); - didFinishExampleGroupCount should equal(4); + it(@"should report that pending examples have started and ended", ^{ + NSPredicate *pendingPredicate = [NSPredicate predicateWithBlock:^BOOL(CDRExample *example, NSDictionary *_) { + return example.state == CDRExampleStatePending; + }]; + [reporter.startedExamples filteredArrayUsingPredicate:pendingPredicate].count should equal(2); + [reporter.finishedExamples filteredArrayUsingPredicate:pendingPredicate].count should equal(2); }); }); @@ -55,9 +51,17 @@ dispatcher stub_method(@selector(runDidFinishExampleGroup:)).and_do_block(^(CDRE describe(@"with nested groups", ^{ describe(@"lots of nested groups", ^{ describe(@"no really, lots of nested groups", ^{ + xit(@"should report pending examples before the first test to run", ^{ + 1 should equal(2); + }); + it(@"should start and finish each example group", ^{ // nothing to see here }); + + xit(@"should report pending examples after the last test to run", ^{ + 1 should equal(2); + }); }); }); });