From ec37ef8a383abd60019e99e6a1947a891e0bc499 Mon Sep 17 00:00:00 2001 From: James Cooper Date: Fri, 31 Oct 2014 09:20:29 -0400 Subject: [PATCH 1/2] James C - added an implies matcher (not an implies matcher-combinator yet) --- Cedar.xcodeproj/project.pbxproj | 12 ++ Source/Headers/Matchers/Base/Imply.h | 58 +++++++ Source/Headers/Matchers/CedarMatchers.h | 1 + Spec/Matchers/Base/ImplySpec.mm | 219 ++++++++++++++++++++++++ 4 files changed, 290 insertions(+) create mode 100644 Source/Headers/Matchers/Base/Imply.h create mode 100644 Spec/Matchers/Base/ImplySpec.mm diff --git a/Cedar.xcodeproj/project.pbxproj b/Cedar.xcodeproj/project.pbxproj index 4128d910..a4c22679 100644 --- a/Cedar.xcodeproj/project.pbxproj +++ b/Cedar.xcodeproj/project.pbxproj @@ -75,6 +75,10 @@ 2234907F18009DAD001C8E8D /* CDRHooks.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 2234907C18009DA6001C8E8D /* CDRHooks.h */; }; 228F3FA717E3ECD10000C8AF /* CDRSpyiOSSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 228F3FA617E3ECD10000C8AF /* CDRSpyiOSSpec.mm */; }; 22B6A22715B7ACF800960ADE /* InvocationMatcher.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE597B4015B0638B00EEF305 /* InvocationMatcher.h */; }; + 268A80C81A036D9000798659 /* Imply.h in Headers */ = {isa = PBXBuildFile; fileRef = 268A80C71A036D8400798659 /* Imply.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 268A80C91A036D9100798659 /* Imply.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 268A80C71A036D8400798659 /* Imply.h */; }; + 26F100531A0378DB00975D83 /* ImplySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26F100511A0378CA00975D83 /* ImplySpec.mm */; }; + 26F100541A0378DD00975D83 /* ImplySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26F100511A0378CA00975D83 /* ImplySpec.mm */; }; 3414776E191406E700CBA385 /* ComparatorsContainerConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFF375718FC452E002DA993 /* ComparatorsContainerConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3414776F191406FC00CBA385 /* ComparatorsContainerConvenience.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEFF375718FC452E002DA993 /* ComparatorsContainerConvenience.h */; }; 34147770191408C900CBA385 /* AnInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 34D1E67A18F7A2E6005161AD /* AnInstanceOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -623,6 +627,7 @@ AEEE226211DC2C8300029872 /* CDRSpecHelper.h in Copy headers to framework */, AEC9DEF112C2CC7E0039512D /* CDRColorizedReporter.h in Copy headers to framework */, AE18A7B813F450A700C8872C /* Base.h in Copy headers to framework */, + 268A80C91A036D9100798659 /* Imply.h in Copy headers to framework */, AE18A7B913F450A700C8872C /* BeCloseTo.h in Copy headers to framework */, 2234907F18009DAD001C8E8D /* CDRHooks.h in Copy headers to framework */, AE02E814184ECB0F00414F19 /* ShouldSyntax.h in Copy headers to framework */, @@ -693,6 +698,8 @@ 1FF449B318A0C04D00AF94B0 /* CDRBufferedDefaultReporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = CDRBufferedDefaultReporter.h; sourceTree = ""; }; 2234907C18009DA6001C8E8D /* CDRHooks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRHooks.h; sourceTree = ""; }; 228F3FA617E3ECD10000C8AF /* CDRSpyiOSSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRSpyiOSSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + 268A80C71A036D8400798659 /* Imply.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Imply.h; sourceTree = ""; }; + 26F100511A0378CA00975D83 /* ImplySpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ImplySpec.mm; sourceTree = ""; }; 342F5D0A18F430DB00F38E35 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; 343FAFE8190FDAEC0085AFEC /* DeallocNotifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeallocNotifier.h; sourceTree = ""; }; 343FAFE9190FDAEC0085AFEC /* DeallocNotifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeallocNotifier.m; sourceTree = ""; }; @@ -1724,6 +1731,7 @@ 5898AEAF3FE8C683E6F23C1D /* ConformTo.h */, AEF7300113ECC21E00786282 /* Equal.h */, AE0721E2187518FD0031CC42 /* Exist.h */, + 268A80C71A036D8400798659 /* Imply.h */, AEB45A901496C8D800845D09 /* RaiseException.h */, CA17998C17F89C4B00C38060 /* RespondTo.h */, ); @@ -1748,6 +1756,7 @@ 5898A53A07BC580786243CD0 /* ConformToSpec.mm */, AEF7301913ECC4AE00786282 /* EqualSpec.mm */, AE0721DF187513870031CC42 /* ExistSpec.mm */, + 26F100511A0378CA00975D83 /* ImplySpec.mm */, AEF7301A13ECC4AE00786282 /* MutableEqualSpec.mm */, AEBB92601496C1F000EEBD59 /* RaiseExceptionSpec.mm */, CA17999217F8A0EE00C38060 /* RespondToSpec.mm */, @@ -1886,6 +1895,7 @@ AE4A945E1880792E008566F5 /* RejectedMethod.h in Headers */, AEEE1FFA11DC27B800029872 /* CDRExample.h in Headers */, AEEE1FFC11DC27B800029872 /* CDRExampleGroup.h in Headers */, + 268A80C81A036D9000798659 /* Imply.h in Headers */, 969B6F96160F1FEC00C7C792 /* CDRSymbolicator.h in Headers */, AE84F0DB145B70DD00769F85 /* ShouldSyntax.h in Headers */, 34147770191408C900CBA385 /* AnInstanceOf.h in Headers */, @@ -2582,6 +2592,7 @@ AE9AA68015AB748E00617E1A /* CDRClassFakeSpec.mm in Sources */, AE807893183C71950078C608 /* SimpleKeyValueObserver.m in Sources */, AE9AA69715ADB99800617E1A /* CedarDoubleSharedExamples.mm in Sources */, + 26F100531A0378DB00975D83 /* ImplySpec.mm in Sources */, AE3E8F39184FEEE900633740 /* ObjectWithCollections.m in Sources */, AE74903215B45EBA008EA127 /* CDRProtocolFakeSpec.mm in Sources */, 343FAFEA190FDAEC0085AFEC /* DeallocNotifier.m in Sources */, @@ -2689,6 +2700,7 @@ 1FDCD5611821D3BF00B511DB /* BeSameInstanceAs_ARCSpec.mm in Sources */, AEF7302D13ECC4E700786282 /* BeEmptySpec.mm in Sources */, 228F3FA717E3ECD10000C8AF /* CDRSpyiOSSpec.mm in Sources */, + 26F100541A0378DD00975D83 /* ImplySpec.mm in Sources */, 44B9A71F1888661100CBCA1B /* ExampleWithPublicRunDates.m in Sources */, AE18A80B13F4640600C8872C /* ContainSpec.mm in Sources */, AED10EBD18F46C0E00950904 /* FooSuperclass.m in Sources */, diff --git a/Source/Headers/Matchers/Base/Imply.h b/Source/Headers/Matchers/Base/Imply.h new file mode 100644 index 00000000..b28b5441 --- /dev/null +++ b/Source/Headers/Matchers/Base/Imply.h @@ -0,0 +1,58 @@ +#import +#import "Base.h" + +#pragma mark - private interface +namespace Cedar { namespace Matchers { namespace Private { + + template + class Imply : public Base<> { + private: + Imply & operator=(const Imply &); + + public: + explicit Imply(const T & expectedValue); + ~Imply(); + // Allow default copy ctor. + + template + bool matches(const U &) const; + + protected: + virtual NSString * failure_message_end() const; + + private: + const T & expectedValue_; + }; + + template + Imply::Imply(const T & expectedValue) + : Base<>(), expectedValue_(expectedValue) { + } + + template + Imply::~Imply() { + } + + template + /*virtual*/ NSString * Imply::failure_message_end() const { + NSString * expectedValueString = Stringifiers::string_for(expectedValue_); + return [NSString stringWithFormat:@"imply <%@>", expectedValueString]; + } + + template template + bool Imply::matches(const U & actualValue) const { + return !!expectedValue_ || !actualValue; + } + +}}} + +#pragma mark - public interface +namespace Cedar { namespace Matchers { + template + using CedarImply = Cedar::Matchers::Private::Imply; + + template + CedarImply imply(const T & expectedValue) { + return CedarImply(expectedValue); + } +}} diff --git a/Source/Headers/Matchers/CedarMatchers.h b/Source/Headers/Matchers/CedarMatchers.h index 7c9082bb..d2b71511 100644 --- a/Source/Headers/Matchers/CedarMatchers.h +++ b/Source/Headers/Matchers/CedarMatchers.h @@ -10,6 +10,7 @@ #import "BeGTE.h" #import "BeLessThan.h" #import "BeLTE.h" +#import "Imply.h" #import "RaiseException.h" #import "RespondTo.h" #import "ConformTo.h" diff --git a/Spec/Matchers/Base/ImplySpec.mm b/Spec/Matchers/Base/ImplySpec.mm new file mode 100644 index 00000000..5d4ddac7 --- /dev/null +++ b/Spec/Matchers/Base/ImplySpec.mm @@ -0,0 +1,219 @@ +#if TARGET_OS_IPHONE +#import +#else +#import +#endif + +extern "C" { +#import "ExpectFailureWithMessage.h" +} + +using namespace Cedar::Matchers; + +SPEC_BEGIN(ImplySpec) + +describe(@"implies matcher", ^{ + describe(@"when the values are built-in type", ^{ + describe(@"which evaluates to true", ^{ + describe(@"positive match", ^{ + it(@"should pass", ^{ + expect(true).to(imply(true)); + }); + + it(@"should pass", ^{ + expect(false).to(imply(true)); + }); + + it(@"should pass", ^{ + expect(false).to(imply(false)); + }); + }); + + describe(@"negative match", ^{ + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(true).to_not(imply(true)); + }); + }); + + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(false).to_not(imply(true)); + }); + }); + + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(false).to_not(imply(false)); + }); + }); + }); + }); + + describe(@"which evaluates to false", ^{ + describe(@"positive match", ^{ + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to imply ", ^{ + expect(true).to(imply(false)); + }); + }); + }); + + describe(@"negative match", ^{ + it(@"should should pass", ^{ + expect(true).to_not(imply(false)); + }); + }); + }); + }); + + describe(@"when the value is an id", ^{ + describe(@"which evaluates to true", ^{ + describe(@"positive match", ^{ + it(@"should pass", ^{ + expect(@"wurble").to(imply(@"wurble")); + }); + + it(@"should pass", ^{ + expect(nil).to(imply(@"wurble")); + }); + + it(@"should pass", ^{ + expect(nil).to(imply(nil)); + }); + }); + + describe(@"negative match", ^{ + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(@"wurble").to_not(imply(@"wurble")); + }); + }); + + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(nil).to_not(imply(@"wurble")); + }); + }); + + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(nil).to_not(imply(nil)); + }); + }); + }); + }); + + describe(@"which evaluates to false", ^{ + describe(@"positive match", ^{ + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to imply ", ^{ + expect(@"wurble").to(imply(nil)); + }); + }); + }); + + describe(@"negative match", ^{ + it(@"should should pass", ^{ + expect(@"wurble").to_not(imply(nil)); + }); + }); + }); + }); + + describe(@"when the values are mixed", ^{ + describe(@"which evaluates to true", ^{ + describe(@"positive match", ^{ + it(@"should pass", ^{ + expect(@"wurble").to(imply(true)); + }); + + it(@"should pass", ^{ + expect(nil).to(imply(true)); + }); + + it(@"should pass", ^{ + expect(nil).to(imply(false)); + }); + + it(@"should pass", ^{ + expect(true).to(imply(@"wurble")); + }); + + it(@"should pass", ^{ + expect(false).to(imply(@"wurble")); + }); + + it(@"should pass", ^{ + expect(false).to(imply(nil)); + }); + }); + + describe(@"negative match", ^{ + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(@"wurble").to_not(imply(true)); + }); + }); + + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(nil).to_not(imply(true)); + }); + }); + + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(nil).to_not(imply(false)); + }); + }); + + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(true).to_not(imply(@"wurble")); + }); + }); + + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(false).to_not(imply(@"wurble")); + }); + }); + + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to not imply ", ^{ + expect(false).to_not(imply(nil)); + }); + }); + }); + }); + + describe(@"which evaluates to false", ^{ + describe(@"positive match", ^{ + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to imply ", ^{ + expect(@"wurble").to(imply(false)); + }); + }); + + it(@"should fail with a sensible failure message", ^{ + expectFailureWithMessage(@"Expected to imply ", ^{ + expect(true).to(imply(nil)); + }); + }); + }); + + describe(@"negative match", ^{ + it(@"should should pass", ^{ + expect(@"wurble").to_not(imply(false)); + }); + + it(@"should should pass", ^{ + expect(true).to_not(imply(nil)); + }); + }); + }); + }); +}); + +SPEC_END From b3bcfab9526ef3a942bb8e836595b7bc8ea16b66 Mon Sep 17 00:00:00 2001 From: James Cooper Date: Fri, 31 Oct 2014 13:51:21 -0400 Subject: [PATCH 2/2] James C - fixed tests for Travis --- Spec/Matchers/Base/ImplySpec.mm | 74 ++++++++++++++++----------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/Spec/Matchers/Base/ImplySpec.mm b/Spec/Matchers/Base/ImplySpec.mm index 5d4ddac7..72b7895a 100644 --- a/Spec/Matchers/Base/ImplySpec.mm +++ b/Spec/Matchers/Base/ImplySpec.mm @@ -17,34 +17,34 @@ describe(@"which evaluates to true", ^{ describe(@"positive match", ^{ it(@"should pass", ^{ - expect(true).to(imply(true)); + expect(YES).to(imply(YES)); }); it(@"should pass", ^{ - expect(false).to(imply(true)); + expect(NO).to(imply(YES)); }); it(@"should pass", ^{ - expect(false).to(imply(false)); + expect(NO).to(imply(NO)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(true).to_not(imply(true)); + expect(YES).to_not(imply(YES)); }); }); it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(false).to_not(imply(true)); + expect(NO).to_not(imply(YES)); }); }); it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(false).to_not(imply(false)); + expect(NO).to_not(imply(NO)); }); }); }); @@ -54,14 +54,14 @@ describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to imply ", ^{ - expect(true).to(imply(false)); + expect(YES).to(imply(NO)); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ - expect(true).to_not(imply(false)); + expect(YES).to_not(imply(NO)); }); }); }); @@ -75,11 +75,11 @@ }); it(@"should pass", ^{ - expect(nil).to(imply(@"wurble")); + expect((id)nil).to(imply(@"wurble")); }); it(@"should pass", ^{ - expect(nil).to(imply(nil)); + expect((id)nil).to(imply((id)nil)); }); }); @@ -91,14 +91,14 @@ }); it(@"should fail with a sensible failure message", ^{ - expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(nil).to_not(imply(@"wurble")); + expectFailureWithMessage(@"Expected <(null)> to not imply ", ^{ + expect((id)nil).to_not(imply(@"wurble")); }); }); it(@"should fail with a sensible failure message", ^{ - expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(nil).to_not(imply(nil)); + expectFailureWithMessage(@"Expected <(null)> to not imply <(null)>", ^{ + expect((id)nil).to_not(imply((id)nil)); }); }); }); @@ -107,15 +107,15 @@ describe(@"which evaluates to false", ^{ describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ - expectFailureWithMessage(@"Expected to imply ", ^{ - expect(@"wurble").to(imply(nil)); + expectFailureWithMessage(@"Expected to imply <(null)>", ^{ + expect(@"wurble").to(imply((id)nil)); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ - expect(@"wurble").to_not(imply(nil)); + expect(@"wurble").to_not(imply((id)nil)); }); }); }); @@ -125,64 +125,64 @@ describe(@"which evaluates to true", ^{ describe(@"positive match", ^{ it(@"should pass", ^{ - expect(@"wurble").to(imply(true)); + expect(@"wurble").to(imply(YES)); }); it(@"should pass", ^{ - expect(nil).to(imply(true)); + expect((id)nil).to(imply(YES)); }); it(@"should pass", ^{ - expect(nil).to(imply(false)); + expect((id)nil).to(imply(NO)); }); it(@"should pass", ^{ - expect(true).to(imply(@"wurble")); + expect(YES).to(imply(@"wurble")); }); it(@"should pass", ^{ - expect(false).to(imply(@"wurble")); + expect(NO).to(imply(@"wurble")); }); it(@"should pass", ^{ - expect(false).to(imply(nil)); + expect(NO).to(imply((id)nil)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(@"wurble").to_not(imply(true)); + expect(@"wurble").to_not(imply(YES)); }); }); it(@"should fail with a sensible failure message", ^{ - expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(nil).to_not(imply(true)); + expectFailureWithMessage(@"Expected <(null)> to not imply ", ^{ + expect((id)nil).to_not(imply(YES)); }); }); it(@"should fail with a sensible failure message", ^{ - expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(nil).to_not(imply(false)); + expectFailureWithMessage(@"Expected <(null)> to not imply ", ^{ + expect((id)nil).to_not(imply(NO)); }); }); it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(true).to_not(imply(@"wurble")); + expect(YES).to_not(imply(@"wurble")); }); }); it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(false).to_not(imply(@"wurble")); + expect(NO).to_not(imply(@"wurble")); }); }); it(@"should fail with a sensible failure message", ^{ - expectFailureWithMessage(@"Expected to not imply ", ^{ - expect(false).to_not(imply(nil)); + expectFailureWithMessage(@"Expected to not imply <(null)>", ^{ + expect(NO).to_not(imply((id)nil)); }); }); }); @@ -192,24 +192,24 @@ describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to imply ", ^{ - expect(@"wurble").to(imply(false)); + expect(@"wurble").to(imply(NO)); }); }); it(@"should fail with a sensible failure message", ^{ - expectFailureWithMessage(@"Expected to imply ", ^{ - expect(true).to(imply(nil)); + expectFailureWithMessage(@"Expected to imply <(null)>", ^{ + expect(YES).to(imply((id)nil)); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ - expect(@"wurble").to_not(imply(false)); + expect(@"wurble").to_not(imply(NO)); }); it(@"should should pass", ^{ - expect(true).to_not(imply(nil)); + expect(YES).to_not(imply((id)nil)); }); }); });