From a3233211adac4584a56ac22be21a3103fbb449a4 Mon Sep 17 00:00:00 2001 From: Sam Coward Date: Fri, 15 Apr 2016 14:48:04 -0400 Subject: [PATCH] Only call +before/afterEach on CDRHooks conformers (#387) * Only call +before/afterEach on CDRHooks conformers Rebased from and added more tests from #365 --- Cedar.xcodeproj/project.pbxproj | 28 +++--- Source/CDRFunctions.m | 18 ++-- Source/Doubles/CDRSpyInfo.mm | 3 +- Source/Doubles/CedarDoubleImpl.mm | 5 +- Source/Headers/Public/CDRHooks.h | 6 ++ Spec/CDRHooksSpec.mm | 104 ++++++++++++++++++++++ Spec/Doubles/CedarDoubleSharedExamples.mm | 1 + Spec/GlobalBeforeEachSpec.mm | 36 -------- Spec/SpecSpec.mm | 1 - 9 files changed, 139 insertions(+), 63 deletions(-) create mode 100644 Spec/CDRHooksSpec.mm delete mode 100644 Spec/GlobalBeforeEachSpec.mm diff --git a/Cedar.xcodeproj/project.pbxproj b/Cedar.xcodeproj/project.pbxproj index db953546..f97bc91e 100644 --- a/Cedar.xcodeproj/project.pbxproj +++ b/Cedar.xcodeproj/project.pbxproj @@ -492,7 +492,7 @@ 34D7C4AC1BB9C6C400E8E523 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; 34D7C4AD1BB9C6C400E8E523 /* CDRSymbolicatorSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */; }; 34D7C4AE1BB9C6C400E8E523 /* CDRSpecFailureSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */; }; - 34D7C4AF1BB9C6C400E8E523 /* GlobalBeforeEachSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* GlobalBeforeEachSpec.mm */; }; + 34D7C4AF1BB9C6C400E8E523 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; 34D7C4B01BB9C6C400E8E523 /* ObjCHeadersSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */; }; 34D7C4B11BB9C6C400E8E523 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; 34D7C4B21BB9C6C700E8E523 /* CDRTypeUtilitiesSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */; }; @@ -571,7 +571,7 @@ 34FD46601B99D2F200257186 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; 34FD46611B99D2F200257186 /* CDRSymbolicatorSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */; }; 34FD46621B99D2F200257186 /* CDRSpecFailureSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */; }; - 34FD46631B99D2F200257186 /* GlobalBeforeEachSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* GlobalBeforeEachSpec.mm */; }; + 34FD46631B99D2F200257186 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; 34FD46641B99D2F200257186 /* ObjCHeadersSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */; }; 34FD46651B99D2F200257186 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; 34FD46661B99D2F900257186 /* CDRTypeUtilitiesSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */; }; @@ -705,7 +705,7 @@ AE1937671B1AC22D008C8CD8 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; AE1937681B1AC22D008C8CD8 /* CDRSymbolicatorSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */; }; AE1937691B1AC22D008C8CD8 /* CDRSpecFailureSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */; }; - AE19376A1B1AC22D008C8CD8 /* GlobalBeforeEachSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* GlobalBeforeEachSpec.mm */; }; + AE19376A1B1AC22D008C8CD8 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; AE19376B1B1AC22D008C8CD8 /* ObjCHeadersSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */; }; AE19376C1B1AC22D008C8CD8 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; AE19376E1B1AC22D008C8CD8 /* CDRTypeUtilitiesSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */; }; @@ -758,7 +758,7 @@ AE31A29F19C0F23F00C438C1 /* CDRXCTestSuite.h in Headers */ = {isa = PBXBuildFile; fileRef = AE31A29D19C0F23F00C438C1 /* CDRXCTestSuite.h */; }; AE31A2A119C0F23F00C438C1 /* CDRXCTestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = AE31A29E19C0F23F00C438C1 /* CDRXCTestSuite.m */; }; AE31A2A219C0F23F00C438C1 /* CDRXCTestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = AE31A29E19C0F23F00C438C1 /* CDRXCTestSuite.m */; }; - AE34722819C11872005CA6F1 /* GlobalBeforeEachSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* GlobalBeforeEachSpec.mm */; }; + AE34722819C11872005CA6F1 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; AE34722A19C118C9005CA6F1 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; AE34722F19C124CE005CA6F1 /* CDRExampleSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */; }; AE34723019C124CE005CA6F1 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; @@ -1047,7 +1047,7 @@ AEEE21BE11DC290400029872 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; AEEE21BF11DC290400029872 /* CDRExampleSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */; }; AEEE21C111DC290400029872 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FEF11DC27B800029872 /* main.mm */; }; - AEEE21C211DC290400029872 /* GlobalBeforeEachSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* GlobalBeforeEachSpec.mm */; }; + AEEE21C211DC290400029872 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; AEEE21C311DC290400029872 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; AEEE21C411DC290400029872 /* SpecSpec2.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF211DC27B800029872 /* SpecSpec2.m */; }; AEEE220311DC29AC00029872 /* Cedar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEEE1FB611DC271300029872 /* Cedar.framework */; }; @@ -1064,7 +1064,7 @@ AEEE226211DC2C8300029872 /* CDRSpecHelper.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FDB11DC27B800029872 /* CDRSpecHelper.h */; }; AEEE227E11DC2D3A00029872 /* libCedar.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AEEE222911DC2B0600029872 /* libCedar.a */; }; AEEE228011DC2D5200029872 /* CDRExampleSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */; }; - AEEE228311DC2D5200029872 /* GlobalBeforeEachSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* GlobalBeforeEachSpec.mm */; }; + AEEE228311DC2D5200029872 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; AEEE228411DC2D5200029872 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; AEEE228511DC2D5200029872 /* SpecSpec2.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF211DC27B800029872 /* SpecSpec2.m */; }; AEEE228711DC2D5800029872 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FED11DC27B800029872 /* main.mm */; }; @@ -1617,7 +1617,7 @@ AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRExampleSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEEE1FED11DC27B800029872 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; AEEE1FEF11DC27B800029872 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; - AEEE1FF011DC27B800029872 /* GlobalBeforeEachSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GlobalBeforeEachSpec.mm; sourceTree = ""; }; + AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRHooksSpec.mm; sourceTree = ""; }; AEEE1FF111DC27B800029872 /* SpecSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SpecSpec.mm; sourceTree = ""; }; AEEE1FF211DC27B800029872 /* SpecSpec2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpecSpec2.m; sourceTree = ""; }; AEEE218611DC28E200029872 /* Cedar-OSX Specs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "Cedar-OSX Specs"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2341,7 +2341,7 @@ 9672F0A81615C3F40012ED58 /* CDRSpecSpec.mm */, 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */, 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */, - AEEE1FF011DC27B800029872 /* GlobalBeforeEachSpec.mm */, + AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */, AEEE1FEF11DC27B800029872 /* main.mm */, 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */, AEEE1FF111DC27B800029872 /* SpecSpec.mm */, @@ -3519,7 +3519,7 @@ AE34723D19C22547005CA6F1 /* CDRDefaultReporterSpec.mm in Sources */, AE34724619C225A1005CA6F1 /* CDRXCTestSuiteSpec.mm in Sources */, F78FDA1A1B43AA930054C768 /* HaveReceivedSpec.mm in Sources */, - AE34722819C11872005CA6F1 /* GlobalBeforeEachSpec.mm in Sources */, + AE34722819C11872005CA6F1 /* CDRHooksSpec.mm in Sources */, 1F45A3D1180E4796003C1E36 /* CDRSpecFailureSpec.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3611,7 +3611,7 @@ 34FD46311B99D22700257186 /* ArgumentReleaser.m in Sources */, 34FD46371B99D23800257186 /* SimpleIncrementer.m in Sources */, 34FD462D1B99D21300257186 /* CDRDefaultReporterSpec.mm in Sources */, - 34FD46631B99D2F200257186 /* GlobalBeforeEachSpec.mm in Sources */, + 34FD46631B99D2F200257186 /* CDRHooksSpec.mm in Sources */, 34FD465A1B99D2E300257186 /* CedarDoubleSharedExamples.mm in Sources */, 34FD46501B99D2B000257186 /* RespondToSpec.mm in Sources */, 34FD46661B99D2F900257186 /* CDRTypeUtilitiesSpec.mm in Sources */, @@ -3726,7 +3726,7 @@ 34D7C4AC1BB9C6C400E8E523 /* CDRExampleGroupSpec.mm in Sources */, 34D7C4851BB9C62400E8E523 /* DeallocNotifier.m in Sources */, 34D7C4891BB9C67400E8E523 /* CDRSpyiOSSpec.mm in Sources */, - 34D7C4AF1BB9C6C400E8E523 /* GlobalBeforeEachSpec.mm in Sources */, + 34D7C4AF1BB9C6C400E8E523 /* CDRHooksSpec.mm in Sources */, 34D7C48D1BB9C67C00E8E523 /* BeGTESpec.mm in Sources */, 34D7C47A1BB9B7AD00E8E523 /* FibonacciCalculator.m in Sources */, 34D7C4961BB9C67C00E8E523 /* ConformToSpec.mm in Sources */, @@ -3895,7 +3895,7 @@ AE1937951B1AC94D008C8CD8 /* MutableEqualSpec.mm in Sources */, AE19375F1B1AC22D008C8CD8 /* CDRSpySpec.mm in Sources */, AE1937991B1AC94D008C8CD8 /* ContainSpec.mm in Sources */, - AE19376A1B1AC22D008C8CD8 /* GlobalBeforeEachSpec.mm in Sources */, + AE19376A1B1AC22D008C8CD8 /* CDRHooksSpec.mm in Sources */, AE1937761B1AC3DC008C8CD8 /* ObjectWithCollections.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4048,7 +4048,7 @@ AEEE21BF11DC290400029872 /* CDRExampleSpec.mm in Sources */, AEEE21BE11DC290400029872 /* CDRExampleGroupSpec.mm in Sources */, AEEE21C111DC290400029872 /* main.mm in Sources */, - AEEE21C211DC290400029872 /* GlobalBeforeEachSpec.mm in Sources */, + AEEE21C211DC290400029872 /* CDRHooksSpec.mm in Sources */, AEEE21C311DC290400029872 /* SpecSpec.mm in Sources */, AE8C87AE136245BB006C9305 /* ExpectFailureWithMessage.mm in Sources */, 96EA1CBA142C6560001A78E0 /* CDRSpecFailureSpec.mm in Sources */, @@ -4171,7 +4171,7 @@ buildActionMask = 2147483647; files = ( AEEE228011DC2D5200029872 /* CDRExampleSpec.mm in Sources */, - AEEE228311DC2D5200029872 /* GlobalBeforeEachSpec.mm in Sources */, + AEEE228311DC2D5200029872 /* CDRHooksSpec.mm in Sources */, AEEE228411DC2D5200029872 /* SpecSpec.mm in Sources */, 1FDCD5601821D3BB00B511DB /* BeNil_ARCSpec.mm in Sources */, AEEE228511DC2D5200029872 /* SpecSpec2.m in Sources */, diff --git a/Source/CDRFunctions.m b/Source/CDRFunctions.m index cb7d2d1e..ec33ea37 100644 --- a/Source/CDRFunctions.m +++ b/Source/CDRFunctions.m @@ -1,6 +1,7 @@ #import #import #import "CDRSpec.h" +#import "CDRHooks.h" #import "CDRExampleGroup.h" #import "CDRExampleReporter.h" #import "CDRDefaultReporter.h" @@ -105,22 +106,21 @@ void CDRDefineSharedExampleGroups() { } BOOL CDRClassHasClassMethod(Class class, SEL selector) { - const char *className = class_getName(class); - if (strcmp("UIAccessibilitySafeCategory__NSObject", className) && - strcmp("SCRCException", className)) { + if (class_conformsToProtocol(class, @protocol(CDRHooks))) { return !!class_getClassMethod(class, selector); } return NO; } -void CDRDefineGlobalBeforeAndAfterEachBlocks() { - [CDRSpecHelper specHelper].globalBeforeEachClasses = CDRSelectClasses(^BOOL(Class class) { - return CDRClassHasClassMethod(class, @selector(beforeEach)); +NSArray *CDRHooksClassesWithSelector(SEL selector) { + return CDRSelectClasses(^BOOL(Class class) { + return class_conformsToProtocol(class, @protocol(CDRHooks)) && !!class_getClassMethod(class, selector); }); +} - [CDRSpecHelper specHelper].globalAfterEachClasses = CDRSelectClasses(^BOOL(Class class) { - return CDRClassHasClassMethod(class, @selector(afterEach)); - }); +void CDRDefineGlobalBeforeAndAfterEachBlocks() { + [CDRSpecHelper specHelper].globalBeforeEachClasses = CDRHooksClassesWithSelector(@selector(beforeEach)); + [CDRSpecHelper specHelper].globalAfterEachClasses = CDRHooksClassesWithSelector(@selector(afterEach)); } #pragma mark - Reporters diff --git a/Source/Doubles/CDRSpyInfo.mm b/Source/Doubles/CDRSpyInfo.mm index bdea9995..cf65377d 100644 --- a/Source/Doubles/CDRSpyInfo.mm +++ b/Source/Doubles/CDRSpyInfo.mm @@ -1,11 +1,12 @@ #import "CDRSpyInfo.h" #import "CDRSpy.h" +#import "CDRHooks.h" #import "CedarDoubleImpl.h" #import static NSHashTable *currentSpies__; -@interface CDRSpyInfo () +@interface CDRSpyInfo () @property (nonatomic, assign) id originalObject; @property (nonatomic, weak) id weakOriginalObject; @end diff --git a/Source/Doubles/CedarDoubleImpl.mm b/Source/Doubles/CedarDoubleImpl.mm index 3b327730..0242dfe8 100644 --- a/Source/Doubles/CedarDoubleImpl.mm +++ b/Source/Doubles/CedarDoubleImpl.mm @@ -1,10 +1,11 @@ #import "CedarDoubleImpl.h" +#import "CDRHooks.h" using namespace Cedar::Doubles; static NSMutableArray *registeredDoubleImpls__ = nil; -@interface CedarDoubleImpl () { +@interface CedarDoubleImpl () { StubbedMethod::selector_map_t stubbed_methods_; NSMutableArray *sent_messages_; NSObject *parent_double_; @@ -54,7 +55,7 @@ - (NSArray *)sent_messages_with_selector:(SEL)selector { [sentMessages addObject:invocation]; } } - + return [sentMessages autorelease]; } diff --git a/Source/Headers/Public/CDRHooks.h b/Source/Headers/Public/CDRHooks.h index d1070717..497ab59b 100644 --- a/Source/Headers/Public/CDRHooks.h +++ b/Source/Headers/Public/CDRHooks.h @@ -1,5 +1,11 @@ #import +/** + * CDRHooks + * + * Conform classes to this protocol if you want to register global + * beforeEach and afterEach blocks that are called for all specs + */ @protocol CDRHooks @optional diff --git a/Spec/CDRHooksSpec.mm b/Spec/CDRHooksSpec.mm new file mode 100644 index 00000000..72702273 --- /dev/null +++ b/Spec/CDRHooksSpec.mm @@ -0,0 +1,104 @@ +#import "Cedar.h" +#import "CDRSpec.h" +#import "CDRSpecRun.h" + +static BOOL conformantClassBeforeEachWasTriggered__ = NO; +static BOOL conformantClassBeforeEachWasTriggeredBeforeSpecBeforeEach__ = NO; +static BOOL nonConformantClassBeforeEachWasTriggered__ = NO; +static BOOL conformantClassAfterEachWasTriggered__ = NO; +static BOOL conformantClassAfterEachWasTriggeredBeforeSpecAfterEach__ = NO; +static BOOL nonConformantClassAfterEachWasTriggered__ = NO; + +using namespace Cedar::Matchers; + + +@interface ClassThatDoesntConformToCDRHooks : NSObject +@end + +@interface ClassThatConformsToCDRHooks : NSObject +@end + +@interface ClassThatConformsToCDRHooks () +@end + +@implementation ClassThatConformsToCDRHooks ++ (void)beforeEach { + conformantClassBeforeEachWasTriggered__ = YES; +} + ++ (void)afterEach { + conformantClassAfterEachWasTriggered__ = YES; +} +@end + +@implementation ClassThatDoesntConformToCDRHooks ++ (void)beforeEach { + nonConformantClassBeforeEachWasTriggered__ = YES; +} + ++ (void)afterEach { + nonConformantClassAfterEachWasTriggered__ = YES; +} +@end + +@interface DummySpecForTestingHooks : CDRSpec +@end +@implementation DummySpecForTestingHooks +- (void)declareBehaviors { + self.fileName = [NSString stringWithUTF8String:__FILE__]; + beforeEach(^{ + conformantClassBeforeEachWasTriggeredBeforeSpecBeforeEach__ = conformantClassBeforeEachWasTriggered__; + }); + it(@"just needs to have a spec", ^{ + }); + afterEach(^{ + conformantClassAfterEachWasTriggeredBeforeSpecAfterEach__ = conformantClassAfterEachWasTriggered__; + }); +} +@end + +SPEC_BEGIN(CDRHooksSpec) + +//NB: If you focus any test here, you must also focus "just needs to run this spec" in DummySpecForTestingHooks +describe(@"CDRHooks", ^{ + beforeEach(^{ + nonConformantClassBeforeEachWasTriggered__ = + nonConformantClassAfterEachWasTriggered__ = + conformantClassBeforeEachWasTriggered__ = + conformantClassBeforeEachWasTriggeredBeforeSpecBeforeEach__ = + conformantClassAfterEachWasTriggered__ = + conformantClassAfterEachWasTriggeredBeforeSpecAfterEach__ = NO; + + CDRSpec *dummySpec = [[[DummySpecForTestingHooks class] alloc] init]; + [dummySpec defineBehaviors]; + + CDRSpecRun *specRun = [[CDRSpecRun alloc] initWithExampleReporters:@[]]; + [specRun performSpecRun:^{ + [dummySpec.rootGroup runWithDispatcher:specRun.dispatcher]; + }]; + }); + + describe(@"+beforeEach", ^{ + it(@"should not call +beforeEach on non-conformant classes", ^{ + expect(nonConformantClassBeforeEachWasTriggered__).to(be_falsy); + }); + + it(@"should run the +beforeEach BEFORE spec beforeEaches for CDRHooks conformers", ^{ + expect(conformantClassBeforeEachWasTriggered__).to(be_truthy); + expect(conformantClassBeforeEachWasTriggeredBeforeSpecBeforeEach__).to(be_truthy); + }); + }); + + describe(@"+afterEach", ^{ + it(@"should not call +afterEach on non-conformant classes", ^{ + expect(nonConformantClassAfterEachWasTriggered__).to(be_falsy); + }); + + it(@"should run the +afterEach AFTER spec afterEaches for CDRHooks conformers", ^{ + expect(conformantClassAfterEachWasTriggered__).to(be_truthy); + expect(conformantClassAfterEachWasTriggeredBeforeSpecAfterEach__).to(be_falsy); + }); + }); +}); + +SPEC_END diff --git a/Spec/Doubles/CedarDoubleSharedExamples.mm b/Spec/Doubles/CedarDoubleSharedExamples.mm index b8a57809..33e29239 100644 --- a/Spec/Doubles/CedarDoubleSharedExamples.mm +++ b/Spec/Doubles/CedarDoubleSharedExamples.mm @@ -95,6 +95,7 @@ myDouble.retainCount should equal(doubleRetainCount + numInvocations); + [CedarDoubleImpl class] should conform_to(@protocol(CDRHooks)); [CedarDoubleImpl afterEach]; myDouble.retainCount should equal(doubleRetainCount); diff --git a/Spec/GlobalBeforeEachSpec.mm b/Spec/GlobalBeforeEachSpec.mm deleted file mode 100644 index 1763dcfa..00000000 --- a/Spec/GlobalBeforeEachSpec.mm +++ /dev/null @@ -1,36 +0,0 @@ -#import "Cedar.h" - -static unsigned int globalValue__ = 0; - -using namespace Cedar::Matchers; - -@interface SomeClass : NSObject -@end - -@implementation SomeClass -+ (void)beforeEach { - globalValue__ = 1; -} - -+ (void)afterEach { -// NSLog(@"=====================> AFTER EACH 1"); -} -@end - - -SPEC_BEGIN(GlobalBeforeEachSpec) - -describe(@"global beforeEach", ^{ - it(@"should run before all specs", ^{ - expect(globalValue__).to(equal(1)); - }); -}); - -describe(@"global afterEach", ^{ - it(@"should run after all specs", ^{ - // Uncomment the line in the afterEach method, run, and check console output. - }); -}); - - -SPEC_END diff --git a/Spec/SpecSpec.mm b/Spec/SpecSpec.mm index 0e38ccaa..62be21de 100644 --- a/Spec/SpecSpec.mm +++ b/Spec/SpecSpec.mm @@ -205,7 +205,6 @@ void expectFailure(CDRSpecBlock block) { globalValue__ = @"something"; }); - expect(globalValue__).to(be_nil); itShouldBehaveLike(@"a shared example group that receives a value in the context", ^(NSMutableDictionary *context) { context[@"value"] = globalValue__; });