From 3cf1645b1a4d2b34dc162559647cda92c43bd250 Mon Sep 17 00:00:00 2001 From: Tony Li Date: Tue, 8 Nov 2022 13:54:56 +1300 Subject: [PATCH 1/5] Replace Specta with Quick From Specta's GitHub repo: > Specta is considered a done project [...], we recommend you consider Quick. --- Podfile | 2 +- Podfile.lock | 10 +-- WordPressShared.xcodeproj/project.pbxproj | 4 +- WordPressSharedTests/WPAnalyticsTests.m | 95 ++++++++++++----------- 4 files changed, 56 insertions(+), 55 deletions(-) diff --git a/Podfile b/Podfile index fdc613b7..4499efd0 100644 --- a/Podfile +++ b/Podfile @@ -26,6 +26,6 @@ target 'WordPressSharedTests' do pod 'OHHTTPStubs', '~> 9.0' pod 'OHHTTPStubs/Swift', '~> 9.0' pod 'OCMock', '~> 3.4' - pod 'Specta', '1.0.7' + pod 'Quick', '~> 6.0' pod 'Expecta', '1.0.6' end diff --git a/Podfile.lock b/Podfile.lock index f532b489..ff5258a7 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -22,7 +22,7 @@ PODS: - OHHTTPStubs/OHPathHelpers (9.1.0) - OHHTTPStubs/Swift (9.1.0): - OHHTTPStubs/Default - - Specta (1.0.7) + - Quick (6.0.0) DEPENDENCIES: - CocoaLumberjack (~> 3.4) @@ -31,7 +31,7 @@ DEPENDENCIES: - OCMock (~> 3.4) - OHHTTPStubs (~> 9.0) - OHHTTPStubs/Swift (~> 9.0) - - Specta (= 1.0.7) + - Quick (~> 6.0) SPEC REPOS: trunk: @@ -40,7 +40,7 @@ SPEC REPOS: - FormatterKit - OCMock - OHHTTPStubs - - Specta + - Quick SPEC CHECKSUMS: CocoaLumberjack: e8955b9d337ac307103b0a34fd141c32f27e53c5 @@ -48,8 +48,8 @@ SPEC CHECKSUMS: FormatterKit: 4b8f29acc9b872d5d12a63efb560661e8f2e1b98 OCMock: 29f6e52085b4e7d9b075cbf03ed7c3112f82f934 OHHTTPStubs: 90eac6d8f2c18317baeca36698523dc67c513831 - Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66 + Quick: 4d5ab9e81f0a632cbf9bc4f3069b55e5eeb175df -PODFILE CHECKSUM: ace859cfebf0a7a9ce551e216483b641cd360251 +PODFILE CHECKSUM: ada0d4ed55a22efd07f3eb930484d8c31a5efcd4 COCOAPODS: 1.11.3 diff --git a/WordPressShared.xcodeproj/project.pbxproj b/WordPressShared.xcodeproj/project.pbxproj index c241c528..8f97f5d0 100644 --- a/WordPressShared.xcodeproj/project.pbxproj +++ b/WordPressShared.xcodeproj/project.pbxproj @@ -675,7 +675,7 @@ "${BUILT_PRODUCTS_DIR}/Expecta/Expecta.framework", "${BUILT_PRODUCTS_DIR}/OCMock/OCMock.framework", "${BUILT_PRODUCTS_DIR}/OHHTTPStubs/OHHTTPStubs.framework", - "${BUILT_PRODUCTS_DIR}/Specta/Specta.framework", + "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -684,7 +684,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Expecta.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OCMock.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OHHTTPStubs.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Specta.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/WordPressSharedTests/WPAnalyticsTests.m b/WordPressSharedTests/WPAnalyticsTests.m index a8c99c9a..ea5838fc 100644 --- a/WordPressSharedTests/WPAnalyticsTests.m +++ b/WordPressSharedTests/WPAnalyticsTests.m @@ -1,47 +1,48 @@ -#import -#define EXP_SHORTHAND -#import +#import #import #import "TestAnalyticsTracker.h" // Rather than duplicate these tests for each method, we abstracted them into a set of // shared examples and use an NSInvocation object to tell us what to call. -SharedExampleGroupsBegin(WPAnalyticsMethodBehavior) - -sharedExamplesFor(@"a WPAnalyticsTracker method", ^(NSDictionary *data) { - NSInvocation *invocation = data[@"invocation"]; - it(@"should not be called if tracker isn't registered", ^{ - id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); - id expectation = [trackerMock reject]; - [invocation invokeWithTarget:expectation]; - [trackerMock verify]; +QuickConfigurationBegin(WPAnalyticsMethodBehavior) + ++ (void)configure:(QCKConfiguration *)configuration +{ + sharedExamples(@"a WPAnalyticsTracker method", ^(QCKDSLSharedExampleContext context) { + NSInvocation *invocation = context()[@"invocation"]; + it(@"should not be called if tracker isn't registered", ^{ + id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); + id expectation = [trackerMock reject]; + [invocation invokeWithTarget:expectation]; + [trackerMock verify]; + }); + + it(@"should be called if tracker is registered", ^{ + id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); + id expectation = [trackerMock expect]; + [invocation invokeWithTarget:expectation]; + [invocation invokeWithTarget:trackerMock]; + [trackerMock verify]; + }); + + it(@"should be called on multiple trackers if registered", ^{ + id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); + id trackerMock2 = OCMStrictClassMock([TestAnalyticsTracker class]); + id expectation = [trackerMock expect]; + id expectation2 = [trackerMock2 expect]; + [invocation invokeWithTarget:expectation]; + [invocation invokeWithTarget:expectation2]; + [invocation invokeWithTarget:trackerMock]; + [invocation invokeWithTarget:trackerMock2]; + [trackerMock verify]; + [trackerMock2 verify]; + }); }); - - it(@"should be called if tracker is registered", ^{ - id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); - id expectation = [trackerMock expect]; - [invocation invokeWithTarget:expectation]; - [invocation invokeWithTarget:trackerMock]; - [trackerMock verify]; - }); - - it(@"should be called on multiple trackers if registered", ^{ - id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); - id trackerMock2 = OCMStrictClassMock([TestAnalyticsTracker class]); - id expectation = [trackerMock expect]; - id expectation2 = [trackerMock2 expect]; - [invocation invokeWithTarget:expectation]; - [invocation invokeWithTarget:expectation2]; - [invocation invokeWithTarget:trackerMock]; - [invocation invokeWithTarget:trackerMock2]; - [trackerMock verify]; - [trackerMock2 verify]; - }); -}); +} -SharedExampleGroupsEnd +QuickConfigurationEnd -SpecBegin(WPAnalyticsSpecs) +QuickSpecBegin(WPAnalyticsSpecs) beforeEach(^{ [WPAnalytics clearTrackers]; @@ -51,8 +52,8 @@ NSMethodSignature *signature = [TestAnalyticsTracker instanceMethodSignatureForSelector:@selector(beginSession)]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setSelector:@selector(beginSession)]; - - itShouldBehaveLike(@"a WPAnalyticsTracker method", @{@"invocation": invocation}); + + itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); }); describe(@"endSession", ^{ @@ -60,7 +61,7 @@ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setSelector:@selector(endSession)]; - itShouldBehaveLike(@"a WPAnalyticsTracker method", @{@"invocation": invocation}); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); }); describe(@"refreshMetadata", ^{ @@ -68,7 +69,7 @@ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setSelector:@selector(refreshMetadata)]; - itShouldBehaveLike(@"a WPAnalyticsTracker method", @{@"invocation": invocation}); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); }); describe(@"beginTimerForStat:", ^{ @@ -78,7 +79,7 @@ WPAnalyticsStat stat = WPAnalyticsStatApplicationOpened; [invocation setArgument:&stat atIndex:2]; - itShouldBehaveLike(@"a WPAnalyticsTracker method", @{@"invocation": invocation}); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); }); describe(@"endTimerForStat:withProperties", ^{ @@ -91,7 +92,7 @@ [invocation setArgument:&stat atIndex:2]; [invocation setArgument:&dict atIndex:3]; - itShouldBehaveLike(@"a WPAnalyticsTracker method", @{@"invocation": invocation}); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); }); describe(@"track:", ^{ @@ -101,7 +102,7 @@ WPAnalyticsStat stat = WPAnalyticsStatApplicationOpened; [invocation setArgument:&stat atIndex:2]; - itShouldBehaveLike(@"a WPAnalyticsTracker method", @{@"invocation": invocation}); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); }); describe(@"track:withProperties:", ^{ @@ -114,7 +115,7 @@ [invocation setArgument:&stat atIndex:2]; [invocation setArgument:&dict atIndex:3]; - itShouldBehaveLike(@"a WPAnalyticsTracker method", @{@"invocation": invocation}); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); }); describe(@"trackString:", ^{ @@ -124,7 +125,7 @@ NSString *event = @"my_event"; [invocation setArgument:&event atIndex:2]; - itShouldBehaveLike(@"a WPAnalyticsTracker method", @{@"invocation": invocation}); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); }); describe(@"trackString:withProperties:", ^{ @@ -137,7 +138,7 @@ [invocation setArgument:&event atIndex:2]; [invocation setArgument:&dict atIndex:3]; - itShouldBehaveLike(@"a WPAnalyticsTracker method", @{@"invocation": invocation}); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); }); -SpecEnd +QuickSpecEnd From 80727b34e5507c29ba14aa86ada40decc6682df2 Mon Sep 17 00:00:00 2001 From: Tony Li Date: Tue, 8 Nov 2022 14:03:37 +1300 Subject: [PATCH 2/5] Simplify WPAnalyticsTests implementation --- WordPressSharedTests/WPAnalyticsTests.m | 148 ++++++++++++------------ 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/WordPressSharedTests/WPAnalyticsTests.m b/WordPressSharedTests/WPAnalyticsTests.m index ea5838fc..a654968a 100644 --- a/WordPressSharedTests/WPAnalyticsTests.m +++ b/WordPressSharedTests/WPAnalyticsTests.m @@ -2,6 +2,8 @@ #import #import "TestAnalyticsTracker.h" +typedef void *(^WPAnalyticsMethodBehaviorInvocation)(id); + // Rather than duplicate these tests for each method, we abstracted them into a set of // shared examples and use an NSInvocation object to tell us what to call. QuickConfigurationBegin(WPAnalyticsMethodBehavior) @@ -9,19 +11,19 @@ + (void)configure:(QCKConfiguration *)configuration { sharedExamples(@"a WPAnalyticsTracker method", ^(QCKDSLSharedExampleContext context) { - NSInvocation *invocation = context()[@"invocation"]; + WPAnalyticsMethodBehaviorInvocation invocation = context()[@"invocation"]; it(@"should not be called if tracker isn't registered", ^{ id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); id expectation = [trackerMock reject]; - [invocation invokeWithTarget:expectation]; + invocation(expectation); [trackerMock verify]; }); it(@"should be called if tracker is registered", ^{ id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); id expectation = [trackerMock expect]; - [invocation invokeWithTarget:expectation]; - [invocation invokeWithTarget:trackerMock]; + invocation(expectation); + invocation(trackerMock); [trackerMock verify]; }); @@ -30,10 +32,10 @@ + (void)configure:(QCKConfiguration *)configuration id trackerMock2 = OCMStrictClassMock([TestAnalyticsTracker class]); id expectation = [trackerMock expect]; id expectation2 = [trackerMock2 expect]; - [invocation invokeWithTarget:expectation]; - [invocation invokeWithTarget:expectation2]; - [invocation invokeWithTarget:trackerMock]; - [invocation invokeWithTarget:trackerMock2]; + invocation(expectation); + invocation(expectation2); + invocation(trackerMock); + invocation(trackerMock2); [trackerMock verify]; [trackerMock2 verify]; }); @@ -49,96 +51,94 @@ + (void)configure:(QCKConfiguration *)configuration }); describe(@"beginSession", ^{ - NSMethodSignature *signature = [TestAnalyticsTracker instanceMethodSignatureForSelector:@selector(beginSession)]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:@selector(beginSession)]; - - itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ + return @{ + @"invocation": ^(id tracker){ + [tracker beginSession]; + } + }; + }); }); describe(@"endSession", ^{ - NSMethodSignature *signature = [TestAnalyticsTracker instanceMethodSignatureForSelector:@selector(endSession)]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:@selector(endSession)]; - - itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ + return @{ + @"invocation": ^(id tracker){ + [tracker endSession]; + } + }; + }); }); describe(@"refreshMetadata", ^{ - NSMethodSignature *signature = [TestAnalyticsTracker instanceMethodSignatureForSelector:@selector(refreshMetadata)]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:@selector(refreshMetadata)]; - - itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ + return @{ + @"invocation": ^(id tracker){ + [tracker refreshMetadata]; + } + }; + }); }); describe(@"beginTimerForStat:", ^{ - NSMethodSignature *signature = [TestAnalyticsTracker instanceMethodSignatureForSelector:@selector(beginTimerForStat:)]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:@selector(beginTimerForStat:)]; - WPAnalyticsStat stat = WPAnalyticsStatApplicationOpened; - [invocation setArgument:&stat atIndex:2]; - - itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ + return @{ + @"invocation": ^(id tracker){ + [tracker beginTimerForStat:WPAnalyticsStatApplicationOpened]; + } + }; + }); }); describe(@"endTimerForStat:withProperties", ^{ - NSMethodSignature *signature = [TestAnalyticsTracker instanceMethodSignatureForSelector:@selector(endTimerForStat:withProperties:)]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:@selector(endTimerForStat:withProperties:)]; - - WPAnalyticsStat stat = WPAnalyticsStatApplicationOpened; - NSDictionary *dict = @{}; - [invocation setArgument:&stat atIndex:2]; - [invocation setArgument:&dict atIndex:3]; - - itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ + return @{ + @"invocation": ^(id tracker){ + [tracker endTimerForStat:WPAnalyticsStatApplicationOpened withProperties:@{}]; + } + }; + }); }); describe(@"track:", ^{ - NSMethodSignature *signature = [TestAnalyticsTracker instanceMethodSignatureForSelector:@selector(track:)]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:@selector(track:)]; - WPAnalyticsStat stat = WPAnalyticsStatApplicationOpened; - [invocation setArgument:&stat atIndex:2]; - - itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ + return @{ + @"invocation": ^(id tracker){ + [tracker track:WPAnalyticsStatApplicationOpened]; + } + }; + }); }); describe(@"track:withProperties:", ^{ - NSMethodSignature *signature = [TestAnalyticsTracker instanceMethodSignatureForSelector:@selector(track:withProperties:)]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:@selector(track:withProperties:)]; - - WPAnalyticsStat stat = WPAnalyticsStatApplicationOpened; - NSDictionary *dict = @{}; - [invocation setArgument:&stat atIndex:2]; - [invocation setArgument:&dict atIndex:3]; - - itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ + return @{ + @"invocation": ^(id tracker){ + [tracker track:WPAnalyticsStatApplicationOpened withProperties:@{}]; + } + }; + + }); }); describe(@"trackString:", ^{ - NSMethodSignature *signature = [TestAnalyticsTracker instanceMethodSignatureForSelector:@selector(trackString:)]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:@selector(trackString:)]; - NSString *event = @"my_event"; - [invocation setArgument:&event atIndex:2]; - - itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ + return @{ + @"invocation": ^(id tracker){ + [tracker trackString:@"my_event"]; + } + }; + }); }); describe(@"trackString:withProperties:", ^{ - NSMethodSignature *signature = [TestAnalyticsTracker instanceMethodSignatureForSelector:@selector(trackString:withProperties:)]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:@selector(trackString:withProperties:)]; - - NSString *event = @"my_event"; - NSDictionary *dict = @{}; - [invocation setArgument:&event atIndex:2]; - [invocation setArgument:&dict atIndex:3]; - - itBehavesLike(@"a WPAnalyticsTracker method", ^{ return @{@"invocation": invocation}; }); + itBehavesLike(@"a WPAnalyticsTracker method", ^{ + return @{ + @"invocation": ^(id tracker){ + [tracker trackString:@"my_event" withProperties:@{}]; + } + }; + }); }); QuickSpecEnd From f7366c561678320d70311006758398917ef358c4 Mon Sep 17 00:00:00 2001 From: Tony Li Date: Tue, 8 Nov 2022 20:04:04 +1300 Subject: [PATCH 3/5] Rewrite WPAnalyticsTests in Swift --- WordPressShared.xcodeproj/project.pbxproj | 8 +- WordPressSharedTests/TestAnalyticsTracker.h | 10 ++ WordPressSharedTests/TestAnalyticsTracker.m | 30 ++++ WordPressSharedTests/WPAnalyticsTests.m | 144 ------------------ WordPressSharedTests/WPAnalyticsTests.swift | 133 ++++++++++++++++ .../WordPressSharedTests-Bridging-Header.h | 1 + 6 files changed, 178 insertions(+), 148 deletions(-) delete mode 100644 WordPressSharedTests/WPAnalyticsTests.m create mode 100644 WordPressSharedTests/WPAnalyticsTests.swift diff --git a/WordPressShared.xcodeproj/project.pbxproj b/WordPressShared.xcodeproj/project.pbxproj index 8f97f5d0..1439547f 100644 --- a/WordPressShared.xcodeproj/project.pbxproj +++ b/WordPressShared.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 2EB9C57E3BFEDA1676FE857C /* Pods_WordPressShared.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE15A6EE80D7766A21B83BF5 /* Pods_WordPressShared.framework */; }; 32E1BFD524A63DE6007A08F0 /* WPStyleGuide+SerifFonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32E1BFD424A63DE6007A08F0 /* WPStyleGuide+SerifFonts.swift */; }; 3F338B76289BE0F90014ADC5 /* BuildkiteTestCollector in Frameworks */ = {isa = PBXBuildFile; productRef = 3F338B75289BE0F90014ADC5 /* BuildkiteTestCollector */; }; + 4A2B7D132919E294007E5917 /* WPAnalyticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A2B7D122919E294007E5917 /* WPAnalyticsTests.swift */; }; 740B23CC1F17F1FF00067A2A /* DisplayableImageHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 740B23CA1F17F1FF00067A2A /* DisplayableImageHelper.h */; settings = {ATTRIBUTES = (Public, ); }; }; 740B23CD1F17F1FF00067A2A /* DisplayableImageHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 740B23CB1F17F1FF00067A2A /* DisplayableImageHelper.m */; }; 740B23CF1F17F28E00067A2A /* DisplayableImageHelperTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 740B23CE1F17F28E00067A2A /* DisplayableImageHelperTest.m */; }; @@ -87,7 +88,6 @@ E157E126239527700051AE41 /* Secret.swift in Sources */ = {isa = PBXBuildFile; fileRef = E157E125239527700051AE41 /* Secret.swift */; }; E157E128239527AD0051AE41 /* SecretTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E157E127239527AD0051AE41 /* SecretTests.swift */; }; E18EABEA1F0E2C6800BFCB0B /* TestAnalyticsTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = E18EABE81F0E2C6800BFCB0B /* TestAnalyticsTracker.m */; }; - E18EABEB1F0E2C6800BFCB0B /* WPAnalyticsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E18EABE91F0E2C6800BFCB0B /* WPAnalyticsTests.m */; }; E1A444281F063CAB00F6AA8A /* WPAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A444261F063CAB00F6AA8A /* WPAnalytics.h */; settings = {ATTRIBUTES = (Public, ); }; }; E1A444291F063CAB00F6AA8A /* WPAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A444271F063CAB00F6AA8A /* WPAnalytics.m */; }; F106FA61226FA72E00706DE4 /* StringURLValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F19847DD226F92EA0004A8BC /* StringURLValidationTests.swift */; }; @@ -122,6 +122,7 @@ 32E1BFD424A63DE6007A08F0 /* WPStyleGuide+SerifFonts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WPStyleGuide+SerifFonts.swift"; sourceTree = ""; }; 405129D7901B7D4AD3B46442 /* Pods-WordPressShared.release-internal.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WordPressShared.release-internal.xcconfig"; path = "Pods/Target Support Files/Pods-WordPressShared/Pods-WordPressShared.release-internal.xcconfig"; sourceTree = ""; }; 47629DF6D2C813279CBF93C4 /* Pods_WordPressSharedTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WordPressSharedTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4A2B7D122919E294007E5917 /* WPAnalyticsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WPAnalyticsTests.swift; sourceTree = ""; }; 5AC1280B7CDCD44A2F3A20AC /* Pods-WordPressShared.release-alpha.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WordPressShared.release-alpha.xcconfig"; path = "Pods/Target Support Files/Pods-WordPressShared/Pods-WordPressShared.release-alpha.xcconfig"; sourceTree = ""; }; 5B7FC757233F785AA7F785E7 /* Pods-WordPressShared.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WordPressShared.release.xcconfig"; path = "Pods/Target Support Files/Pods-WordPressShared/Pods-WordPressShared.release.xcconfig"; sourceTree = ""; }; 716C92B0CD72E5CD8250C04E /* Pods-WordPressSharedTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WordPressSharedTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-WordPressSharedTests/Pods-WordPressSharedTests.debug.xcconfig"; sourceTree = ""; }; @@ -211,7 +212,6 @@ E157E127239527AD0051AE41 /* SecretTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretTests.swift; sourceTree = ""; }; E18EABE71F0E2C6800BFCB0B /* TestAnalyticsTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestAnalyticsTracker.h; sourceTree = ""; }; E18EABE81F0E2C6800BFCB0B /* TestAnalyticsTracker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestAnalyticsTracker.m; sourceTree = ""; }; - E18EABE91F0E2C6800BFCB0B /* WPAnalyticsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WPAnalyticsTests.m; sourceTree = ""; }; E1A444261F063CAB00F6AA8A /* WPAnalytics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WPAnalytics.h; sourceTree = ""; }; E1A444271F063CAB00F6AA8A /* WPAnalytics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WPAnalytics.m; sourceTree = ""; }; E5A4545AEF641B125A2ABA89 /* Pods-WordPressShared.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WordPressShared.debug.xcconfig"; path = "Pods/Target Support Files/Pods-WordPressShared/Pods-WordPressShared.debug.xcconfig"; sourceTree = ""; }; @@ -378,7 +378,7 @@ F1C83C1123E20F7000A8CCF1 /* StringStripGutenbergContentForExcerptTests.swift */, E18EABE71F0E2C6800BFCB0B /* TestAnalyticsTracker.h */, E18EABE81F0E2C6800BFCB0B /* TestAnalyticsTracker.m */, - E18EABE91F0E2C6800BFCB0B /* WPAnalyticsTests.m */, + 4A2B7D122919E294007E5917 /* WPAnalyticsTests.swift */, 827070911ECA4E1D00155CBF /* WPImageSourceTest.m */, 93A73ABE1EE9DDB000C0F2F9 /* WPMapFilterReduceTest.m */, 8270708F1ECA4E1C00155CBF /* WordPressSharedTests-Bridging-Header.h */, @@ -763,9 +763,9 @@ E157E128239527AD0051AE41 /* SecretTests.swift in Sources */, 740B23CF1F17F28E00067A2A /* DisplayableImageHelperTest.m in Sources */, F1C83C0C23E205D900A8CCF1 /* NSStringSummaryTests.swift in Sources */, - E18EABEB1F0E2C6800BFCB0B /* WPAnalyticsTests.m in Sources */, 7430C9DD1F1934190051B8E6 /* RichContentFormatterTests.swift in Sources */, B5393FDC206D6169007BF9D4 /* EmailFormatValidatorTests.swift in Sources */, + 4A2B7D132919E294007E5917 /* WPAnalyticsTests.swift in Sources */, 748710AC1F06C465008095AB /* StringHelperTests.swift in Sources */, 9A1329DF22170BE2009EE02A /* NSDateHelperTest.swift in Sources */, ); diff --git a/WordPressSharedTests/TestAnalyticsTracker.h b/WordPressSharedTests/TestAnalyticsTracker.h index 59e9a4be..6a3d2543 100644 --- a/WordPressSharedTests/TestAnalyticsTracker.h +++ b/WordPressSharedTests/TestAnalyticsTracker.h @@ -1,6 +1,8 @@ #import #import "WPAnalytics.h" +NS_ASSUME_NONNULL_BEGIN + @interface TestAnalyticsTracker : NSObject - (void)track:(WPAnalyticsStat)stat; @@ -11,3 +13,11 @@ - (void)refreshMetadata; @end + +typedef void (^WPAnalyticsMethodBehaviorInvocation)(id); + +FOUNDATION_EXTERN void WPAnalyticsTestVerifyUnregistered(WPAnalyticsMethodBehaviorInvocation invocation); +FOUNDATION_EXTERN void WPAnalyticsTestVerifyRegistered(WPAnalyticsMethodBehaviorInvocation invocation); +FOUNDATION_EXTERN void WPAnalyticsTestVerifyMultipleTrackers(WPAnalyticsMethodBehaviorInvocation invocation); + +NS_ASSUME_NONNULL_END diff --git a/WordPressSharedTests/TestAnalyticsTracker.m b/WordPressSharedTests/TestAnalyticsTracker.m index 33e1e1b8..3c62a2bc 100644 --- a/WordPressSharedTests/TestAnalyticsTracker.m +++ b/WordPressSharedTests/TestAnalyticsTracker.m @@ -1,5 +1,7 @@ #import "TestAnalyticsTracker.h" +#import + @implementation TestAnalyticsTracker - (void)track:(WPAnalyticsStat)stat @@ -38,3 +40,31 @@ - (void)trackString:(NSString *)event withProperties:(NSDictionary *)properties @end + +void WPAnalyticsTestVerifyUnregistered(WPAnalyticsMethodBehaviorInvocation invocation) { + id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); + id expectation = [trackerMock reject]; + invocation(expectation); + [trackerMock verify]; +} + +void WPAnalyticsTestVerifyRegistered(WPAnalyticsMethodBehaviorInvocation invocation) { + id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); + id expectation = [trackerMock expect]; + invocation(expectation); + invocation(trackerMock); + [trackerMock verify]; +} + +void WPAnalyticsTestVerifyMultipleTrackers(WPAnalyticsMethodBehaviorInvocation invocation) { + id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); + id trackerMock2 = OCMStrictClassMock([TestAnalyticsTracker class]); + id expectation = [trackerMock expect]; + id expectation2 = [trackerMock2 expect]; + invocation(expectation); + invocation(expectation2); + invocation(trackerMock); + invocation(trackerMock2); + [trackerMock verify]; + [trackerMock2 verify]; +} diff --git a/WordPressSharedTests/WPAnalyticsTests.m b/WordPressSharedTests/WPAnalyticsTests.m deleted file mode 100644 index a654968a..00000000 --- a/WordPressSharedTests/WPAnalyticsTests.m +++ /dev/null @@ -1,144 +0,0 @@ -#import -#import -#import "TestAnalyticsTracker.h" - -typedef void *(^WPAnalyticsMethodBehaviorInvocation)(id); - -// Rather than duplicate these tests for each method, we abstracted them into a set of -// shared examples and use an NSInvocation object to tell us what to call. -QuickConfigurationBegin(WPAnalyticsMethodBehavior) - -+ (void)configure:(QCKConfiguration *)configuration -{ - sharedExamples(@"a WPAnalyticsTracker method", ^(QCKDSLSharedExampleContext context) { - WPAnalyticsMethodBehaviorInvocation invocation = context()[@"invocation"]; - it(@"should not be called if tracker isn't registered", ^{ - id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); - id expectation = [trackerMock reject]; - invocation(expectation); - [trackerMock verify]; - }); - - it(@"should be called if tracker is registered", ^{ - id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); - id expectation = [trackerMock expect]; - invocation(expectation); - invocation(trackerMock); - [trackerMock verify]; - }); - - it(@"should be called on multiple trackers if registered", ^{ - id trackerMock = OCMStrictClassMock([TestAnalyticsTracker class]); - id trackerMock2 = OCMStrictClassMock([TestAnalyticsTracker class]); - id expectation = [trackerMock expect]; - id expectation2 = [trackerMock2 expect]; - invocation(expectation); - invocation(expectation2); - invocation(trackerMock); - invocation(trackerMock2); - [trackerMock verify]; - [trackerMock2 verify]; - }); - }); -} - -QuickConfigurationEnd - -QuickSpecBegin(WPAnalyticsSpecs) - -beforeEach(^{ - [WPAnalytics clearTrackers]; -}); - -describe(@"beginSession", ^{ - itBehavesLike(@"a WPAnalyticsTracker method", ^{ - return @{ - @"invocation": ^(id tracker){ - [tracker beginSession]; - } - }; - }); -}); - -describe(@"endSession", ^{ - itBehavesLike(@"a WPAnalyticsTracker method", ^{ - return @{ - @"invocation": ^(id tracker){ - [tracker endSession]; - } - }; - }); -}); - -describe(@"refreshMetadata", ^{ - itBehavesLike(@"a WPAnalyticsTracker method", ^{ - return @{ - @"invocation": ^(id tracker){ - [tracker refreshMetadata]; - } - }; - }); -}); - -describe(@"beginTimerForStat:", ^{ - itBehavesLike(@"a WPAnalyticsTracker method", ^{ - return @{ - @"invocation": ^(id tracker){ - [tracker beginTimerForStat:WPAnalyticsStatApplicationOpened]; - } - }; - }); -}); - -describe(@"endTimerForStat:withProperties", ^{ - itBehavesLike(@"a WPAnalyticsTracker method", ^{ - return @{ - @"invocation": ^(id tracker){ - [tracker endTimerForStat:WPAnalyticsStatApplicationOpened withProperties:@{}]; - } - }; - }); -}); - -describe(@"track:", ^{ - itBehavesLike(@"a WPAnalyticsTracker method", ^{ - return @{ - @"invocation": ^(id tracker){ - [tracker track:WPAnalyticsStatApplicationOpened]; - } - }; - }); -}); - -describe(@"track:withProperties:", ^{ - itBehavesLike(@"a WPAnalyticsTracker method", ^{ - return @{ - @"invocation": ^(id tracker){ - [tracker track:WPAnalyticsStatApplicationOpened withProperties:@{}]; - } - }; - - }); -}); - -describe(@"trackString:", ^{ - itBehavesLike(@"a WPAnalyticsTracker method", ^{ - return @{ - @"invocation": ^(id tracker){ - [tracker trackString:@"my_event"]; - } - }; - }); -}); - -describe(@"trackString:withProperties:", ^{ - itBehavesLike(@"a WPAnalyticsTracker method", ^{ - return @{ - @"invocation": ^(id tracker){ - [tracker trackString:@"my_event" withProperties:@{}]; - } - }; - }); -}); - -QuickSpecEnd diff --git a/WordPressSharedTests/WPAnalyticsTests.swift b/WordPressSharedTests/WPAnalyticsTests.swift new file mode 100644 index 00000000..ac3a869f --- /dev/null +++ b/WordPressSharedTests/WPAnalyticsTests.swift @@ -0,0 +1,133 @@ +import Quick + +@testable import WordPressShared + +class WPAnalyticsMethodBehaviorExamplesConfiguration: QuickConfiguration { + override class func configure(_ configuration: QCKConfiguration!) { + sharedExamples("a WPAnalyticsTracker method") { context in + guard let context else { + XCTFail("Test case needs to provide a context") + return + } + guard let invocation = context()?["invocation"] else { + XCTFail("invocation not found in the provided context") + return + } + guard let theInvocation = invocation as? WPAnalyticsMethodBehaviorInvocation else { + XCTFail("invocation not found in the provided context") + return + } + + it("should not be called if tqracker isn't registered") { + WPAnalyticsTestVerifyUnregistered(theInvocation) + } + + it("should be called if tracker is registered") { + WPAnalyticsTestVerifyRegistered(theInvocation) + } + + it("should be called on multiple trackers if registered") { + WPAnalyticsTestVerifyMultipleTrackers(theInvocation) + } + } + } +} + +class WPAnalyticsTests: QuickSpec { + override func spec() { + beforeEach { + WPAnalytics.clearTrackers() + } + + describe("beginSession") { + itBehavesLike("a WPAnalyticsTracker method") { + [ + "invocation": { (tracker: WPAnalyticsTracker) -> Void in + tracker.beginSession!() + } + ] + } + } + + describe("endSession") { + itBehavesLike("a WPAnalyticsTracker method") { + [ + "invocation": { (tracker: WPAnalyticsTracker) -> Void in + tracker.endSession!() + } + ] + } + } + + describe("refreshMetadata") { + itBehavesLike("a WPAnalyticsTracker method") { + [ + "invocation": { (tracker: WPAnalyticsTracker) -> Void in + tracker.refreshMetadata!() + } + ] + } + } + + describe("beginTimerForStat:") { + itBehavesLike("a WPAnalyticsTracker method") { + [ + "invocation": { (tracker: WPAnalyticsTracker) -> Void in + tracker.beginTimer!(for: .applicationOpened) + } + ] + } + } + + describe("endTimerForStat:withProperties") { + itBehavesLike("a WPAnalyticsTracker method") { + [ + "invocation": { (tracker: WPAnalyticsTracker) -> Void in + tracker.endTimer!(for: .applicationOpened, withProperties: [:]) + } + ] + } + } + + describe("track:") { + itBehavesLike("a WPAnalyticsTracker method") { + [ + "invocation": { (tracker: WPAnalyticsTracker) -> Void in + tracker.track(.applicationOpened) + } + ] + } + } + + describe("track:withProperties:") { + itBehavesLike("a WPAnalyticsTracker method") { + [ + "invocation": { (tracker: WPAnalyticsTracker) -> Void in + tracker.track(.applicationOpened, withProperties: [:]) + } + ] + + } + } + + describe("trackString:") { + itBehavesLike("a WPAnalyticsTracker method") { + [ + "invocation": { (tracker: WPAnalyticsTracker) -> Void in + tracker.trackString("my_event") + } + ] + } + } + + describe("trackString:withProperties:") { + itBehavesLike("a WPAnalyticsTracker method") { + [ + "invocation": { (tracker: WPAnalyticsTracker) -> Void in + tracker.trackString("my_event", withProperties: [:]) + } + ] + } + } + } +} diff --git a/WordPressSharedTests/WordPressSharedTests-Bridging-Header.h b/WordPressSharedTests/WordPressSharedTests-Bridging-Header.h index 1b2cb5d6..69aa50f8 100644 --- a/WordPressSharedTests/WordPressSharedTests-Bridging-Header.h +++ b/WordPressSharedTests/WordPressSharedTests-Bridging-Header.h @@ -2,3 +2,4 @@ // Use this file to import your target's public headers that you would like to expose to Swift. // +#import "TestAnalyticsTracker.h" From 5f6fa84eb539a3f633c8c7bf089bcbaa8d0cb0a7 Mon Sep 17 00:00:00 2001 From: Tony Li Date: Tue, 8 Nov 2022 20:11:42 +1300 Subject: [PATCH 4/5] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43466c7c..90450e55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,3 +48,4 @@ _None._ - Add this changelog entry about changelog itself [#317] - Remove FormatterKit [#320] +- Move away from Specta, use Quick instead [#319] From bea05fadd067bb0d5aaa15f4174b1e23d3fefd9e Mon Sep 17 00:00:00 2001 From: Tony Li Date: Tue, 15 Nov 2022 09:32:31 +1300 Subject: [PATCH 5/5] Remove Expecta --- Podfile | 1 - Podfile.lock | 6 +----- WordPressShared.xcodeproj/project.pbxproj | 2 -- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Podfile b/Podfile index 4499efd0..d78efb5e 100644 --- a/Podfile +++ b/Podfile @@ -27,5 +27,4 @@ target 'WordPressSharedTests' do pod 'OHHTTPStubs/Swift', '~> 9.0' pod 'OCMock', '~> 3.4' pod 'Quick', '~> 6.0' - pod 'Expecta', '1.0.6' end diff --git a/Podfile.lock b/Podfile.lock index ff5258a7..e209e425 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -2,7 +2,6 @@ PODS: - CocoaLumberjack (3.7.0): - CocoaLumberjack/Core (= 3.7.0) - CocoaLumberjack/Core (3.7.0) - - Expecta (1.0.6) - FormatterKit/Resources (1.8.2) - FormatterKit/TimeIntervalFormatter (1.8.2): - FormatterKit/Resources @@ -26,7 +25,6 @@ PODS: DEPENDENCIES: - CocoaLumberjack (~> 3.4) - - Expecta (= 1.0.6) - FormatterKit/TimeIntervalFormatter (= 1.8.2) - OCMock (~> 3.4) - OHHTTPStubs (~> 9.0) @@ -36,7 +34,6 @@ DEPENDENCIES: SPEC REPOS: trunk: - CocoaLumberjack - - Expecta - FormatterKit - OCMock - OHHTTPStubs @@ -44,12 +41,11 @@ SPEC REPOS: SPEC CHECKSUMS: CocoaLumberjack: e8955b9d337ac307103b0a34fd141c32f27e53c5 - Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 FormatterKit: 4b8f29acc9b872d5d12a63efb560661e8f2e1b98 OCMock: 29f6e52085b4e7d9b075cbf03ed7c3112f82f934 OHHTTPStubs: 90eac6d8f2c18317baeca36698523dc67c513831 Quick: 4d5ab9e81f0a632cbf9bc4f3069b55e5eeb175df -PODFILE CHECKSUM: ada0d4ed55a22efd07f3eb930484d8c31a5efcd4 +PODFILE CHECKSUM: 3fc995dfb0ac66f4b9354243efa5e70275914622 COCOAPODS: 1.11.3 diff --git a/WordPressShared.xcodeproj/project.pbxproj b/WordPressShared.xcodeproj/project.pbxproj index 1439547f..e3dde99b 100644 --- a/WordPressShared.xcodeproj/project.pbxproj +++ b/WordPressShared.xcodeproj/project.pbxproj @@ -672,7 +672,6 @@ "${PODS_ROOT}/Target Support Files/Pods-WordPressSharedTests/Pods-WordPressSharedTests-frameworks.sh", "${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework", "${BUILT_PRODUCTS_DIR}/FormatterKit/FormatterKit.framework", - "${BUILT_PRODUCTS_DIR}/Expecta/Expecta.framework", "${BUILT_PRODUCTS_DIR}/OCMock/OCMock.framework", "${BUILT_PRODUCTS_DIR}/OHHTTPStubs/OHHTTPStubs.framework", "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework", @@ -681,7 +680,6 @@ outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaLumberjack.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FormatterKit.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Expecta.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OCMock.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OHHTTPStubs.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework",