diff --git a/OSPaymentsLib.xcodeproj/project.pbxproj b/OSPaymentsLib.xcodeproj/project.pbxproj index a988bd8..8a98295 100644 --- a/OSPaymentsLib.xcodeproj/project.pbxproj +++ b/OSPaymentsLib.xcodeproj/project.pbxproj @@ -8,15 +8,11 @@ /* Begin PBXBuildFile section */ 7507FC1B27FC2AAE003809F6 /* OSPaymentsLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7507FC1227FC2AAE003809F6 /* OSPaymentsLib.framework */; }; + 7507FC2127FC2AAE003809F6 /* OSPaymentsLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 7507FC1527FC2AAE003809F6 /* OSPaymentsLib.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7509DC7728993C4C005BA0D4 /* PKMerchantCapability+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7509DC7628993C4C005BA0D4 /* PKMerchantCapability+Adapter.swift */; }; 7509DC7D28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7509DC7C28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift */; }; 7509DC7F28996482005BA0D4 /* OSPMTApplePayConfigurationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7509DC7E28996482005BA0D4 /* OSPMTApplePayConfigurationSpec.swift */; }; 7509DC81289967A6005BA0D4 /* PKPaymentNetwork+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7509DC80289967A6005BA0D4 /* PKPaymentNetwork+Adapter.swift */; }; - 751B1DB2293A2744009A00B2 /* OSPMTStripeRequestParametersModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 751B1DB1293A2744009A00B2 /* OSPMTStripeRequestParametersModel.swift */; }; - 7556EA952934DAC600FF4044 /* OSPMTRequestParametersModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7556EA942934DAC600FF4044 /* OSPMTRequestParametersModel.swift */; }; - 7556EA982934E10D00FF4044 /* OSPMTStripeAPIDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7556EA972934E10D00FF4044 /* OSPMTStripeAPIDelegate.swift */; }; - 7556EA9A2934E4AB00FF4044 /* OSPMTStripeWrapperSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7556EA992934E4AB00FF4044 /* OSPMTStripeWrapperSpec.swift */; }; - 7556EA9C29350B9B00FF4044 /* OSPMTGatewayFactorySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7556EA9B29350B9B00FF4044 /* OSPMTGatewayFactorySpec.swift */; }; 755A804B289BB96900426EAA /* PKPassLibrary+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A804A289BB96900426EAA /* PKPassLibrary+Adapter.swift */; }; 755A804D289BBAB300426EAA /* PKPaymentAuthorizationController+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A804C289BBAB300426EAA /* PKPaymentAuthorizationController+Adapter.swift */; }; 755A8050289BBDF000426EAA /* OSPMTApplePayAvailabilityBehaviourSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A804F289BBDF000426EAA /* OSPMTApplePayAvailabilityBehaviourSpec.swift */; }; @@ -25,22 +21,16 @@ 755A8058289BC90A00426EAA /* OSPMTRequestDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A8057289BC90A00426EAA /* OSPMTRequestDelegate.swift */; }; 755A805A289BC92A00426EAA /* PKContactField+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A8059289BC92A00426EAA /* PKContactField+Adapter.swift */; }; 755A805C289BD4C600426EAA /* OSPMTApplePayRequestBehaviourSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A805B289BD4C600426EAA /* OSPMTApplePayRequestBehaviourSpec.swift */; }; + 755A805E289BD53000426EAA /* OSPMTTokenInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A805D289BD53000426EAA /* OSPMTTokenInfoModel.swift */; }; 755A8060289BD54E00426EAA /* OSPMTDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A805F289BD54E00426EAA /* OSPMTDataModel.swift */; }; 755A8062289BD56300426EAA /* OSPMTAddressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A8061289BD56300426EAA /* OSPMTAddressModel.swift */; }; 755A8064289BD58900426EAA /* OSPMTContactInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A8063289BD58900426EAA /* OSPMTContactInfoModel.swift */; }; - 755DF3F0297FF02800140860 /* StripePayments in Frameworks */ = {isa = PBXBuildFile; productRef = 755DF3EF297FF02800140860 /* StripePayments */; }; - 756931E62937A9200014618D /* OSPMTTokenInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756931E52937A9200014618D /* OSPMTTokenInfoModel.swift */; }; 75760F78289C102D001BDCEC /* OSPMTAddressModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F77289C102D001BDCEC /* OSPMTAddressModelSpec.swift */; }; 75760F7A289C17AB001BDCEC /* OSPMTContactInfoModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F79289C17AB001BDCEC /* OSPMTContactInfoModelSpec.swift */; }; 75760F7D289C1AED001BDCEC /* OSPMTTokenInfoModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F7C289C1AED001BDCEC /* OSPMTTokenInfoModelSpec.swift */; }; 75760F7F289C1BF9001BDCEC /* OSPMTDataModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F7E289C1BF9001BDCEC /* OSPMTDataModelSpec.swift */; }; 75760F81289C1DF3001BDCEC /* OSPMTScopeModelSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F80289C1DF3001BDCEC /* OSPMTScopeModelSpec.swift */; }; 75760F83289C1F99001BDCEC /* PKPayment+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75760F82289C1F99001BDCEC /* PKPayment+Adapter.swift */; }; - 757ADE062934CF33002B3341 /* OSPMTGateway.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757ADE052934CF32002B3341 /* OSPMTGateway.swift */; }; - 757ADE082934CF5E002B3341 /* OSPMTGatewayFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757ADE072934CF5E002B3341 /* OSPMTGatewayFactory.swift */; }; - 757ADE0A2934CF92002B3341 /* OSPMTGatewayDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757ADE092934CF92002B3341 /* OSPMTGatewayDelegate.swift */; }; - 757ADE0C2934CFE4002B3341 /* OSPMTStripeWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757ADE0B2934CFE4002B3341 /* OSPMTStripeWrapper.swift */; }; - 75CC42E829375A6200149E6E /* OSPMTServiceProviderInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CC42E729375A6200149E6E /* OSPMTServiceProviderInfoModel.swift */; }; 75E4DCB12897C8AD002277FD /* OSPMTPaymentsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75E4DCB02897C8AD002277FD /* OSPMTPaymentsSpec.swift */; }; 75EC4D122893FC3C00CF50E2 /* OSPMTPayments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC4D112893FC3C00CF50E2 /* OSPMTPayments.swift */; }; 75EC4D152894143A00CF50E2 /* OSPMTCallbackDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EC4D142894143A00CF50E2 /* OSPMTCallbackDelegate.swift */; }; @@ -70,16 +60,12 @@ 6E048C72FF94991BB4DC4977 /* Pods-OSPaymentsLib.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OSPaymentsLib.debug.xcconfig"; path = "Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.debug.xcconfig"; sourceTree = ""; }; 7063BC573F58EB7154E9975F /* Pods-OSPaymentsLib.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OSPaymentsLib.release.xcconfig"; path = "Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.release.xcconfig"; sourceTree = ""; }; 7507FC1227FC2AAE003809F6 /* OSPaymentsLib.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OSPaymentsLib.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7507FC1527FC2AAE003809F6 /* OSPaymentsLib.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSPaymentsLib.h; sourceTree = ""; }; 7507FC1A27FC2AAE003809F6 /* OSPaymentsLibTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OSPaymentsLibTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 7509DC7628993C4C005BA0D4 /* PKMerchantCapability+Adapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKMerchantCapability+Adapter.swift"; sourceTree = ""; }; 7509DC7C28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTAvailabilityDelegate.swift; sourceTree = ""; }; 7509DC7E28996482005BA0D4 /* OSPMTApplePayConfigurationSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTApplePayConfigurationSpec.swift; sourceTree = ""; }; 7509DC80289967A6005BA0D4 /* PKPaymentNetwork+Adapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPaymentNetwork+Adapter.swift"; sourceTree = ""; }; - 751B1DB1293A2744009A00B2 /* OSPMTStripeRequestParametersModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTStripeRequestParametersModel.swift; sourceTree = ""; }; - 7556EA942934DAC600FF4044 /* OSPMTRequestParametersModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTRequestParametersModel.swift; sourceTree = ""; }; - 7556EA972934E10D00FF4044 /* OSPMTStripeAPIDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTStripeAPIDelegate.swift; sourceTree = ""; }; - 7556EA992934E4AB00FF4044 /* OSPMTStripeWrapperSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTStripeWrapperSpec.swift; sourceTree = ""; }; - 7556EA9B29350B9B00FF4044 /* OSPMTGatewayFactorySpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTGatewayFactorySpec.swift; sourceTree = ""; }; 755A804A289BB96900426EAA /* PKPassLibrary+Adapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPassLibrary+Adapter.swift"; sourceTree = ""; }; 755A804C289BBAB300426EAA /* PKPaymentAuthorizationController+Adapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPaymentAuthorizationController+Adapter.swift"; sourceTree = ""; }; 755A804F289BBDF000426EAA /* OSPMTApplePayAvailabilityBehaviourSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTApplePayAvailabilityBehaviourSpec.swift; sourceTree = ""; }; @@ -88,21 +74,16 @@ 755A8057289BC90A00426EAA /* OSPMTRequestDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSPMTRequestDelegate.swift; sourceTree = ""; }; 755A8059289BC92A00426EAA /* PKContactField+Adapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PKContactField+Adapter.swift"; sourceTree = ""; }; 755A805B289BD4C600426EAA /* OSPMTApplePayRequestBehaviourSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSPMTApplePayRequestBehaviourSpec.swift; sourceTree = ""; }; + 755A805D289BD53000426EAA /* OSPMTTokenInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTTokenInfoModel.swift; sourceTree = ""; }; 755A805F289BD54E00426EAA /* OSPMTDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTDataModel.swift; sourceTree = ""; }; 755A8061289BD56300426EAA /* OSPMTAddressModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTAddressModel.swift; sourceTree = ""; }; 755A8063289BD58900426EAA /* OSPMTContactInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTContactInfoModel.swift; sourceTree = ""; }; - 756931E52937A9200014618D /* OSPMTTokenInfoModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSPMTTokenInfoModel.swift; sourceTree = ""; }; 75760F77289C102D001BDCEC /* OSPMTAddressModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTAddressModelSpec.swift; sourceTree = ""; }; 75760F79289C17AB001BDCEC /* OSPMTContactInfoModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTContactInfoModelSpec.swift; sourceTree = ""; }; 75760F7C289C1AED001BDCEC /* OSPMTTokenInfoModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTTokenInfoModelSpec.swift; sourceTree = ""; }; 75760F7E289C1BF9001BDCEC /* OSPMTDataModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTDataModelSpec.swift; sourceTree = ""; }; 75760F80289C1DF3001BDCEC /* OSPMTScopeModelSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTScopeModelSpec.swift; sourceTree = ""; }; 75760F82289C1F99001BDCEC /* PKPayment+Adapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKPayment+Adapter.swift"; sourceTree = ""; }; - 757ADE052934CF32002B3341 /* OSPMTGateway.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTGateway.swift; sourceTree = ""; }; - 757ADE072934CF5E002B3341 /* OSPMTGatewayFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTGatewayFactory.swift; sourceTree = ""; }; - 757ADE092934CF92002B3341 /* OSPMTGatewayDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTGatewayDelegate.swift; sourceTree = ""; }; - 757ADE0B2934CFE4002B3341 /* OSPMTStripeWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTStripeWrapper.swift; sourceTree = ""; }; - 75CC42E729375A6200149E6E /* OSPMTServiceProviderInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTServiceProviderInfoModel.swift; sourceTree = ""; }; 75E4DCB02897C8AD002277FD /* OSPMTPaymentsSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTPaymentsSpec.swift; sourceTree = ""; }; 75EC4D112893FC3C00CF50E2 /* OSPMTPayments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTPayments.swift; sourceTree = ""; }; 75EC4D142894143A00CF50E2 /* OSPMTCallbackDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTCallbackDelegate.swift; sourceTree = ""; }; @@ -123,7 +104,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 755DF3F0297FF02800140860 /* StripePayments in Frameworks */, 8DB1869BE6C7A0D7D44D4C34 /* Pods_OSPaymentsLib.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -176,9 +156,9 @@ children = ( 75EC4D182894155D00CF50E2 /* Error */, 7509DC7528993C26005BA0D4 /* Extensions */, - 757ADE042934CEF8002B3341 /* Gateways */, 755A8052289BC8EE00426EAA /* Models */, 75EC4D132894142000CF50E2 /* Protocols */, + 7507FC1527FC2AAE003809F6 /* OSPaymentsLib.h */, 75EC4D1D289416B600CF50E2 /* OSPMTApplePayHandler.swift */, 75EC4D112893FC3C00CF50E2 /* OSPMTPayments.swift */, ); @@ -193,9 +173,7 @@ 7509DC7E28996482005BA0D4 /* OSPMTApplePayConfigurationSpec.swift */, 75EC4D232894449700CF50E2 /* OSPMTApplePayHandlerSpec.swift */, 755A805B289BD4C600426EAA /* OSPMTApplePayRequestBehaviourSpec.swift */, - 7556EA9B29350B9B00FF4044 /* OSPMTGatewayFactorySpec.swift */, 75E4DCB02897C8AD002277FD /* OSPMTPaymentsSpec.swift */, - 7556EA992934E4AB00FF4044 /* OSPMTStripeWrapperSpec.swift */, 75EC4D252894478200CF50E2 /* OSPMTTestConfigurations.swift */, ); path = OSPaymentsLibTests; @@ -214,16 +192,6 @@ path = Extensions; sourceTree = ""; }; - 7556EA962934E09900FF4044 /* Stripe */ = { - isa = PBXGroup; - children = ( - 7556EA972934E10D00FF4044 /* OSPMTStripeAPIDelegate.swift */, - 751B1DB1293A2744009A00B2 /* OSPMTStripeRequestParametersModel.swift */, - 757ADE0B2934CFE4002B3341 /* OSPMTStripeWrapper.swift */, - ); - path = Stripe; - sourceTree = ""; - }; 755A8052289BC8EE00426EAA /* Models */ = { isa = PBXGroup; children = ( @@ -232,10 +200,8 @@ 755A8063289BD58900426EAA /* OSPMTContactInfoModel.swift */, 755A805F289BD54E00426EAA /* OSPMTDataModel.swift */, 755A8053289BC8EE00426EAA /* OSPMTDetailsModel.swift */, - 7556EA942934DAC600FF4044 /* OSPMTRequestParametersModel.swift */, - 75CC42E729375A6200149E6E /* OSPMTServiceProviderInfoModel.swift */, 755A8054289BC8EE00426EAA /* OSPMTScopeModel.swift */, - 756931E52937A9200014618D /* OSPMTTokenInfoModel.swift */, + 755A805D289BD53000426EAA /* OSPMTTokenInfoModel.swift */, ); path = Models; sourceTree = ""; @@ -252,23 +218,12 @@ path = ModelSpecs; sourceTree = ""; }; - 757ADE042934CEF8002B3341 /* Gateways */ = { - isa = PBXGroup; - children = ( - 7556EA962934E09900FF4044 /* Stripe */, - 757ADE052934CF32002B3341 /* OSPMTGateway.swift */, - 757ADE072934CF5E002B3341 /* OSPMTGatewayFactory.swift */, - ); - path = Gateways; - sourceTree = ""; - }; 75EC4D132894142000CF50E2 /* Protocols */ = { isa = PBXGroup; children = ( 75EC4D1B2894160400CF50E2 /* OSPMTActionDelegate.swift */, 7509DC7C28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift */, 75EC4D142894143A00CF50E2 /* OSPMTCallbackDelegate.swift */, - 757ADE092934CF92002B3341 /* OSPMTGatewayDelegate.swift */, 75EC4D162894150F00CF50E2 /* OSPMTHandlerDelegate.swift */, 755A8057289BC90A00426EAA /* OSPMTRequestDelegate.swift */, ); @@ -299,6 +254,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 7507FC2127FC2AAE003809F6 /* OSPaymentsLib.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -321,9 +277,6 @@ dependencies = ( ); name = OSPaymentsLib; - packageProductDependencies = ( - 755DF3EF297FF02800140860 /* StripePayments */, - ); productName = OSPaymentsLib; productReference = 7507FC1227FC2AAE003809F6 /* OSPaymentsLib.framework */; productType = "com.apple.product-type.framework"; @@ -376,9 +329,6 @@ Base, ); mainGroup = 7507FC0827FC2AAE003809F6; - packageReferences = ( - 755DF3EE297FF02800140860 /* XCRemoteSwiftPackageReference "stripe-ios-spm" */, - ); productRefGroup = 7507FC1327FC2AAE003809F6 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -448,7 +398,6 @@ }; 75895022289989D200670171 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -495,21 +444,14 @@ files = ( 7509DC7D28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift in Sources */, 75EC4D1A2894156E00CF50E2 /* OSPMTError.swift in Sources */, - 757ADE082934CF5E002B3341 /* OSPMTGatewayFactory.swift in Sources */, - 757ADE062934CF33002B3341 /* OSPMTGateway.swift in Sources */, 755A8056289BC8EE00426EAA /* OSPMTScopeModel.swift in Sources */, - 7556EA952934DAC600FF4044 /* OSPMTRequestParametersModel.swift in Sources */, - 751B1DB2293A2744009A00B2 /* OSPMTStripeRequestParametersModel.swift in Sources */, - 7556EA982934E10D00FF4044 /* OSPMTStripeAPIDelegate.swift in Sources */, 7509DC7728993C4C005BA0D4 /* PKMerchantCapability+Adapter.swift in Sources */, 755A8055289BC8EE00426EAA /* OSPMTDetailsModel.swift in Sources */, 755A804B289BB96900426EAA /* PKPassLibrary+Adapter.swift in Sources */, - 75CC42E829375A6200149E6E /* OSPMTServiceProviderInfoModel.swift in Sources */, 75760F83289C1F99001BDCEC /* PKPayment+Adapter.swift in Sources */, 75EC4D2228942C3800CF50E2 /* OSPMTConfigurationModel.swift in Sources */, 75EC4D172894150F00CF50E2 /* OSPMTHandlerDelegate.swift in Sources */, 755A8058289BC90A00426EAA /* OSPMTRequestDelegate.swift in Sources */, - 757ADE0C2934CFE4002B3341 /* OSPMTStripeWrapper.swift in Sources */, 755A8062289BD56300426EAA /* OSPMTAddressModel.swift in Sources */, 755A8060289BD54E00426EAA /* OSPMTDataModel.swift in Sources */, 755A804D289BBAB300426EAA /* PKPaymentAuthorizationController+Adapter.swift in Sources */, @@ -517,9 +459,8 @@ 7509DC81289967A6005BA0D4 /* PKPaymentNetwork+Adapter.swift in Sources */, 755A8064289BD58900426EAA /* OSPMTContactInfoModel.swift in Sources */, 75EC4D152894143A00CF50E2 /* OSPMTCallbackDelegate.swift in Sources */, + 755A805E289BD53000426EAA /* OSPMTTokenInfoModel.swift in Sources */, 75EC4D1C2894160400CF50E2 /* OSPMTActionDelegate.swift in Sources */, - 757ADE0A2934CF92002B3341 /* OSPMTGatewayDelegate.swift in Sources */, - 756931E62937A9200014618D /* OSPMTTokenInfoModel.swift in Sources */, 755A805A289BC92A00426EAA /* PKContactField+Adapter.swift in Sources */, 75EC4D122893FC3C00CF50E2 /* OSPMTPayments.swift in Sources */, ); @@ -530,7 +471,6 @@ buildActionMask = 2147483647; files = ( 755A805C289BD4C600426EAA /* OSPMTApplePayRequestBehaviourSpec.swift in Sources */, - 7556EA9A2934E4AB00FF4044 /* OSPMTStripeWrapperSpec.swift in Sources */, 75760F7A289C17AB001BDCEC /* OSPMTContactInfoModelSpec.swift in Sources */, 75EC4D262894478200CF50E2 /* OSPMTTestConfigurations.swift in Sources */, 75760F81289C1DF3001BDCEC /* OSPMTScopeModelSpec.swift in Sources */, @@ -541,7 +481,6 @@ 75EC4D242894449700CF50E2 /* OSPMTApplePayHandlerSpec.swift in Sources */, 75E4DCB12897C8AD002277FD /* OSPMTPaymentsSpec.swift in Sources */, 75760F78289C102D001BDCEC /* OSPMTAddressModelSpec.swift in Sources */, - 7556EA9C29350B9B00FF4044 /* OSPMTGatewayFactorySpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -806,25 +745,6 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 755DF3EE297FF02800140860 /* XCRemoteSwiftPackageReference "stripe-ios-spm" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/stripe/stripe-ios-spm"; - requirement = { - kind = exactVersion; - version = 23.2.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 755DF3EF297FF02800140860 /* StripePayments */ = { - isa = XCSwiftPackageProductDependency; - package = 755DF3EE297FF02800140860 /* XCRemoteSwiftPackageReference "stripe-ios-spm" */; - productName = StripePayments; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = 7507FC0927FC2AAE003809F6 /* Project object */; } diff --git a/OSPaymentsLib.xcodeproj/xcshareddata/xcschemes/OSPaymentsLib.xcscheme b/OSPaymentsLib.xcodeproj/xcshareddata/xcschemes/OSPaymentsLib.xcscheme index 7361bb5..d875850 100644 --- a/OSPaymentsLib.xcodeproj/xcshareddata/xcschemes/OSPaymentsLib.xcscheme +++ b/OSPaymentsLib.xcodeproj/xcshareddata/xcschemes/OSPaymentsLib.xcscheme @@ -1,6 +1,6 @@ OSPMTScopeModel? { - var result: [String: Any] = [OSPMTScopeModel.CodingKeys.paymentData.rawValue: self.createTokenDataData(for: paymentGatewayModel)] + func createScopeModel() -> OSPMTScopeModel? { + var result: [String: Any] = [OSPMTScopeModel.CodingKeys.paymentData.rawValue: self.createTokenDataData()] if let shippingContact = self.shippingContact { result[OSPMTScopeModel.CodingKeys.shippingInfo.rawValue] = self.createContactInfoData(for: shippingContact) } - guard let scopeData = try? JSONSerialization.data(withJSONObject: result), + guard + let scopeData = try? JSONSerialization.data(withJSONObject: result), let scopeModel = try? JSONDecoder().decode(OSPMTScopeModel.self, from: scopeData) else { return nil } return scopeModel } /// Converts a `PKPayment` object into a dictionary that relates to an `OSPMTDataModel` object. - /// - Parameter paymentGatewayModel: model that contains the payment gateway information resulting from completing a payment process. /// - Returns: The corresponding `OSPMTDataModel` dictionary object. - private func createTokenDataData(for paymentGatewayModel: OSPMTServiceProviderInfoModel?) -> [String: Any] { + private func createTokenDataData() -> [String: Any] { var result: [String: Any] = [ OSPMTDataModel.CodingKeys.tokenData.rawValue: self.createTokenData(for: self.token.paymentData) ] @@ -33,11 +32,6 @@ extension PKPayment { result[OSPMTDataModel.CodingKeys.cardNetwork.rawValue] = cardNetwork } } - if let paymentGatewayModel = paymentGatewayModel, - let paymentGatewayData = try? JSONEncoder().encode(paymentGatewayModel), - let paymentGatewayDict = try? JSONSerialization.jsonObject(with: paymentGatewayData) as? [String: String] { - result[OSPMTDataModel.CodingKeys.paymentServiceProviderData.rawValue] = paymentGatewayDict - } return result } @@ -46,6 +40,7 @@ extension PKPayment { /// - Parameter paymentData: `Data` type object that contains information related to a payment token. /// - Returns: The corresponding `OSPMTTokenInfoModel` dictionary object. private func createTokenData(for paymentData: Data) -> [String: String] { + // TODO: The type passed here will probably be changed into the Payment Service Provider's name when this is implemented. var result = [OSPMTTokenInfoModel.CodingKeys.type.rawValue: "Apple Pay"] if let token = String(data: paymentData, encoding: .utf8) { diff --git a/OSPaymentsLib/Models/OSPMTConfigurationModel.swift b/OSPaymentsLib/Models/OSPMTConfigurationModel.swift index 0ee249e..565b10e 100644 --- a/OSPaymentsLib/Models/OSPMTConfigurationModel.swift +++ b/OSPaymentsLib/Models/OSPMTConfigurationModel.swift @@ -1,43 +1,6 @@ import PassKit -/// Model that manages the Payment Service Provider's configuration. -struct OSPMTGatewayModel: Encodable { - let gateway: String - let publishableKey: String? - let requestURL: String - - /// Keys used to encode and decode the model. - enum CodingKeys: String, CodingKey { - case gateway - case publishableKey - case requestURL - } - - /// Encodes this value into the given encoder. - /// - /// If the value fails to encode anything, `encoder` will encode an empty - /// keyed container in its place. - /// - /// This function throws an error if any values are invalid for the given - /// encoder's format. - /// - /// - Parameter encoder: The encoder to write data to. - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - - try container.encode(gateway, forKey: .gateway) - try container.encodeIfPresent(publishableKey, forKey: .publishableKey) - try container.encode(requestURL, forKey: .requestURL) - } -} - -extension OSPMTGatewayModel { - var gatewayEnum: OSPMTGateway? { - return OSPMTGateway.convert(from: self.gateway) - } -} - -/// Model that contains all properties needed to configure a payment service. +/// Protocol that contains all properties needed to configure a payment service. class OSPMTConfigurationModel: Encodable { // MARK: Merchant Information var merchantID: String? @@ -55,9 +18,6 @@ class OSPMTConfigurationModel: Encodable { // MARK: Billing Information var billingSupportedContacts: [String]? - // MARK: Payment Service Provider Information - var gatewayModel: OSPMTGatewayModel? - /// Keys used to encode and decode the model. enum CodingKeys: String, CodingKey { case merchantID @@ -68,7 +28,6 @@ class OSPMTConfigurationModel: Encodable { case paymentSupportedCardCountries case shippingSupportedContacts case billingSupportedContacts - case gatewayModel = "tokenization" } /// Constructor method. @@ -81,18 +40,7 @@ class OSPMTConfigurationModel: Encodable { /// - paymentSupportedCardCountries: Payment Support Card Countries configured /// - shippingSupportedContacts: Shipping Supported Contacts configured /// - billingSupportedContacts: Billing Supported Contacts configured - /// - tokenization: Payment Service Gateway configured - init( - merchantID: String?, - merchantName: String?, - merchantCountryCode: String?, - paymentAllowedNetworks: [String]?, - paymentSupportedCapabilities: [String]?, - paymentSupportedCardCountries: [String]?, - shippingSupportedContacts: [String]?, - billingSupportedContacts: [String]?, - gatewayModel: OSPMTGatewayModel? - ) { + init(merchantID: String?, merchantName: String?, merchantCountryCode: String?, paymentAllowedNetworks: [String]?, paymentSupportedCapabilities: [String]?, paymentSupportedCardCountries: [String]?, shippingSupportedContacts: [String]?, billingSupportedContacts: [String]?) { self.merchantID = merchantID self.merchantName = merchantName self.merchantCountryCode = merchantCountryCode @@ -101,7 +49,6 @@ class OSPMTConfigurationModel: Encodable { self.paymentSupportedCardCountries = paymentSupportedCardCountries self.shippingSupportedContacts = shippingSupportedContacts self.billingSupportedContacts = billingSupportedContacts - self.gatewayModel = gatewayModel } /// Encodes this value into the given encoder. @@ -131,13 +78,10 @@ class OSPMTConfigurationModel: Encodable { // MARK: Billing Information try container.encodeIfPresent(billingSupportedContacts, forKey: .billingSupportedContacts) - - // MARK: Payment Service Provider Information - try container.encodeIfPresent(gatewayModel, forKey: .gatewayModel) } } -public typealias OSPMTConfiguration = [String: Any] +typealias OSPMTConfiguration = [String: Any] /// Manages all configuration properties required to enable Apple Pay in the plugin. class OSPMTApplePayConfiguration: OSPMTConfigurationModel { @@ -153,42 +97,42 @@ class OSPMTApplePayConfiguration: OSPMTConfigurationModel { static let shippingSupportedContacts = "ApplePayShippingSupportedContacts" static let billingSupportedContacts = "ApplePayBillingSupportedContacts" - - static let paymentGateway = "ApplePayPaymentGateway" - static let paymentGatewayName = "ApplePayPaymentGatewayName" - static let paymentRequestURL = "ApplePayRequestURL" - static let stripePublishableKey = "ApplePayStripePublishableKey" } /// Constructor method. /// - Parameter source: Source class contaning the configuration. convenience init(source: OSPMTConfiguration) { // MARK: Merchant Information - let merchantID: String? = Self.getRequiredProperty(forSource: source, andKey: ConfigurationKeys.merchantID) - let merchantName: String? = Self.getRequiredProperty(forSource: source, andKey: ConfigurationKeys.merchantName) - let merchantCountryCode: String? = Self.getRequiredProperty(forSource: source, andKey: ConfigurationKeys.merchantCountryCode) + let merchantID = Self.getRequiredProperty( + ofType: String.self, forSource: source, andKey: ConfigurationKeys.merchantID + ) + let merchantName = Self.getRequiredProperty( + ofType: String.self, forSource: source, andKey: ConfigurationKeys.merchantName + ) + let merchantCountryCode = Self.getRequiredProperty( + ofType: String.self, forSource: source, andKey: ConfigurationKeys.merchantCountryCode + ) // MARK: Payment Information - let paymentAllowedNetworks: [String]? = Self.getRequiredProperty(forSource: source, andKey: ConfigurationKeys.paymentAllowedNetworks) - let paymentSupportedCapabilities: [String]? = Self.getRequiredProperty( - forSource: source, andKey: ConfigurationKeys.paymentSupportedCapabilities + let paymentAllowedNetworks = Self.getRequiredProperty( + ofType: [String].self, forSource: source, andKey: ConfigurationKeys.paymentAllowedNetworks + ) + let paymentSupportedCapabilities = Self.getRequiredProperty( + ofType: [String].self, forSource: source, andKey: ConfigurationKeys.paymentSupportedCapabilities + ) + let paymentSupportedCardCountries = Self.getProperty( + ofType: [String].self, forSource: source, andKey: ConfigurationKeys.paymentSupportedCardCountries ) - let paymentSupportedCardCountries: [String]? = Self.getProperty(forSource: source, andKey: ConfigurationKeys.paymentSupportedCardCountries) // MARK: Shipping Information - let shippingSupportedContacts: [String]? = Self.getProperty(forSource: source, andKey: ConfigurationKeys.shippingSupportedContacts) + let shippingSupportedContacts = Self.getProperty( + ofType: [String].self, forSource: source, andKey: ConfigurationKeys.shippingSupportedContacts + ) // MARK: Billing Information - let billingSupportedContacts: [String]? = Self.getProperty(forSource: source, andKey: ConfigurationKeys.billingSupportedContacts) - - // MARK: Payment Service Provider Information - var gatewayModel: OSPMTGatewayModel? - if let providerGateway: [String: Any] = Self.getProperty(forSource: source, andKey: ConfigurationKeys.paymentGateway), - let providerGatewayName = providerGateway[ConfigurationKeys.paymentGatewayName] as? String, - let requestURL = providerGateway[ConfigurationKeys.paymentRequestURL] as? String { - let publishableKey = providerGateway[ConfigurationKeys.stripePublishableKey] as? String - gatewayModel = OSPMTGatewayModel(gateway: providerGatewayName, publishableKey: publishableKey, requestURL: requestURL) - } + let billingSupportedContacts = Self.getProperty( + ofType: [String].self, forSource: source, andKey: ConfigurationKeys.billingSupportedContacts + ) self.init( merchantID: merchantID, @@ -198,8 +142,7 @@ class OSPMTApplePayConfiguration: OSPMTConfigurationModel { paymentSupportedCapabilities: paymentSupportedCapabilities, paymentSupportedCardCountries: paymentSupportedCardCountries, shippingSupportedContacts: shippingSupportedContacts, - billingSupportedContacts: billingSupportedContacts, - gatewayModel: gatewayModel + billingSupportedContacts: billingSupportedContacts ) } } @@ -211,7 +154,7 @@ private extension OSPMTApplePayConfiguration { /// - key: Property key to search from. /// - isRequired: Indicates if the property is mandatory or not. /// - Returns: The configuration property, if it exists. - static func getProperty(forSource source: OSPMTConfiguration, andKey key: String, isRequired: Bool = false) -> T? { + static func getProperty(ofType type: T.Type, forSource source: OSPMTConfiguration, andKey key: String, isRequired: Bool = false) -> T? { let result = source[key] as? T return !isRequired || result?.isEmpty == false ? result : nil } @@ -221,8 +164,8 @@ private extension OSPMTApplePayConfiguration { /// - type: Type of variable to return. /// - key: Property key to search from. /// - Returns: The configuration property, if it exists. - static func getRequiredProperty(forSource source: OSPMTConfiguration, andKey key: String) -> T? { - self.getProperty(forSource: source, andKey: key, isRequired: true) + static func getRequiredProperty(ofType type: T.Type, forSource source: OSPMTConfiguration, andKey key: String) -> T? { + self.getProperty(ofType: type, forSource: source, andKey: key, isRequired: true) } } diff --git a/OSPaymentsLib/Models/OSPMTDataModel.swift b/OSPaymentsLib/Models/OSPMTDataModel.swift index fe860fd..a427af8 100644 --- a/OSPaymentsLib/Models/OSPMTDataModel.swift +++ b/OSPaymentsLib/Models/OSPMTDataModel.swift @@ -4,11 +4,10 @@ struct OSPMTDataModel: Codable { let cardDetails: String let cardNetwork: String let tokenData: OSPMTTokenInfoModel - let paymentServiceProviderData: OSPMTServiceProviderInfoModel? /// Keys used to encode and decode the model. enum CodingKeys: String, CodingKey { - case billingInfo, cardDetails, cardNetwork, tokenData, paymentServiceProviderData + case billingInfo, cardDetails, cardNetwork, tokenData } /// Constructor method. @@ -17,13 +16,11 @@ struct OSPMTDataModel: Codable { /// - cardDetails: The last four digits of the card used for payment. /// - cardNetwork: The network of the card used for payment. /// - tokenData: The data of the token used for payment. - /// - paymentServiceProviderData: Information related with the payment gateway process result. If can be `nil` if no Gateway was configured - init(billingInfo: OSPMTContactInfoModel? = nil, cardDetails: String, cardNetwork: String, tokenData: OSPMTTokenInfoModel, paymentServiceProviderData: OSPMTServiceProviderInfoModel? = nil) { + init(billingInfo: OSPMTContactInfoModel? = nil, cardDetails: String, cardNetwork: String, tokenData: OSPMTTokenInfoModel) { self.billingInfo = billingInfo self.cardDetails = cardDetails self.cardNetwork = cardNetwork self.tokenData = tokenData - self.paymentServiceProviderData = paymentServiceProviderData } /// Creates a new instance by decoding from the given decoder. @@ -38,14 +35,7 @@ struct OSPMTDataModel: Codable { let cardDetails = try container.decode(String.self, forKey: .cardDetails) let cardNetwork = try container.decode(String.self, forKey: .cardNetwork) let tokenData = try container.decode(OSPMTTokenInfoModel.self, forKey: .tokenData) - let paymentServiceProviderData = try container.decodeIfPresent(OSPMTServiceProviderInfoModel.self, forKey: .paymentServiceProviderData) - self.init( - billingInfo: billingInfo, - cardDetails: cardDetails, - cardNetwork: cardNetwork, - tokenData: tokenData, - paymentServiceProviderData: paymentServiceProviderData - ) + self.init(billingInfo: billingInfo, cardDetails: cardDetails, cardNetwork: cardNetwork, tokenData: tokenData) } /// Encodes this value into the given encoder. @@ -63,7 +53,6 @@ struct OSPMTDataModel: Codable { try container.encode(cardDetails, forKey: .cardDetails) try container.encode(cardNetwork, forKey: .cardNetwork) try container.encode(tokenData, forKey: .tokenData) - try container.encodeIfPresent(paymentServiceProviderData, forKey: .paymentServiceProviderData) } } @@ -82,6 +71,5 @@ extension OSPMTDataModel: Equatable { && lhs.cardDetails == rhs.cardDetails && lhs.cardNetwork == rhs.cardNetwork && lhs.tokenData == rhs.tokenData - && lhs.paymentServiceProviderData == rhs.paymentServiceProviderData } } diff --git a/OSPaymentsLib/Models/OSPMTDetailsModel.swift b/OSPaymentsLib/Models/OSPMTDetailsModel.swift index 00989f2..a991c3b 100644 --- a/OSPaymentsLib/Models/OSPMTDetailsModel.swift +++ b/OSPaymentsLib/Models/OSPMTDetailsModel.swift @@ -47,7 +47,6 @@ struct OSPMTDetailsModel: Decodable { let status: OSPMTStatus let shippingContact: OSPMTContact let billingContact: OSPMTContact - let gateway: OSPMTGateway? /// Keys used to encode and decode the model. enum CodingKeys: String, CodingKey { @@ -56,7 +55,6 @@ struct OSPMTDetailsModel: Decodable { case status case shippingContact = "shippingContacts" case billingContact = "billingContacts" - case gateway = "psp" } /// Constructor method. @@ -66,14 +64,12 @@ struct OSPMTDetailsModel: Decodable { /// - status: Final value status. /// - shippingContact: Shipping properties required for filling. /// - billingContact: Billiing properties required for filling. - /// - gateway: Payment service provided to be used for processing, if passed. - init(amount: Decimal, currency: String, status: OSPMTStatus, shippingContact: OSPMTContact, billingContact: OSPMTContact, gateway: String? = nil) { + init(amount: Decimal, currency: String, status: OSPMTStatus, shippingContact: OSPMTContact, billingContact: OSPMTContact) { self.amount = amount self.currency = currency self.status = status self.shippingContact = shippingContact self.billingContact = billingContact - self.gateway = OSPMTGateway.convert(from: gateway) } /// Creates a new instance by decoding from the given decoder. @@ -89,9 +85,8 @@ struct OSPMTDetailsModel: Decodable { let status = try container.decode(OSPMTStatus.self, forKey: .status) let shippingContact = try container.decode(OSPMTContact.self, forKey: .shippingContact) let billingContact = try container.decode(OSPMTContact.self, forKey: .billingContact) - let gateway = try container.decodeIfPresent(String.self, forKey: .gateway) self.init( - amount: amount, currency: currency, status: status, shippingContact: shippingContact, billingContact: billingContact, gateway: gateway + amount: amount, currency: currency, status: status, shippingContact: shippingContact, billingContact: billingContact ) } } diff --git a/OSPaymentsLib/OSPMTApplePayHandler.swift b/OSPaymentsLib/OSPMTApplePayHandler.swift index 7bc4956..b60ae67 100644 --- a/OSPaymentsLib/OSPMTApplePayHandler.swift +++ b/OSPaymentsLib/OSPMTApplePayHandler.swift @@ -1,5 +1,3 @@ -import Foundation - /// Class resopnsible to manage the Apple Pay payment service requests. It delegates every operation type to its manager. class OSPMTApplePayHandler: NSObject { let configuration: OSPMTConfigurationModel @@ -53,9 +51,8 @@ extension OSPMTApplePayHandler: OSPMTHandlerDelegate { /// Sets Payment details and triggers its processing. /// - Parameters: /// - detailsModel: payment details information. - /// - accessToken: Authorisation token related with a full payment type. /// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise. - func set(_ detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler) { - self.requestBehaviour.trigger(with: detailsModel, and: accessToken, completion) + func set(_ detailsModel: OSPMTDetailsModel, completion: @escaping OSPMTCompletionHandler) { + self.requestBehaviour.trigger(with: detailsModel, completion) } } diff --git a/OSPaymentsLib/OSPMTPayments.swift b/OSPaymentsLib/OSPMTPayments.swift index 9539659..9a429c1 100644 --- a/OSPaymentsLib/OSPMTPayments.swift +++ b/OSPaymentsLib/OSPMTPayments.swift @@ -1,7 +1,5 @@ -import Foundation - /// Class that provides the bridge between the library and 3rd party consumers. -public class OSPMTPayments: NSObject { +class OSPMTPayments: NSObject { private weak var delegate: OSPMTCallbackDelegate? private let handler: OSPMTHandlerDelegate @@ -18,7 +16,7 @@ public class OSPMTPayments: NSObject { /// - Parameters: /// - delegate: Handles the asynchronous return calls. /// - configurationSource: Configuration source, containing all values needed to configure. - public convenience init(applePayWithDelegate delegate: OSPMTCallbackDelegate, andConfiguration configurationSource: OSPMTConfiguration = Bundle.main.infoDictionary!) { + convenience init(applePayWithDelegate delegate: OSPMTCallbackDelegate, andConfiguration configurationSource: OSPMTConfiguration = Bundle.main.infoDictionary!) { let applePayHandler = OSPMTApplePayHandler(configurationSource: configurationSource) self.init(delegate: delegate, handler: applePayHandler) } @@ -27,7 +25,7 @@ public class OSPMTPayments: NSObject { // MARK: - Action Methods to be called by Bridge extension OSPMTPayments: OSPMTActionDelegate { /// Sets up the payment configuration. - public func setupConfiguration() { + func setupConfiguration() { let result = self.handler.setupConfiguration() switch result { @@ -39,7 +37,7 @@ extension OSPMTPayments: OSPMTActionDelegate { } /// Verifies the device is ready to process a payment, considering the configuration provided before. - public func checkWalletSetup() { + func checkWalletSetup() { if let error = self.handler.checkWalletAvailability() { self.delegate?.callback(error: error) } else { @@ -47,15 +45,13 @@ extension OSPMTPayments: OSPMTActionDelegate { } } - /// Sets payment details and triggers the request process. - /// - Parameters: - /// - details: Payment details model serialized into a text field. - /// - accessToken: Authorisation token related with a full payment type. - public func set(_ details: String, and accessToken: String?) { + /// Sets payment details and triggers the request proccess. + /// - Parameter details: Payment details model serialized into a text field. + func set(_ details: String) { let detailsResult = self.decode(details) switch detailsResult { case .success(let detailsModel): - self.handler.set(detailsModel, and: accessToken) { [weak self] result in + self.handler.set(detailsModel) { [weak self] result in guard let self = self else { return } switch result { case .success(let scopeModel): diff --git a/OSPaymentsLib/Protocols/OSPMTActionDelegate.swift b/OSPaymentsLib/Protocols/OSPMTActionDelegate.swift index 6b161cf..a990bcd 100644 --- a/OSPaymentsLib/Protocols/OSPMTActionDelegate.swift +++ b/OSPaymentsLib/Protocols/OSPMTActionDelegate.swift @@ -1,5 +1,5 @@ /// Protocol that provides the server actions the plugin provides. -public protocol OSPMTActionDelegate: AnyObject { +protocol OSPMTActionDelegate: AnyObject { /// Sets up the payment configuration. func setupConfiguration() @@ -7,16 +7,6 @@ public protocol OSPMTActionDelegate: AnyObject { func checkWalletSetup() /// Sets payment details and triggers the request proccess. - /// - Parameters: - /// - details: Payment details model serialized into a text field. - /// - accessToken: Authorisation token related with a full payment type. - func set(_ details: String, and accessToken: String?) -} - -public extension OSPMTActionDelegate { - /// Sets payment details and triggers the request proccess. This uses the default method without the `accessToken` parameter. /// - Parameter details: Payment details model serialized into a text field. - func set(_ details: String) { - self.set(details, and: nil) - } + func set(_ details: String) } diff --git a/OSPaymentsLib/Protocols/OSPMTCallbackDelegate.swift b/OSPaymentsLib/Protocols/OSPMTCallbackDelegate.swift index 2abd5c9..3f72095 100644 --- a/OSPaymentsLib/Protocols/OSPMTCallbackDelegate.swift +++ b/OSPaymentsLib/Protocols/OSPMTCallbackDelegate.swift @@ -1,5 +1,5 @@ /// Delegate for the callback return calls for the plugin -public protocol OSPMTCallbackDelegate: AnyObject { +protocol OSPMTCallbackDelegate: AnyObject { func callback(result: String?, error: OSPMTError?) } diff --git a/OSPaymentsLib/Protocols/OSPMTHandlerDelegate.swift b/OSPaymentsLib/Protocols/OSPMTHandlerDelegate.swift index 9cbb498..06a759b 100644 --- a/OSPaymentsLib/Protocols/OSPMTHandlerDelegate.swift +++ b/OSPaymentsLib/Protocols/OSPMTHandlerDelegate.swift @@ -13,17 +13,6 @@ protocol OSPMTHandlerDelegate: AnyObject { /// Sets Payment details and triggers its processing. /// - Parameters: /// - detailsModel: payment details information. - /// - accessToken: Authorisation token related with a full payment type. /// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise. - func set(_ detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler) -} - -extension OSPMTHandlerDelegate { - /// Sets Payment details and triggers its processing. It uses the default `set` method without the `accessToken` parameter. - /// - Parameters: - /// - detailsModel: payment details information. - /// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise. - func set(_ detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler) { - self.set(detailsModel, and: nil, completion) - } + func set(_ detailsModel: OSPMTDetailsModel, completion: @escaping OSPMTCompletionHandler) } diff --git a/OSPaymentsLib/Protocols/OSPMTRequestDelegate.swift b/OSPaymentsLib/Protocols/OSPMTRequestDelegate.swift index 5922531..2a5e2c3 100644 --- a/OSPaymentsLib/Protocols/OSPMTRequestDelegate.swift +++ b/OSPaymentsLib/Protocols/OSPMTRequestDelegate.swift @@ -25,19 +25,8 @@ protocol OSPMTRequestDelegate: AnyObject { /// Sets Payment details and triggers its processing. /// - Parameters: /// - detailsModel: payment details information. - /// - accessToken: Authorisation token related with a full payment type. /// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise. - func trigger(with detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler) -} - -extension OSPMTRequestDelegate { - /// Sets Payment details and triggers its processing. It uses the default method without the `accessToken` parameter. - /// - Parameters: - /// - detailsModel: payment details information. - /// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise. - func trigger(with detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler) { - self.trigger(with: detailsModel, and: nil, completion) - } + func trigger(with detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler) } /// Class that implements the `OSPMTRequestDelegate` for Apple Pay, providing it the required that details to work. @@ -47,8 +36,6 @@ class OSPMTApplePayRequestBehaviour: NSObject, OSPMTRequestDelegate { var paymentStatus: PKPaymentAuthorizationStatus = .failure var paymentScope: OSPMTScopeModel? - var paymentDetails: OSPMTDetailsModel? - var accessToken: String? var completionHandler: OSPMTCompletionHandler! /// Constructor method. @@ -60,14 +47,7 @@ class OSPMTApplePayRequestBehaviour: NSObject, OSPMTRequestDelegate { self.requestTriggerType = requestTriggerType } - /// Sets Payment details and triggers its processing. - /// - Parameters: - /// - detailsModel: payment details information. - /// - accessToken: Authorisation token related with a full payment type. - /// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise. - func trigger(with detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler) { - self.paymentDetails = detailsModel - self.accessToken = accessToken + func trigger(with detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler) { self.completionHandler = completion let result = self.requestTriggerType.createRequestTriggerBehaviour(for: detailsModel, andDelegate: self) @@ -110,6 +90,8 @@ extension OSPMTApplePayRequestBehaviour { // MARK: - Set up PKPaymentAuthorizationControllerDelegate conformance extension OSPMTApplePayRequestBehaviour: PKPaymentAuthorizationControllerDelegate { + /// Tells the delegate that payment authorization finished. + /// - Parameter controller: The payment authorization view controller. func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) { controller.dismiss() // The payment sheet doesn't automatically dismiss once it has finished. Dismiss the payment sheet. @@ -122,53 +104,20 @@ extension OSPMTApplePayRequestBehaviour: PKPaymentAuthorizationControllerDelegat } } + /// Tells the delegate that the user authorized the payment request, and asks for a result. + /// - Parameters: + /// - controller: The payment authorization view controller. + /// - payment: The authorized payment. This object contains the payment token you need to submit to your payment processor, as well as the billing and shipping information required by the payment request. + /// - completion: The completion handler to call with the result of authorizing the payment. func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) { - func setPaymentResults(with errorArray: [OSPMTError], and scopeModel: OSPMTScopeModel?, _ completion: @escaping (PKPaymentAuthorizationResult) -> Void) { - if errorArray.isEmpty, let scopeModel = scopeModel { - self.paymentScope = scopeModel - self.paymentStatus = .success - } else { - self.paymentScope = nil - self.paymentStatus = .failure - } - - completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: errorArray)) - } - - if let paymentDetails = paymentDetails, paymentDetails.gateway != nil { - guard let accessToken = self.accessToken, !accessToken.isEmpty else { - return completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: [OSPMTError.tokenIssue])) - } - - guard let paymentGateway = self.configuration.gatewayModel, paymentGateway.gatewayEnum == paymentDetails.gateway else { - return completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: [OSPMTError.gatewayNotConfigured])) - } - - guard let gatewayWrapper = OSPMTGatewayFactory.createWrapper(for: paymentGateway) else { - return completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: [OSPMTError.gatewaySetFailed])) - } - - gatewayWrapper.process(payment, with: paymentDetails, and: accessToken) { result in - var errorArray = [OSPMTError]() - var paymentResultModel: OSPMTServiceProviderInfoModel? - - switch result { - case .success(let result): - paymentResultModel = result - case .failure(let error): - errorArray += [error] - } - - setPaymentResults(with: errorArray, and: payment.createScopeModel(for: paymentResultModel), completion) - } + if let scopeModel = payment.createScopeModel() { + self.paymentScope = scopeModel + self.paymentStatus = .success } else { - setPaymentResults(with: [], and: payment.createScopeModel(), completion) + self.paymentScope = nil + self.paymentStatus = .failure } + + completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: [])) } - - /** - Despite the need to implement the method, this is not required by app's functionality. - For that reason, we're returning `nil` as the presentation window. - */ - func presentationWindow(for controller: PKPaymentAuthorizationController) -> UIWindow? { nil } } diff --git a/OSPaymentsLibTests/ModelSpecs/OSPMTAddressModelSpec.swift b/OSPaymentsLibTests/ModelSpecs/OSPMTAddressModelSpec.swift index ba53556..5048f1c 100644 --- a/OSPaymentsLibTests/ModelSpecs/OSPMTAddressModelSpec.swift +++ b/OSPaymentsLibTests/ModelSpecs/OSPMTAddressModelSpec.swift @@ -80,7 +80,7 @@ class OSPMTAddressModelSpec: QuickSpec { ) } - override class func spec() { + override func spec() { describe("Given a full configuration") { context("When decoding the Address Model") { it("Should return a filled object") { diff --git a/OSPaymentsLibTests/ModelSpecs/OSPMTContactInfoModelSpec.swift b/OSPaymentsLibTests/ModelSpecs/OSPMTContactInfoModelSpec.swift index d0c6583..fc4c0c5 100644 --- a/OSPaymentsLibTests/ModelSpecs/OSPMTContactInfoModelSpec.swift +++ b/OSPaymentsLibTests/ModelSpecs/OSPMTContactInfoModelSpec.swift @@ -60,7 +60,7 @@ class OSPMTContactInfoModelSpec: QuickSpec { ) } - override class func spec() { + override func spec() { describe("Given a full configuration") { context("When decoding the Contact Info Model") { it("Should return a filled object") { diff --git a/OSPaymentsLibTests/ModelSpecs/OSPMTDataModelSpec.swift b/OSPaymentsLibTests/ModelSpecs/OSPMTDataModelSpec.swift index cd6a248..dd4c715 100644 --- a/OSPaymentsLibTests/ModelSpecs/OSPMTDataModelSpec.swift +++ b/OSPaymentsLibTests/ModelSpecs/OSPMTDataModelSpec.swift @@ -45,7 +45,7 @@ class OSPMTDataModelSpec: QuickSpec { ) } - override class func spec() { + override func spec() { describe("Given a full configuration") { context("When decoding the Data Model") { it("Should return a filled object") { diff --git a/OSPaymentsLibTests/ModelSpecs/OSPMTScopeModelSpec.swift b/OSPaymentsLibTests/ModelSpecs/OSPMTScopeModelSpec.swift index 42aa7ad..7545dea 100644 --- a/OSPaymentsLibTests/ModelSpecs/OSPMTScopeModelSpec.swift +++ b/OSPaymentsLibTests/ModelSpecs/OSPMTScopeModelSpec.swift @@ -22,7 +22,7 @@ class OSPMTScopeModelSpec: QuickSpec { static let paymentRequest = PKPaymentRequest() } - override class func spec() { + override func spec() { describe("Given a full configuration") { context("When decoding the Data Model") { it("Should return a filled object") { diff --git a/OSPaymentsLibTests/ModelSpecs/OSPMTTokenInfoModelSpec.swift b/OSPaymentsLibTests/ModelSpecs/OSPMTTokenInfoModelSpec.swift index 0ec8e34..6bce82b 100644 --- a/OSPaymentsLibTests/ModelSpecs/OSPMTTokenInfoModelSpec.swift +++ b/OSPaymentsLibTests/ModelSpecs/OSPMTTokenInfoModelSpec.swift @@ -15,7 +15,7 @@ class OSPMTTokenInfoModelSpec: QuickSpec { static let fullModel = OSPMTTokenInfoModel(token: OSPMTTestConfigurations.dummyString, type: OSPMTTestConfigurations.dummyString) } - override class func spec() { + override func spec() { describe("Given a full configuration") { context("When decoding the Token Info Model") { it("Should return a filled object") { diff --git a/OSPaymentsLibTests/OSPMTApplePayAvailabilityBehaviourSpec.swift b/OSPaymentsLibTests/OSPMTApplePayAvailabilityBehaviourSpec.swift index 0c7e6f3..2a8a20f 100644 --- a/OSPaymentsLibTests/OSPMTApplePayAvailabilityBehaviourSpec.swift +++ b/OSPaymentsLibTests/OSPMTApplePayAvailabilityBehaviourSpec.swift @@ -25,7 +25,7 @@ class MockSetupAvailableBehaviour: OSPMTApplePaySetupAvailabilityDelegate { } class OSPMTApplePayAvailabilityBehaviourSpec: QuickSpec { - override class func spec() { + override func spec() { var applePayAvailabilityBehaviour: OSPMTApplePayAvailabilityBehaviour! let mockConfiguration = OSPMTApplePayConfiguration(source: OSPMTTestConfigurations.validNetworkCapabilityConfig) diff --git a/OSPaymentsLibTests/OSPMTApplePayConfigurationSpec.swift b/OSPaymentsLibTests/OSPMTApplePayConfigurationSpec.swift index d889705..54bc9b1 100644 --- a/OSPaymentsLibTests/OSPMTApplePayConfigurationSpec.swift +++ b/OSPaymentsLibTests/OSPMTApplePayConfigurationSpec.swift @@ -4,7 +4,7 @@ import Quick @testable import OSPaymentsLib class OSPMTApplePayConfigurationSpec: QuickSpec { - override class func spec() { + override func spec() { var applePayConfiguration: OSPMTApplePayConfiguration! describe("Given a correct configuration") { diff --git a/OSPaymentsLibTests/OSPMTApplePayHandlerSpec.swift b/OSPaymentsLibTests/OSPMTApplePayHandlerSpec.swift index 64bfb0f..c02d4c7 100644 --- a/OSPaymentsLibTests/OSPMTApplePayHandlerSpec.swift +++ b/OSPaymentsLibTests/OSPMTApplePayHandlerSpec.swift @@ -31,7 +31,7 @@ class OSPMTMockRequestBehaviour: OSPMTRequestDelegate { self.scopeModel = scopeModel } - func trigger(with detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler) { + func trigger(with detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler) { if let error = self.error { completion(.failure(error)) } else { @@ -41,7 +41,7 @@ class OSPMTMockRequestBehaviour: OSPMTRequestDelegate { } class OSPMTApplePayHandlerSpec: QuickSpec { - override class func spec() { + override func spec() { var applePayHandler: OSPMTApplePayHandler! var mockAvailabilityBehaviour: OSPMTMockAvailabilityBehaviour! var mockRequestBehaviour: OSPMTMockRequestBehaviour! diff --git a/OSPaymentsLibTests/OSPMTApplePayRequestBehaviourSpec.swift b/OSPaymentsLibTests/OSPMTApplePayRequestBehaviourSpec.swift index 1347bd5..9ae1667 100644 --- a/OSPaymentsLibTests/OSPMTApplePayRequestBehaviourSpec.swift +++ b/OSPaymentsLibTests/OSPMTApplePayRequestBehaviourSpec.swift @@ -25,7 +25,7 @@ class MockRequestTriggerBehaviour: OSPMTApplePayRequestTriggerDelegate { } class OSPMTApplePayRequestBehaviourSpec: QuickSpec { - override class func spec() { + override func spec() { var applePayRequestBehaviour: OSPMTApplePayRequestBehaviour! var mockConfiguration: OSPMTApplePayConfiguration! diff --git a/OSPaymentsLibTests/OSPMTPaymentsSpec.swift b/OSPaymentsLibTests/OSPMTPaymentsSpec.swift index 037467d..4770295 100644 --- a/OSPaymentsLibTests/OSPMTPaymentsSpec.swift +++ b/OSPaymentsLibTests/OSPMTPaymentsSpec.swift @@ -35,7 +35,7 @@ class OSPMTMockHandler: OSPMTHandlerDelegate { return self.error } - func set(_ detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler) { + func set(_ detailsModel: OSPMTDetailsModel, completion: @escaping OSPMTCompletionHandler) { if let error = self.error { completion(.failure(error)) } else if let scopeModel = self.scopeModel { @@ -45,7 +45,7 @@ class OSPMTMockHandler: OSPMTHandlerDelegate { } class OSPMTPaymentsSpec: QuickSpec { - override class func spec() { + override func spec() { var mockDelegate: OSPMTMockCallback! var mockHandler: OSPMTMockHandler! var payments: OSPMTPayments! @@ -86,12 +86,8 @@ class OSPMTPaymentsSpec: QuickSpec { expect(mockDelegate.error).to(beNil()) let result = payments.encode(OSPMTTestConfigurations.dummyScopeModel) - if case let .success(scopeText) = result, - let scopeTextData = scopeText.data(using: .utf8), - let successTextData = mockDelegate.successText?.data(using: .utf8), - let scopeObject = try? JSONSerialization.jsonObject(with: scopeTextData) as? [String: Any], - let successTextObject = try? JSONSerialization.jsonObject(with: successTextData) as? [String: Any] { - expect(NSDictionary(dictionary: scopeObject)).to(equal(NSDictionary(dictionary: successTextObject))) + if case let .success(scopeText) = result { + expect(mockDelegate.successText).to(equal(scopeText)) } else { fail() } @@ -122,14 +118,9 @@ class OSPMTPaymentsSpec: QuickSpec { payments.set(detailsString) expect(mockDelegate.error).to(beNil()) - let result = payments.encode(OSPMTTestConfigurations.useConfigurationBillingScopeModel) - if case let .success(scopeText) = result, - let scopeTextData = scopeText.data(using: .utf8), - let successTextData = mockDelegate.successText?.data(using: .utf8), - let scopeObject = try? JSONSerialization.jsonObject(with: scopeTextData) as? [String: Any], - let successTextObject = try? JSONSerialization.jsonObject(with: successTextData) as? [String: Any] { - expect(NSDictionary(dictionary: scopeObject)).to(equal(NSDictionary(dictionary: successTextObject))) + if case let .success(scopeText) = result { + expect(mockDelegate.successText).to(equal(scopeText)) } else { fail() } @@ -198,38 +189,16 @@ class OSPMTPaymentsSpec: QuickSpec { describe("and an Apple Pay Handler correctly configured") { context("When the OSPMTPayments object is initialized") { - it("Setup configuration should return a non empty text message") { + beforeEach { payments = OSPMTPayments(applePayWithDelegate: mockDelegate, andConfiguration: OSPMTTestConfigurations.fullConfig) - + } + + it("Setup configuration should return a non empty text message") { payments.setupConfiguration() expect(mockDelegate.successText).toNot(beEmpty()) expect(mockDelegate.error).to(beNil()) } - - context("And Payment Gateway information is provided") { - it("Setup configuration should return a non empty text message") { - payments = OSPMTPayments(applePayWithDelegate: mockDelegate, andConfiguration: OSPMTTestConfigurations.dummyGatewayConfig) - - payments.setupConfiguration() - - expect(mockDelegate.successText).toNot(beEmpty()) - expect(mockDelegate.error).to(beNil()) - } - } - - context("And a Stripe Payment Gateway information is provided") { - it("Setup configuration should return a non empty text message") { - payments = OSPMTPayments( - applePayWithDelegate: mockDelegate, andConfiguration: OSPMTTestConfigurations.stripeGatewayConfig - ) - - payments.setupConfiguration() - - expect(mockDelegate.successText).toNot(beEmpty()) - expect(mockDelegate.error).to(beNil()) - } - } } } } diff --git a/OSPaymentsLibTests/OSPMTTestConfigurations.swift b/OSPaymentsLibTests/OSPMTTestConfigurations.swift index 2f61da2..63de031 100644 --- a/OSPaymentsLibTests/OSPMTTestConfigurations.swift +++ b/OSPaymentsLibTests/OSPMTTestConfigurations.swift @@ -57,39 +57,6 @@ struct OSPMTTestConfigurations { static let nilNetworkCapabilityConfig: OSPMTConfiguration = [:] - static let dummyGatewayConfig: OSPMTConfiguration = [ - OSPMTApplePayConfiguration.ConfigurationKeys.merchantID: Self.dummyString, - OSPMTApplePayConfiguration.ConfigurationKeys.merchantName: Self.dummyString, - OSPMTApplePayConfiguration.ConfigurationKeys.merchantCountryCode: Self.dummyString, - OSPMTApplePayConfiguration.ConfigurationKeys.paymentAllowedNetworks: [Self.dummyString], - OSPMTApplePayConfiguration.ConfigurationKeys.paymentSupportedCapabilities: [Self.dummyString], - OSPMTApplePayConfiguration.ConfigurationKeys.paymentSupportedCardCountries: [Self.dummyString], - OSPMTApplePayConfiguration.ConfigurationKeys.shippingSupportedContacts: [Self.dummyString, Self.dummyString], - OSPMTApplePayConfiguration.ConfigurationKeys.billingSupportedContacts: [Self.dummyString, Self.dummyString], - OSPMTApplePayConfiguration.ConfigurationKeys.paymentGateway: [ - OSPMTApplePayConfiguration.ConfigurationKeys.paymentGatewayName: Self.dummyString, - OSPMTApplePayConfiguration.ConfigurationKeys.paymentRequestURL: Self.dummyString - ], - OSPMTApplePayConfiguration.ConfigurationKeys.paymentRequestURL: Self.dummyString - ] - - static let stripeGatewayConfig: OSPMTConfiguration = [ - OSPMTApplePayConfiguration.ConfigurationKeys.merchantID: Self.dummyString, - OSPMTApplePayConfiguration.ConfigurationKeys.merchantName: Self.dummyString, - OSPMTApplePayConfiguration.ConfigurationKeys.merchantCountryCode: Self.dummyString, - OSPMTApplePayConfiguration.ConfigurationKeys.paymentAllowedNetworks: [Self.dummyString], - OSPMTApplePayConfiguration.ConfigurationKeys.paymentSupportedCapabilities: [Self.dummyString], - OSPMTApplePayConfiguration.ConfigurationKeys.paymentSupportedCardCountries: [Self.dummyString], - OSPMTApplePayConfiguration.ConfigurationKeys.shippingSupportedContacts: [Self.dummyString, Self.dummyString], - OSPMTApplePayConfiguration.ConfigurationKeys.billingSupportedContacts: [Self.dummyString, Self.dummyString], - OSPMTApplePayConfiguration.ConfigurationKeys.paymentGateway: [ - OSPMTApplePayConfiguration.ConfigurationKeys.paymentGatewayName: OSPMTGateway.stripe.rawValue, - OSPMTApplePayConfiguration.ConfigurationKeys.paymentRequestURL: Self.dummyString, - OSPMTApplePayConfiguration.ConfigurationKeys.stripePublishableKey: Self.dummyString - ], - OSPMTApplePayConfiguration.ConfigurationKeys.paymentRequestURL: Self.dummyString - ] - // MARK: - OSPMTApplePayRequestBehaviourSpec Configurations static let dummyContact = OSPMTContact(isCustom: true, contactArray: [Self.dummyString]) static let dummyDetailsModel = OSPMTDetailsModel( @@ -170,21 +137,4 @@ struct OSPMTTestConfigurations { guard let data = try? JSONEncoder().encode(model), let result = String(data: data, encoding: .utf8) else { return nil } return result } - - // MARK: - OSPMTGatewayFactorySpec Configurations - - static let validStripeModel = OSPMTGatewayModel( - gateway: OSPMTGateway.stripe.rawValue, publishableKey: Self.dummyString, requestURL: Self.dummyString - ) - static let invalidStripeModel = OSPMTGatewayModel( - gateway: OSPMTGateway.stripe.rawValue, publishableKey: nil, requestURL: Self.dummyString - ) - static let invalidGatewayModel = OSPMTGatewayModel( - gateway: Self.dummyString, publishableKey: Self.dummyString, requestURL: Self.dummyString - ) - - static let invalidPaymentProcessResultModel = OSPMTServiceProviderInfoModel(id: Self.dummyString, status: OSPMTProcessStatus.fail.rawValue) - static let validPaymentProcessResultModel = OSPMTServiceProviderInfoModel(id: Self.dummyString, status: OSPMTProcessStatus.success.rawValue) - - static let dummyAccessToken = "dummy" } diff --git a/Podfile b/Podfile index 518c232..9432713 100644 --- a/Podfile +++ b/Podfile @@ -6,8 +6,8 @@ target 'OSPaymentsLib' do # Pods for OSPaymentsLib target 'OSPaymentsLibTests' do - pod 'Quick', '5.0.1' - pod 'Nimble', '10.0.0' + pod 'Quick', '~> 5.0.1' + pod 'Nimble', '~> 10.0.0' end end diff --git a/Podfile.lock b/Podfile.lock index eccd046..72d9901 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -3,8 +3,8 @@ PODS: - Quick (5.0.1) DEPENDENCIES: - - Nimble (= 10.0.0) - - Quick (= 5.0.1) + - Nimble (~> 10.0.0) + - Quick (~> 5.0.1) SPEC REPOS: trunk: @@ -15,6 +15,6 @@ SPEC CHECKSUMS: Nimble: 5316ef81a170ce87baf72dd961f22f89a602ff84 Quick: 749aa754fd1e7d984f2000fe051e18a3a9809179 -PODFILE CHECKSUM: 573766210a1468eb831a29c19f8af7f8f1800801 +PODFILE CHECKSUM: 1dd1a31673f4cf5f75ac55de69a3a3854ab3533b COCOAPODS: 1.11.3 diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index eccd046..72d9901 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -3,8 +3,8 @@ PODS: - Quick (5.0.1) DEPENDENCIES: - - Nimble (= 10.0.0) - - Quick (= 5.0.1) + - Nimble (~> 10.0.0) + - Quick (~> 5.0.1) SPEC REPOS: trunk: @@ -15,6 +15,6 @@ SPEC CHECKSUMS: Nimble: 5316ef81a170ce87baf72dd961f22f89a602ff84 Quick: 749aa754fd1e7d984f2000fe051e18a3a9809179 -PODFILE CHECKSUM: 573766210a1468eb831a29c19f8af7f8f1800801 +PODFILE CHECKSUM: 1dd1a31673f4cf5f75ac55de69a3a3854ab3533b COCOAPODS: 1.11.3 diff --git a/Pods/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchException/CwlCatchException.swift b/Pods/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchException/CwlCatchException.swift new file mode 100644 index 0000000..2cb9b29 --- /dev/null +++ b/Pods/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchException/CwlCatchException.swift @@ -0,0 +1,35 @@ +// +// CwlCatchException.swift +// CwlAssertionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +#if SWIFT_PACKAGE +import CwlCatchExceptionSupport +#endif + +private func catchReturnTypeConverter(_ type: T.Type, block: @escaping () -> Void) -> T? { + return catchExceptionOfKind(type, block) as? T +} + +extension NSException { + public static func catchException(in block: @escaping () -> Void) -> Self? { + return catchReturnTypeConverter(self, block: block) + } +} diff --git a/Pods/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchExceptionSupport/CwlCatchException.m b/Pods/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchExceptionSupport/CwlCatchException.m new file mode 100644 index 0000000..ff35465 --- /dev/null +++ b/Pods/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchExceptionSupport/CwlCatchException.m @@ -0,0 +1,34 @@ +// +// CwlCatchException.m +// CwlAssertionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#import "CwlCatchException.h" + +NSException* __nullable catchExceptionOfKind(Class __nonnull type, void (^ __nonnull inBlock)(void)) { + @try { + inBlock(); + } @catch (NSException *exception) { + if ([exception isKindOfClass:type]) { + return exception; + } else { + @throw; + } + } + return nil; +} diff --git a/Pods/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchExceptionSupport/include/CwlCatchException.h b/Pods/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchExceptionSupport/include/CwlCatchException.h new file mode 100644 index 0000000..eb42378 --- /dev/null +++ b/Pods/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchExceptionSupport/include/CwlCatchException.h @@ -0,0 +1,23 @@ +// +// CwlCatchException.h +// CwlCatchException +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#import + +NSException* __nullable catchExceptionOfKind(Class __nonnull type, void (^ __nonnull inBlock)(void)); diff --git a/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/CwlMachBadInstructionHandler.m b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/CwlMachBadInstructionHandler.m new file mode 100644 index 0000000..168fa5b --- /dev/null +++ b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/CwlMachBadInstructionHandler.m @@ -0,0 +1,56 @@ +// +// CwlMachBadExceptionHandler.m +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#ifdef __APPLE__ +#import "TargetConditionals.h" +#if TARGET_OS_OSX || TARGET_OS_IOS + +#import "mach_excServer.h" +#import "CwlMachBadInstructionHandler.h" + +@protocol BadInstructionReply ++(int)receiveReply:(bad_instruction_exception_reply_t)reply; +@end + +/// A basic function that receives callbacks from mach_exc_server and relays them to the Swift implemented BadInstructionException.catch_mach_exception_raise_state. +kern_return_t catch_mach_exception_raise_state(mach_port_t exception_port, exception_type_t exception, const mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, const thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { + bad_instruction_exception_reply_t reply = { exception_port, exception, code, codeCnt, flavor, old_state, old_stateCnt, new_state, new_stateCnt }; + Class badInstructionClass = NSClassFromString(@"BadInstructionException"); + return [badInstructionClass receiveReply:reply]; +} + +// The mach port should be configured so that this function is never used. +kern_return_t catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt) { + assert(false); + return KERN_FAILURE; +} + +// The mach port should be configured so that this function is never used. +kern_return_t catch_mach_exception_raise_state_identity(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { + assert(false); + return KERN_FAILURE; +} + +NDR_record_t mach_ndr_record(void) { + return NDR_record; +} + +#endif /* TARGET_OS_OSX || TARGET_OS_IOS */ +#endif /* __APPLE__ */ diff --git a/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/include/CwlMachBadInstructionHandler.h b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/include/CwlMachBadInstructionHandler.h new file mode 100644 index 0000000..6feabe5 --- /dev/null +++ b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/include/CwlMachBadInstructionHandler.h @@ -0,0 +1,80 @@ +// +// CwlMachBadInstructionHandler.h +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#import + +#if TARGET_OS_OSX || TARGET_OS_IOS + +#import + +extern bool _swift_disableExclusivityChecking; +extern bool _swift_reportFatalErrorsToDebugger; + +NS_ASSUME_NONNULL_BEGIN + +extern boolean_t mach_exc_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +// The request_mach_exception_raise_t struct is passed to mach_msg which assumes its exact layout. To avoid problems with different layouts, we keep the definition in C rather than Swift. +typedef struct +{ + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; +} request_mach_exception_raise_t; + +// The reply_mach_exception_raise_state_t struct is passed to mach_msg which assumes its exact layout. To avoid problems with different layouts, we keep the definition in C rather than Swift. +typedef struct +{ + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; +} reply_mach_exception_raise_state_t; + +typedef struct +{ + mach_port_t exception_port; + exception_type_t exception; + mach_exception_data_type_t const * _Nullable code; + mach_msg_type_number_t codeCnt; + int32_t * _Nullable flavor; + natural_t const * _Nullable old_state; + mach_msg_type_number_t old_stateCnt; + thread_state_t _Nullable new_state; + mach_msg_type_number_t * _Nullable new_stateCnt; +} bad_instruction_exception_reply_t; + +NDR_record_t mach_ndr_record(void); + +NS_ASSUME_NONNULL_END + +#endif diff --git a/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.c b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.c new file mode 100644 index 0000000..ccd8f84 --- /dev/null +++ b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.c @@ -0,0 +1,536 @@ +/* + * IDENTIFICATION: + * stub generated Sun Jan 29 19:05:29 2017 + * with a MiG generated by bootstrap_cmds-96.20.2 + * OPTIONS: + */ + +/* Module mach_exc */ + +#define __MIG_check__Request__mach_exc_subsystem__ 1 + +#import "mach_excServer.h" +#if TARGET_OS_OSX || TARGET_OS_IOS + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef __DeclareRcvRpc +#define __DeclareRcvRpc(_NUM_, _NAME_) +#endif /* __DeclareRcvRpc */ + +#ifndef __BeforeRcvRpc +#define __BeforeRcvRpc(_NUM_, _NAME_) +#endif /* __BeforeRcvRpc */ + +#ifndef __AfterRcvRpc +#define __AfterRcvRpc(_NUM_, _NAME_) +#endif /* __AfterRcvRpc */ + +#ifndef __DeclareRcvSimple +#define __DeclareRcvSimple(_NUM_, _NAME_) +#endif /* __DeclareRcvSimple */ + +#ifndef __BeforeRcvSimple +#define __BeforeRcvSimple(_NUM_, _NAME_) +#endif /* __BeforeRcvSimple */ + +#ifndef __AfterRcvSimple +#define __AfterRcvSimple(_NUM_, _NAME_) +#endif /* __AfterRcvSimple */ + +#define novalue void + +#define msgh_request_port msgh_local_port +#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) +#define msgh_reply_port msgh_remote_port +#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) + +#define MIG_RETURN_ERROR(X, code) {\ + ((mig_reply_error_t *)X)->RetCode = code;\ + ((mig_reply_error_t *)X)->NDR = NDR_record;\ + return;\ + } + +/* Forward Declarations */ + + +mig_internal novalue _Xmach_exception_raise + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state_identity + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_t__defined) +#define __MIG_check__Request__mach_exception_raise_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_t(__attribute__((__unused__)) __Request__mach_exception_raise_t *In0P) +{ + + typedef __Request__mach_exception_raise_t __Request; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 16)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 16)) / 8 < In0P->codeCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 16) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise */ +mig_internal novalue _Xmach_exception_raise + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_t __Request; + typedef __Reply__mach_exception_raise_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_t__defined */ + + __DeclareRcvRpc(2405, "mach_exception_raise") + __BeforeRcvRpc(2405, "mach_exception_raise") + +#if defined(__MIG_check__Request__mach_exception_raise_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_t((__Request *)In0P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_t__defined) */ + + OutP->RetCode = catch_mach_exception_raise(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt); + + OutP->NDR = NDR_record; + + + __AfterRcvRpc(2405, "mach_exception_raise") +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_t __Request; + __Request *In1P; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; +#endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ +#if __MigTypeCheck + if ( In1P->old_stateCnt > 224 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state */ +mig_internal novalue _Xmach_exception_raise_state + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_state_t __Request; + typedef __Reply__mach_exception_raise_state_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_state_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_state_t__defined */ + + __DeclareRcvRpc(2406, "mach_exception_raise_state") + __BeforeRcvRpc(2406, "mach_exception_raise_state") + +#if defined(__MIG_check__Request__mach_exception_raise_state_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_t((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ + + OutP->new_stateCnt = 224; + + OutP->RetCode = catch_mach_exception_raise_state(In0P->Head.msgh_request_port, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2406, "mach_exception_raise_state") +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_identity_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_identity_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_identity_t __Request; + __Request *In1P; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; +#endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ +#if __MigTypeCheck + if ( In1P->old_stateCnt > 224 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state_identity */ +mig_internal novalue _Xmach_exception_raise_state_identity + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_state_identity_t __Request; + typedef __Reply__mach_exception_raise_state_identity_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_state_identity_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_state_identity_t__defined */ + + __DeclareRcvRpc(2407, "mach_exception_raise_state_identity") + __BeforeRcvRpc(2407, "mach_exception_raise_state_identity") + +#if defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_identity_t((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ + + OutP->new_stateCnt = 224; + + OutP->RetCode = catch_mach_exception_raise_state_identity(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2407, "mach_exception_raise_state_identity") +} + + + +/* Description of this subsystem, for use in direct RPC */ +const struct catch_mach_exc_subsystem catch_mach_exc_subsystem = { + mach_exc_server_routine, + 2405, + 2408, + (mach_msg_size_t)sizeof(union __ReplyUnion__catch_mach_exc_subsystem), + (vm_address_t)0, + { + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state_identity, 11, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_identity_t)}, + } +}; + +mig_external boolean_t mach_exc_server + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + register mig_routine_t routine; + + OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); + OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; + /* Minimal size: routine() will update it if different */ + OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); + OutHeadP->msgh_local_port = MACH_PORT_NULL; + OutHeadP->msgh_id = InHeadP->msgh_id + 100; + OutHeadP->msgh_reserved = 0; + + if ((InHeadP->msgh_id > 2407) || (InHeadP->msgh_id < 2405) || + ((routine = catch_mach_exc_subsystem.routine[InHeadP->msgh_id - 2405].stub_routine) == 0)) { + ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; + ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; + return FALSE; + } + (*routine) (InHeadP, OutHeadP); + return TRUE; +} + +mig_external mig_routine_t mach_exc_server_routine + (mach_msg_header_t *InHeadP) +{ + register int msgh_id; + + msgh_id = InHeadP->msgh_id - 2405; + + if ((msgh_id > 2) || (msgh_id < 0)) + return 0; + + return catch_mach_exc_subsystem.routine[msgh_id].stub_routine; +} + +#endif /* TARGET_OS_OSX || TARGET_OS_IOS */ diff --git a/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.h b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.h new file mode 100644 index 0000000..1f03d66 --- /dev/null +++ b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.h @@ -0,0 +1,329 @@ +#ifdef __APPLE__ +#import "TargetConditionals.h" +#if TARGET_OS_OSX || TARGET_OS_IOS + +#ifndef _mach_exc_server_ +#define _mach_exc_server_ + +/* Module mach_exc */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN VOUCHER CODE */ + +#ifndef KERNEL +#if defined(__has_include) +#if __has_include() +#ifndef USING_VOUCHERS +#define USING_VOUCHERS +#endif +#ifndef __VOUCHER_FORWARD_TYPE_DECLS__ +#define __VOUCHER_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif // __VOUCHER_FORWARD_TYPE_DECLS__ +#endif // __has_include() +#endif // __has_include +#endif // !KERNEL + +/* END VOUCHER CODE */ + + +/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ + +#if defined(__has_include) +#if __has_include() +#ifndef USING_MIG_STRNCPY_ZEROFILL +#define USING_MIG_STRNCPY_ZEROFILL +#endif +#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ +#endif /* __has_include() */ +#endif /* __has_include */ + +/* END MIG_STRNCPY_ZEROFILL CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef mach_exc_MSG_COUNT +#define mach_exc_MSG_COUNT 3 +#endif /* mach_exc_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigServerHeader +__BeforeMigServerHeader +#endif /* __BeforeMigServerHeader */ + + +/* Routine mach_exception_raise */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt +); + +/* Routine mach_exception_raise_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state +( + mach_port_t exception_port, + exception_type_t exception, + const mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine mach_exception_raise_state_identity */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state_identity +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +boolean_t mach_exc_server( + mach_msg_header_t *InHeadP, + mach_msg_header_t *OutHeadP); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +mig_routine_t mach_exc_server_routine( + mach_msg_header_t *InHeadP); + + +/* Description of this subsystem, for use in direct RPC */ +extern const struct catch_mach_exc_subsystem { + mig_server_routine_t server; /* Server routine */ + mach_msg_id_t start; /* Min routine number */ + mach_msg_id_t end; /* Max routine number + 1 */ + unsigned int maxsize; /* Max msg size */ + vm_address_t reserved; /* Reserved */ + struct routine_descriptor /*Array of routine descriptors */ + routine[3]; +} catch_mach_exc_subsystem; + +/* typedefs for all requests */ + +#ifndef __Request__mach_exc_subsystem__defined +#define __Request__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + } __Request__mach_exception_raise_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_identity_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Request__mach_exc_subsystem__defined */ + + +/* union of all requests */ + +#ifndef __RequestUnion__catch_mach_exc_subsystem__defined +#define __RequestUnion__catch_mach_exc_subsystem__defined +union __RequestUnion__catch_mach_exc_subsystem { + __Request__mach_exception_raise_t Request_mach_exception_raise; + __Request__mach_exception_raise_state_t Request_mach_exception_raise_state; + __Request__mach_exception_raise_state_identity_t Request_mach_exception_raise_state_identity; +}; +#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_exc_subsystem__defined +#define __Reply__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_exception_raise_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_identity_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Reply__mach_exc_subsystem__defined */ + + +/* union of all replies */ + +#ifndef __ReplyUnion__catch_mach_exc_subsystem__defined +#define __ReplyUnion__catch_mach_exc_subsystem__defined +union __ReplyUnion__catch_mach_exc_subsystem { + __Reply__mach_exception_raise_t Reply_mach_exception_raise; + __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; + __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; +}; +#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_exc +#define subsystem_to_name_map_mach_exc \ + { "mach_exception_raise", 2405 },\ + { "mach_exception_raise_state", 2406 },\ + { "mach_exception_raise_state_identity", 2407 } +#endif + +#ifdef __AfterMigServerHeader +__AfterMigServerHeader +#endif /* __AfterMigServerHeader */ + +#endif /* _mach_exc_server_ */ + +#endif /* TARGET_OS_OSX || TARGET_OS_IOS */ +#endif /* __APPLE__ */ diff --git a/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlBadInstructionException.swift b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlBadInstructionException.swift new file mode 100644 index 0000000..9ec85da --- /dev/null +++ b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlBadInstructionException.swift @@ -0,0 +1,92 @@ +// +// CwlBadInstructionException.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#if (os(macOS) || os(iOS)) && (arch(x86_64) || arch(arm64)) + +import Foundation + +#if SWIFT_PACKAGE + import CwlMachBadInstructionHandler +#endif + +var raiseBadInstructionException = { + BadInstructionException().raise() +} as @convention(c) () -> Void + +/// A simple NSException subclass. It's not required to subclass NSException (since the exception type is represented in the name) but this helps for identifying the exception through runtime type. +@objc(BadInstructionException) +public class BadInstructionException: NSException { + static var name: String = "com.cocoawithlove.BadInstruction" + + init() { + super.init(name: NSExceptionName(rawValue: BadInstructionException.name), reason: nil, userInfo: nil) + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + /// An Objective-C callable function, invoked from the `mach_exc_server` callback function `catch_mach_exception_raise_state` to push the `raiseBadInstructionException` function onto the stack. + @objc(receiveReply:) + public class func receiveReply(_ reply: bad_instruction_exception_reply_t) -> CInt { + let old_state = UnsafeRawPointer(reply.old_state!).bindMemory(to: NativeThreadState.self, capacity: 1) + let old_stateCnt: mach_msg_type_number_t = reply.old_stateCnt + let new_state = UnsafeMutableRawPointer(reply.new_state!).bindMemory(to: NativeThreadState.self, capacity: 1) + let new_stateCnt: UnsafeMutablePointer = reply.new_stateCnt! + + // Make sure we've been given enough memory + guard + old_stateCnt == nativeThreadStateCount, + new_stateCnt.pointee >= nativeThreadStateCount + else { + return KERN_INVALID_ARGUMENT + } + + // 0. Copy over the state. + new_state.pointee = old_state.pointee + +#if arch(x86_64) + // 1. Decrement the stack pointer + new_state.pointee.__rsp -= UInt64(MemoryLayout.size) + + // 2. Save the old Instruction Pointer to the stack. + guard let pointer = UnsafeMutablePointer(bitPattern: UInt(new_state.pointee.__rsp)) else { + return KERN_INVALID_ARGUMENT + } + pointer.pointee = old_state.pointee.__rip + + // 3. Set the Instruction Pointer to the new function's address + new_state.pointee.__rip = unsafeBitCast(raiseBadInstructionException, to: UInt64.self) + +#elseif arch(arm64) + // 1. Set the link register to the current address. + new_state.pointee.__lr = old_state.pointee.__pc + + // 2. Set the Instruction Pointer to the new function's address. + new_state.pointee.__pc = unsafeBitCast(raiseBadInstructionException, to: UInt64.self) +#endif + + new_stateCnt.pointee = nativeThreadStateCount + + return KERN_SUCCESS + } +} + +#endif diff --git a/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlCatchBadInstruction.swift b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlCatchBadInstruction.swift new file mode 100644 index 0000000..7232c24 --- /dev/null +++ b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlCatchBadInstruction.swift @@ -0,0 +1,209 @@ +// +// CwlCatchBadInstruction.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#if (os(macOS) || os(iOS)) && (arch(x86_64) || arch(arm64)) + +import Foundation +import Swift + +#if SWIFT_PACKAGE + import CwlMachBadInstructionHandler +#endif + +private enum PthreadError: Error { case code(Int32) } +private enum MachExcServer: Error { case code(kern_return_t) } + +/// A quick function for converting Mach error results into Swift errors +private func kernCheck(_ f: () -> Int32) throws { + let r = f() + guard r == KERN_SUCCESS else { + throw NSError(domain: NSMachErrorDomain, code: Int(r), userInfo: nil) + } +} + +extension request_mach_exception_raise_t { + mutating func withMsgHeaderPointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: mach_msg_header_t.self, capacity: 1) { ptr -> R in + return block(ptr) + } + } + } +} + +extension reply_mach_exception_raise_state_t { + mutating func withMsgHeaderPointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: mach_msg_header_t.self, capacity: 1) { ptr -> R in + return block(ptr) + } + } + } +} + +/// A structure used to store context associated with the Mach message port +private struct MachContext { + var masks = execTypesCountTuple() + var count: mach_msg_type_number_t = 0 + var ports = execTypesCountTuple() + var behaviors = execTypesCountTuple() + var flavors = execTypesCountTuple() + var currentExceptionPort: mach_port_t = 0 + var handlerThread: pthread_t? = nil + + static func internalMutablePointers(_ m: UnsafeMutablePointer>, _ c: UnsafeMutablePointer, _ p: UnsafeMutablePointer>, _ b: UnsafeMutablePointer>, _ f: UnsafeMutablePointer>, _ block: (UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer) -> R) -> R { + return m.withMemoryRebound(to: exception_mask_t.self, capacity: 1) { masksPtr in + return c.withMemoryRebound(to: mach_msg_type_number_t.self, capacity: 1) { countPtr in + return p.withMemoryRebound(to: mach_port_t.self, capacity: 1) { portsPtr in + return b.withMemoryRebound(to: exception_behavior_t.self, capacity: 1) { behaviorsPtr in + return f.withMemoryRebound(to: thread_state_flavor_t.self, capacity: 1) { flavorsPtr in + return block(masksPtr, countPtr, portsPtr, behaviorsPtr, flavorsPtr) + } + } + } + } + } + } + + mutating func withUnsafeMutablePointers(in block: @escaping (UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer) -> R) -> R { + return MachContext.internalMutablePointers(&masks, &count, &ports, &behaviors, &flavors, block) + } +} + +/// A function for receiving mach messages and parsing the first with mach_exc_server (and if any others are received, throwing them away). +private func machMessageHandler(_ arg: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { + let context = arg.assumingMemoryBound(to: MachContext.self).pointee + var request = request_mach_exception_raise_t() + var reply = reply_mach_exception_raise_state_t() + + var handledfirstException = false + repeat { do { + // Request the next mach message from the port + request.Head.msgh_local_port = context.currentExceptionPort + request.Head.msgh_size = UInt32(MemoryLayout.size) + let requestSize = request.Head.msgh_size + try kernCheck { request.withMsgHeaderPointer { requestPtr in + mach_msg(requestPtr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0, requestSize, context.currentExceptionPort, 0, UInt32(MACH_PORT_NULL)) + } } + + // Prepare the reply structure + reply.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(request.Head.msgh_bits), 0) + reply.Head.msgh_local_port = UInt32(MACH_PORT_NULL) + reply.Head.msgh_remote_port = request.Head.msgh_remote_port + reply.Head.msgh_size = UInt32(MemoryLayout.size) + reply.NDR = mach_ndr_record() + + if !handledfirstException { + // Use the MiG generated server to invoke our handler for the request and fill in the rest of the reply structure + guard request.withMsgHeaderPointer(in: { requestPtr in reply.withMsgHeaderPointer { replyPtr in + mach_exc_server(requestPtr, replyPtr) + } }) != 0 else { throw MachExcServer.code(reply.RetCode) } + + handledfirstException = true + } else { + // If multiple fatal errors occur, don't handle subsquent errors (let the program crash) + reply.RetCode = KERN_FAILURE + } + + // Send the reply + let replySize = reply.Head.msgh_size + try kernCheck { reply.withMsgHeaderPointer { replyPtr in + mach_msg(replyPtr, MACH_SEND_MSG, replySize, 0, UInt32(MACH_PORT_NULL), 0, UInt32(MACH_PORT_NULL)) + } } + } catch let error as NSError where (error.domain == NSMachErrorDomain && (error.code == Int(MACH_RCV_PORT_CHANGED) || error.code == Int(MACH_RCV_INVALID_NAME))) { + // Port was already closed before we started or closed while we were listening. + // This means the controlling thread shut down. + return nil + } catch { + // Should never be reached but this is testing code, don't try to recover, just abort + fatalError("Mach message error: \(error)") + } } while true +} + +/// Run the provided block. If a mach "BAD_INSTRUCTION" exception is raised, catch it and return a BadInstructionException (which captures stack information about the throw site, if desired). Otherwise return nil. +/// NOTE: This function is only intended for use in test harnesses – use in a distributed build is almost certainly a bad choice. If a "BAD_INSTRUCTION" exception is raised, the block will be exited before completion via Objective-C exception. The risks associated with an Objective-C exception apply here: most Swift/Objective-C functions are *not* exception-safe. Memory may be leaked and the program will not necessarily be left in a safe state. +/// - parameter block: a function without parameters that will be run +/// - returns: if an EXC_BAD_INSTRUCTION is raised during the execution of `block` then a BadInstructionException will be returned, otherwise `nil`. +public func catchBadInstruction(in block: @escaping () -> Void) -> BadInstructionException? { + // Suppress Swift runtime's direct triggering of the debugger and exclusivity checking which crashes when we throw past it + let previousExclusivity = _swift_disableExclusivityChecking + let previousReporting = _swift_reportFatalErrorsToDebugger + _swift_disableExclusivityChecking = true + _swift_reportFatalErrorsToDebugger = false + defer { + _swift_reportFatalErrorsToDebugger = previousReporting + _swift_disableExclusivityChecking = previousExclusivity + } + + var context = MachContext() + var result: BadInstructionException? = nil + do { + var handlerThread: pthread_t? = nil + defer { + // 8. Wait for the thread to terminate *if* we actually made it to the creation point + // The mach port should be destroyed *before* calling pthread_join to avoid a deadlock. + if handlerThread != nil { + pthread_join(handlerThread!, nil) + } + } + + try kernCheck { + // 1. Create the mach port + mach_port_allocate(mach_task_self_, MACH_PORT_RIGHT_RECEIVE, &context.currentExceptionPort) + } + defer { + // 7. Cleanup the mach port + mach_port_destroy(mach_task_self_, context.currentExceptionPort) + } + + try kernCheck { + // 2. Configure the mach port + mach_port_insert_right(mach_task_self_, context.currentExceptionPort, context.currentExceptionPort, MACH_MSG_TYPE_MAKE_SEND) + } + + let currentExceptionPtr = context.currentExceptionPort + try kernCheck { context.withUnsafeMutablePointers { masksPtr, countPtr, portsPtr, behaviorsPtr, flavorsPtr in + // 3. Apply the mach port as the handler for this thread + thread_swap_exception_ports(mach_thread_self(), nativeMachExceptionMask, currentExceptionPtr, Int32(bitPattern: UInt32(EXCEPTION_STATE) | MACH_EXCEPTION_CODES), nativeThreadState, masksPtr, countPtr, portsPtr, behaviorsPtr, flavorsPtr) + } } + + defer { context.withUnsafeMutablePointers { masksPtr, countPtr, portsPtr, behaviorsPtr, flavorsPtr in + // 6. Unapply the mach port + _ = thread_swap_exception_ports(mach_thread_self(), nativeMachExceptionMask, 0, EXCEPTION_DEFAULT, THREAD_STATE_NONE, masksPtr, countPtr, portsPtr, behaviorsPtr, flavorsPtr) + } } + + try withUnsafeMutablePointer(to: &context) { c throws in + // 4. Create the thread + let e = pthread_create(&handlerThread, nil, machMessageHandler, c) + guard e == 0 else { throw PthreadError.code(e) } + + // 5. Run the block + result = BadInstructionException.catchException(in: block) + } + } catch { + // Should never be reached but this is testing code, don't try to recover, just abort + fatalError("Mach port error: \(error)") + } + + return result +} + +#endif + diff --git a/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlDarwinDefinitions.swift b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlDarwinDefinitions.swift new file mode 100644 index 0000000..ccce5c5 --- /dev/null +++ b/Pods/Nimble/Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlDarwinDefinitions.swift @@ -0,0 +1,64 @@ +// +// CwlDarwinDefinitions.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( https://www.cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#if (os(macOS) || os(iOS)) && (arch(x86_64) || arch(arm64)) + +import Darwin + +// From /usr/include/mach/message.h +// #define MACH_MSG_TYPE_MAKE_SEND 20 /* Must hold receive right */ +// #define MACH_MSGH_BITS_REMOTE(bits) \ +// ((bits) & MACH_MSGH_BITS_REMOTE_MASK) +// #define MACH_MSGH_BITS(remote, local) /* legacy */ \ +// ((remote) | ((local) << 8)) +public let MACH_MSG_TYPE_MAKE_SEND: UInt32 = 20 +public func MACH_MSGH_BITS_REMOTE(_ bits: UInt32) -> UInt32 { return bits & UInt32(MACH_MSGH_BITS_REMOTE_MASK) } +public func MACH_MSGH_BITS(_ remote: UInt32, _ local: UInt32) -> UInt32 { return ((remote) | ((local) << 8)) } + +// From /usr/include/mach/exception_types.h +// #define EXC_BAD_INSTRUCTION 2 /* Instruction failed */ +// #define EXC_MASK_BAD_INSTRUCTION (1 << EXC_BAD_INSTRUCTION) +//public let EXC_MASK_BAD_INSTRUCTION: UInt32 = 1 << EXC_BAD_INSTRUCTION + +#if arch(x86_64) +// From /usr/include/mach/i386/thread_status.h +// #define x86_threadStateCount ((mach_msg_type_number_t) \ +// ( sizeof (x86_NativeThreadState) / sizeof (int) )) +public let nativeThreadState = x86_THREAD_STATE64 +public let nativeThreadStateCount = UInt32(MemoryLayout.size / MemoryLayout.size) +typealias NativeThreadState = x86_thread_state64_t +public let nativeMachExceptionMask = exception_mask_t(EXC_MASK_BAD_INSTRUCTION) +#elseif arch(arm64) +public let nativeThreadState = ARM_THREAD_STATE64 +public let nativeThreadStateCount = UInt32(MemoryLayout.size / MemoryLayout.size) +typealias NativeThreadState = arm_thread_state64_t +public let nativeMachExceptionMask = exception_mask_t(EXC_MASK_BREAKPOINT) +#endif + +public let EXC_TYPES_COUNT = 14 +public struct execTypesCountTuple { + // From /usr/include/mach/i386/exception.h + // #define EXC_TYPES_COUNT 14 /* incl. illegal exception 0 */ + public var value: (T, T, T, T, T, T, T, T, T, T, T, T, T, T) = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + public init() { + } +} + +#endif diff --git a/Pods/Nimble/README.md b/Pods/Nimble/README.md index 8137a10..e92cbb2 100644 --- a/Pods/Nimble/README.md +++ b/Pods/Nimble/README.md @@ -32,23 +32,9 @@ expect(ocean.isClean).toEventually(beTruthy()) - [Operator Overloads](#operator-overloads) - [Lazily Computed Values](#lazily-computed-values) - [C Primitives](#c-primitives) - - [Async/Await Support](#asyncawait-support) - - [Async Matchers](#async-matchers) - - [Polling Expectations](#polling-expectations) - - [Using Polling Expectations in Async Tests](#using-polling-expectations-in-async-tests) - - [Verifying a Matcher will Never or Always Match](#verifying-a-matcher-will-never-or-always-match) - - [Waiting for a Callback to be Called](#waiting-for-a-callback-to-be-called) - - [Changing the Timeout and Polling Intervals](#changing-the-timeout-and-polling-intervals) - - [Changing default Timeout and Poll Intervals](#changing-default-timeout-and-poll-intervals) - - [Quick](#quick) - - [XCTest](#xctest) + - [Asynchronous Expectations](#asynchronous-expectations) - [Objective-C Support](#objective-c-support) - [Disabling Objective-C Shorthand](#disabling-objective-c-shorthand) -- [Using `require` to demand that a matcher pass before continuing](#using-require-to-demand-that-a-matcher-pass-before-continuing) - - [Polling with `require`.](#polling-with-require) - - [Using `require` with Async expressions and Async matchers](#using-require-with-async-expressions-and-async-matchers) - - [Using `unwrap` to replace `require(...).toNot(beNil())`](#using-unwrap-to-replace-requiretonotbenil) - - [Throwing a Custom Error from Require](#throwing-a-custom-error-from-require) - [Built-in Matcher Functions](#built-in-matcher-functions) - [Type Checking](#type-checking) - [Equivalence](#equivalence) @@ -62,32 +48,25 @@ expect(ocean.isClean).toEventually(beTruthy()) - [Collection Membership](#collection-membership) - [Strings](#strings) - [Collection Elements](#collection-elements) - - [Swift](#swift) - - [Objective-C](#objective-c) - [Collection Count](#collection-count) - [Notifications](#notifications) - [Result](#result) - [Matching a value to any of a group of matchers](#matching-a-value-to-any-of-a-group-of-matchers) - [Custom Validation](#custom-validation) - - [Mapping a Value to Another Value](#mapping-a-value-to-another-value) - [Writing Your Own Matchers](#writing-your-own-matchers) - - [MatcherResult](#matcherresult) + - [PredicateResult](#predicateresult) - [Lazy Evaluation](#lazy-evaluation) - [Type Checking via Swift Generics](#type-checking-via-swift-generics) - [Customizing Failure Messages](#customizing-failure-messages) - [Basic Customization](#basic-customization) - [Full Customization](#full-customization) - - [Asynchronous Matchers](#asynchronous-matchers) - [Supporting Objective-C](#supporting-objective-c) - [Properly Handling `nil` in Objective-C Matchers](#properly-handling-nil-in-objective-c-matchers) + - [Migrating from the Old Matcher API](#migrating-from-the-old-matcher-api) - [Installing Nimble](#installing-nimble) - [Installing Nimble as a Submodule](#installing-nimble-as-a-submodule) - [Installing Nimble via CocoaPods](#installing-nimble-via-cocoapods) - - [Installing Nimble via Swift Package Manager](#installing-nimble-via-swift-package-manager) - - [Xcode](#xcode) - - [Package.Swift](#packageswift) - [Using Nimble without XCTest](#using-nimble-without-xctest) - - [Privacy Statement](#privacy-statement) @@ -318,66 +297,7 @@ expect(1 as CInt).to(equal(1)) expect(@(1 + 1)).to(equal(@2)); ``` -## Async/Await Support - -Nimble makes it easy to await for an async function to complete. Simply pass -the async function in to `expect`: - -```swift -// Swift -await expect { await aFunctionReturning1() }.to(equal(1)) -``` - -The async function is awaited on first, before passing it to the matcher. This -enables the matcher to run synchronous code like before, without caring about -whether the value it's processing was abtained async or not. - -Async support is Swift-only, and it requires that you execute the test in an -async context. For XCTest, this is as simple as marking your test function with -`async`. If you use Quick, all tests in Quick 6 are executed in an async context. -In Quick 7 and later, only tests that are in an `AsyncSpec` subclass will be -executed in an async context. - -To avoid a compiler errors when using synchronous `expect` in asynchronous contexts, -`expect` with async expressions does not support autoclosures. However, the `expecta` -(expect async) function is provided as an alternative, which does support autoclosures. - -```swift -// Swift -await expecta(await aFunctionReturning1()).to(equal(1))) -``` - -Similarly, if you're ever in a situation where you want to force the compiler to -produce a `SyncExpectation`, you can use the `expects` (expect sync) function to -produce a `SyncExpectation`. Like so: - -```swift -// Swift -expects(someNonAsyncFunction()).to(equal(1))) - -expects(await someAsyncFunction()).to(equal(1)) // Compiler error: 'async' call in an autoclosure that does not support concurrency -``` - -### Async Matchers - -In addition to asserting on async functions prior to passing them to a -synchronous matcher, you can also write matchers that directly take in an -async value. These are called `AsyncMatcher`s. This is most obviously useful -when directly asserting against an actor. In addition to writing your own -async matchers, Nimble currently ships with async versions of the following -matchers: - -- `allPass` -- `containElementSatisfying` -- `satisfyAllOf` and the `&&` operator overload accept both `AsyncMatcher` and - synchronous `Matcher`s. -- `satisfyAnyOf` and the `||` operator overload accept both `AsyncMatcher` and - synchronous `Matcher`s. - -Note: Async/Await support is different than the `toEventually`/`toEventuallyNot` -feature described below. - -## Polling Expectations +## Asynchronous Expectations In Nimble, it's easy to make expectations on values that are updated asynchronously. Just use `toEventually` or `toEventuallyNot`: @@ -413,39 +333,6 @@ contains dolphins and whales, the expectation passes. If `ocean` still doesn't contain them, even after being continuously re-evaluated for one whole second, the expectation fails. -### Using Polling Expectations in Async Tests - -You can easily use `toEventually` or `toEventuallyNot` in async contexts as -well. You only need to add an `await` statement to the beginning of the line: - -```swift -// Swift -DispatchQueue.main.async { - ocean.add("dolphins") - ocean.add("whales") -} -await expect(ocean).toEventually(contain("dolphens", "whiles")) -``` - -Starting in Nimble 12, `toEventually` et. al. now also supports async -expectations. For example, the following test is now supported: - -```swift -actor MyActor { - private var counter = 0 - - func access() -> Int { - counter += 1 - return counter - } -} - -let subject = MyActor() -await expect { await subject.access() }.toEventually(equal(2)) -``` - -### Verifying a Matcher will Never or Always Match - You can also test that a value always or never matches throughout the length of the timeout. Use `toNever` and `toAlways` for this: ```swift @@ -462,7 +349,25 @@ expect(ocean).toAlways(contain(@"dolphins")) expect(ocean).toNever(contain(@"hares")) ``` -### Waiting for a Callback to be Called +Sometimes it takes more than a second for a value to update. In those +cases, use the `timeout` parameter: + +```swift +// Swift + +// Waits three seconds for ocean to contain "starfish": +expect(ocean).toEventually(contain("starfish"), timeout: .seconds(3)) + +// Evaluate someValue every 0.2 seconds repeatedly until it equals 100, or fails if it timeouts after 5.5 seconds. +expect(someValue).toEventually(equal(100), timeout: .milliseconds(5500), pollInterval: .milliseconds(200)) +``` + +```objc +// Objective-C + +// Waits three seconds for ocean to contain "starfish": +expect(ocean).withTimeout(3).toEventually(contain(@"starfish")); +``` You can also provide a callback by using the `waitUntil` function: @@ -518,30 +423,6 @@ pollution for whatever incomplete code that was running on the main thread. Blocking the main thread can be caused by blocking IO, calls to sleep(), deadlocks, and synchronous IPC. -### Changing the Timeout and Polling Intervals - -Sometimes it takes more than a second for a value to update. In those -cases, use the `timeout` parameter: - -```swift -// Swift - -// Waits three seconds for ocean to contain "starfish": -expect(ocean).toEventually(contain("starfish"), timeout: .seconds(3)) - -// Evaluate someValue every 0.2 seconds repeatedly until it equals 100, or fails if it timeouts after 5.5 seconds. -expect(someValue).toEventually(equal(100), timeout: .milliseconds(5500), pollInterval: .milliseconds(200)) -``` - -```objc -// Objective-C - -// Waits three seconds for ocean to contain "starfish": -expect(ocean).withTimeout(3).toEventually(contain(@"starfish")); -``` - -### Changing default Timeout and Poll Intervals - In some cases (e.g. when running on slower machines) it can be useful to modify the default timeout and poll interval values. This can be done as follows: @@ -549,73 +430,12 @@ the default timeout and poll interval values. This can be done as follows: // Swift // Increase the global timeout to 5 seconds: -Nimble.PollingDefaults.timeout = .seconds(5) +Nimble.AsyncDefaults.timeout = .seconds(5) // Slow the polling interval to 0.1 seconds: -Nimble.PollingDefaults.pollInterval = .milliseconds(100) -``` - -You can set these globally at test startup in two ways: - -#### Quick - -If you use [Quick](https://github.com/Quick/Quick), add a [`QuickConfiguration` subclass](https://github.com/Quick/Quick/blob/main/Documentation/en-us/ConfiguringQuick.md) which sets your desired `PollingDefaults`. - -```swift -import Quick -import Nimble - -class PollingConfiguration: QuickConfiguration { - override class func configure(_ configuration: QCKConfiguration) { - Nimble.PollingDefaults.timeout = .seconds(5) - Nimble.PollingDefaults.pollInterval = .milliseconds(100) - } -} -``` - -#### XCTest - -If you use [XCTest](https://developer.apple.com/documentation/xctest), add an object that conforms to [`XCTestObservation`](https://developer.apple.com/documentation/xctest/xctestobservation) and implement [`testBundleWillStart(_:)`](https://developer.apple.com/documentation/xctest/xctestobservation/1500772-testbundlewillstart). - -Additionally, you will need to register this observer with the [`XCTestObservationCenter`](https://developer.apple.com/documentation/xctest/xctestobservationcenter) at test startup. To do this, set the `NSPrincipalClass` key in your test bundle's Info.plist and implement a class with that same name. - -For example - -```xml - - - - - - - NSPrincipalClass - MyTests.TestSetup - - -``` - -```swift -// TestSetup.swift -import XCTest -import Nimble - -@objc -class TestSetup: NSObject { - override init() { - XCTestObservationCenter.shared.register(PollingConfigurationTestObserver()) - } -} - -class PollingConfigurationTestObserver: NSObject, XCTestObserver { - func testBundleWillStart(_ testBundle: Bundle) { - Nimble.PollingDefaults.timeout = .seconds(5) - Nimble.PollingDefaults.pollInterval = .milliseconds(100) - } -} +Nimble.AsyncDefaults.pollInterval = .milliseconds(100) ``` -In Linux, you can implement `LinuxMain` to set the PollingDefaults before calling `XCTMain`. - ## Objective-C Support Nimble has full support for Objective-C. However, there are two things @@ -675,7 +495,6 @@ For the following matchers: - `beFalsy` - `haveCount` - If you would like to see more, [file an issue](https://github.com/Quick/Nimble/issues). ## Disabling Objective-C Shorthand @@ -697,89 +516,6 @@ NMB_expect(^{ return seagull.squawk; }, __FILE__, __LINE__).to(NMB_equal(@"Squee names that conflict with Nimble functions, such as `expect` or `equal`. If that's not the case, there's no point in disabling the shorthand. - -# Using `require` to demand that a matcher pass before continuing - -Nimble 13.1 added the `require` dsl to complement `expect`. `require` -looks similar to `expect` and works with matchers just like `expect` does. The -difference is that `require` requires that the matcher passes - if the matcher -doesn't pass, then `require` will throw an error. Additionally, if `require` -does pass, then it'll return the result of running the expression. - -For example, in testing a function that returns an array, you might need to -first guarantee that there are exactly 3 items in the array before continuing -to assert on it. Instead of writing code that needlessly duplicates an assertion -and a conditional like so: - -```swift -let collection = myFunction() -expect(collection).to(haveCount(3)) -guard collection.count == 3 else { return } -// ... -``` - -You can replace that with: - -```swift -let collection = try require(myFunction()).to(haveCount(3)) -// ... -``` - -## Polling with `require`. - -Because `require` does everything you can do with `expect`, you can also use -`require` to [poll matchers](#polling-expectations) using `toEventually`, -`eventuallyTo`, `toEventuallyNot`, `toNotEventually`, `toNever`, `neverTo`, -`toAlways`, and `alwaysTo`. These work exactly the same as they do when using -`expect`, except that they throw if they fail, and they return the value of the -expression when they pass. - -## Using `require` with Async expressions and Async matchers - -`require` also works with both async expressions -(`require { await someExpression() }.to(...)`), and async matchers -(`require().to(someAsyncMatcher())`). - -Note that to prevent compiler confusion, -you cannot use `require` with async autoclosures. That is, -`require(await someExpression())` will not compile. You can instead either -make the closure explicit (`require { await someExpression() }`), or use the -`requirea` function, which does accept autoclosures. -Similarly, if you ever wish to use the sync version of `require` when the -compiler is trying to force you to use the async version, you can use the -`requires` function, which only allows synchronous expressions. - -## Using `unwrap` to replace `require(...).toNot(beNil())` - -It's very common to require that a value not be nil. Instead of writing -`try require(...).toNot(beNil())`, Nimble provides the `unwrap` function. This -expression throws an error if the expression evaluates to nil, or returns the -non-nil result when it passes. For example: - -```swift -let value = try unwrap(nil as Int?) // throws -let value = try unwrap(1 as Int?) // returns 1 -``` - -Additionally, there is also the `pollUnwrap` function, which aliases to -`require(...).toEventuallyNot(beNil())`. This is extremely useful for verifying -that a value that is updated on a background thread was eventually set to a -non-nil value. - -Note: As with `require`, there are `unwraps`, `unwrapa`, `pollUnwraps`, and -`pollUnwrapa` variants for allowing you to use autoclosures specifically with -synchronous or asynchronous code. - -## Throwing a Custom Error from Require - -By default, if the matcher fails in a `require`, then a `RequireError` will be -thrown. You can override this behavior and throw a custom error by passing a -non-nil `Error` value to the `customError` parameter: - -```swift -try require(1).to(equal(2)) // throws a `RequireError` -try require(customError: MyCustomError(), 1).to(equal(2)) // throws a `MyCustomError` -``` # Built-in Matcher Functions @@ -1312,9 +1048,6 @@ expect(turtles).to(containElementSatisfying({ turtle in // should it fail ``` -Note: in Swift, `containElementSatisfying` also has a variant that takes in an -async function. - ```objc // Objective-C @@ -1409,19 +1142,6 @@ expect([1, 2, 3, 4]).to(allPass { $0 < 5 }) expect([1, 2, 3, 4]).to(allPass(beLessThan(5))) ``` -There are also variants of `allPass` that check against async matchers, and -that take in async functions: - -```swift -// Swift - -// Providing a custom function: -expect([1, 2, 3, 4]).to(allPass { await asyncFunctionReturningBool($0) }) - -// Composing the expectation with another matcher: -expect([1, 2, 3, 4]).to(allPass(someAsyncMatcher())) -``` - ### Objective-C In Objective-C, the collection must be an instance of a type which implements @@ -1549,9 +1269,6 @@ expect(6).to(satisfyAnyOf(equal(2), equal(3), equal(4), equal(5), equal(6), equa expect(82).to(beLessThan(50) || beGreaterThan(80)) ``` -Note: In swift, you can mix and match synchronous and asynchronous matchers -using by `satisfyAnyOf`/`||`. - ```objc // Objective-C @@ -1596,60 +1313,28 @@ The `String` provided with `.failed()` is shown when the test fails. When using `toEventually()` be careful not to make state changes or run process intensive code since this closure will be ran many times. -## Mapping a Value to Another Value - -Sometimes, you only want to match against a property or group of properties. -For example, if you wanted to check that only one or a few properties of a value -are equal to something else. For this, use the `map` matcher to convert a value -to another value and check it with a matcher. - -```swift -// Swift - -expect(someValue).to(map(\.someProperty, equal(expectedProperty))) - -// or, for checking multiple different properties: - -expect(someValue).to(satisfyAllOf( - map(\.firstProperty, equal(expectedFirstProperty)), - map({ $0.secondProperty }, equal(expectedSecondProperty)) -)) -``` - -The `map` matcher takes in either a closure or a keypath literal, and a matcher -to compose with. It also works with async closures and async matchers. - -In most cases, it is simpler and easier to not use map (that is, prefer -`expect(someValue.property).to(equal(1))` to -`expect(someValue).to(map(\.property, equal(1)))`). But `map` is incredibly -useful when combined with `satisfyAllOf`/`satisfyAnyOf`, especially for checking -a value that cannot conform to `Equatable` (or you don't want to make it -conform to `Equatable`). However, if you find yourself reusing `map` many times -to do a fuzzy-equals of a given type, you will find writing a custom matcher to -be much easier to use and maintain. - # Writing Your Own Matchers In Nimble, matchers are Swift functions that take an expected -value and return a `Matcher` closure. Take `equal`, for example: +value and return a `Predicate` closure. Take `equal`, for example: ```swift // Swift -public func equal(expectedValue: T?) -> Matcher { +public func equal(expectedValue: T?) -> Predicate { // Can be shortened to: - // Matcher { actual in ... } + // Predicate { actual in ... } // // But shown with types here for clarity. - return Matcher { (actualExpression: Expression) throws -> MatcherResult in + return Predicate { (actualExpression: Expression) throws -> PredicateResult in let msg = ExpectationMessage.expectedActualValueTo("equal <\(expectedValue)>") if let actualValue = try actualExpression.evaluate() { - return MatcherResult( + return PredicateResult( bool: actualValue == expectedValue!, message: msg ) } else { - return MatcherResult( + return PredicateResult( status: .fail, message: msg.appendedBeNilHint() ) @@ -1658,7 +1343,7 @@ public func equal(expectedValue: T?) -> Matcher { } ``` -The return value of a `Matcher` closure is a `MatcherResult` that indicates +The return value of a `Predicate` closure is a `PredicateResult` that indicates whether the actual value matches the expectation and what error message to display on failure. @@ -1678,27 +1363,27 @@ For examples of how to write your own matchers, just check out the to see how Nimble's built-in set of matchers are implemented. You can also check out the tips below. -## MatcherResult +## PredicateResult -`MatcherResult` is the return struct that `Matcher` return to indicate -success and failure. A `MatcherResult` is made up of two values: -`MatcherStatus` and `ExpectationMessage`. +`PredicateResult` is the return struct that `Predicate` return to indicate +success and failure. A `PredicateResult` is made up of two values: +`PredicateStatus` and `ExpectationMessage`. -Instead of a boolean, `MatcherStatus` captures a trinary set of values: +Instead of a boolean, `PredicateStatus` captures a trinary set of values: ```swift // Swift -public enum MatcherStatus { -// The matcher "passes" with the given expression +public enum PredicateStatus { +// The predicate "passes" with the given expression // eg - expect(1).to(equal(1)) case matches -// The matcher "fails" with the given expression +// The predicate "fails" with the given expression // eg - expect(1).toNot(equal(1)) case doesNotMatch -// The matcher never "passes" with the given expression, even if negated +// The predicate never "passes" with the given expression, even if negated // eg - expect(nil as Int?).toNot(equal(1)) case fail @@ -1724,11 +1409,11 @@ case fail(/* message: */ String) } ``` -Matchers should usually depend on either `.expectedActualValueTo(..)` or +Predicates should usually depend on either `.expectedActualValueTo(..)` or `.fail(..)` when reporting errors. Special cases can be used for the other enum cases. -Finally, if your Matcher utilizes other Matchers, you can utilize +Finally, if your Predicate utilizes other Predicates, you can utilize `.appended(details:)` and `.appended(message:)` methods to annotate an existing error with more details. @@ -1745,15 +1430,15 @@ custom matchers should call `actualExpression.evaluate()`: ```swift // Swift -public func beNil() -> Matcher { - // Matcher.simpleNilable(..) automatically generates ExpectationMessage for +public func beNil() -> Predicate { + // Predicate.simpleNilable(..) automatically generates ExpectationMessage for // us based on the string we provide to it. Also, the 'Nilable' postfix indicates - // that this Matcher supports matching against nil actualExpressions, instead of - // always resulting in a MatcherStatus.fail result -- which is true for - // Matcher.simple(..) - return Matcher.simpleNilable("be nil") { actualExpression in + // that this Predicate supports matching against nil actualExpressions, instead of + // always resulting in a PredicateStatus.fail result -- which is true for + // Predicate.simple(..) + return Predicate.simpleNilable("be nil") { actualExpression in let actualValue = try actualExpression.evaluate() - return MatcherStatus(bool: actualValue == nil) + return PredicateStatus(bool: actualValue == nil) } } ``` @@ -1775,16 +1460,16 @@ against the one provided to the matcher function, and passes if they are the sam ```swift // Swift -public func haveDescription(description: String) -> Matcher { - return Matcher.simple("have description") { actual in - return MatcherStatus(bool: actual.evaluate().description == description) +public func haveDescription(description: String) -> Predicate { + return Predicate.simple("have description") { actual in + return PredicateStatus(bool: actual.evaluate().description == description) } } ``` ## Customizing Failure Messages -When using `Matcher.simple(..)` or `Matcher.simpleNilable(..)`, Nimble +When using `Predicate.simple(..)` or `Predicate.simpleNilable(..)`, Nimble outputs the following failure message when an expectation fails: ```swift @@ -1793,36 +1478,36 @@ outputs the following failure message when an expectation fails: "expected to \(message), got <\(actual)>" ``` -You can customize this message by modifying the way you create a `Matcher`. +You can customize this message by modifying the way you create a `Predicate`. ### Basic Customization For slightly more complex error messaging, receive the created failure message -with `Matcher.define(..)`: +with `Predicate.define(..)`: ```swift // Swift -public func equal(_ expectedValue: T?) -> Matcher { - return Matcher.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in +public func equal(_ expectedValue: T?) -> Predicate { + return Predicate.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in let actualValue = try actualExpression.evaluate() let matches = actualValue == expectedValue && expectedValue != nil if expectedValue == nil || actualValue == nil { if expectedValue == nil && actualValue != nil { - return MatcherResult( + return PredicateResult( status: .fail, message: msg.appendedBeNilHint() ) } - return MatcherResult(status: .fail, message: msg) + return PredicateResult(status: .fail, message: msg) } - return MatcherResult(bool: matches, message: msg) + return PredicateResult(bool: matches, message: msg) } } ``` In the example above, `msg` is defined based on the string given to -`Matcher.define`. The code looks akin to: +`Predicate.define`. The code looks akin to: ```swift // Swift @@ -1832,10 +1517,10 @@ let msg = ExpectationMessage.expectedActualValueTo("equal <\(stringify(expectedV ### Full Customization -To fully customize the behavior of the Matcher, use the overload that expects -a `MatcherResult` to be returned. +To fully customize the behavior of the Predicate, use the overload that expects +a `PredicateResult` to be returned. -Along with `MatcherResult`, there are other `ExpectationMessage` enum values you can use: +Along with `PredicateResult`, there are other `ExpectationMessage` enum values you can use: ```swift public indirect enum ExpectationMessage { @@ -1879,52 +1564,19 @@ For a more comprehensive message that spans multiple lines, use .expectedActualValueTo("be true").appended(details: "use beFalse() for inverse\nor use beNil()") ``` -## Asynchronous Matchers - -To write matchers against async expressions, return an instance of -`AsyncMatcher`. The closure passed to `AsyncMatcher` is async, and the -expression you evaluate is also asynchronous and needs to be awaited on. - -```swift -// Swift - -actor CallRecorder { - private(set) var calls: [Arguments] = [] - - func record(call: Arguments) { - calls.append(call) - } -} - -func beCalled(with arguments: Argument) -> AsyncMatcher> { - AsyncMatcher { (expression: AsyncExpression>) in - let message = ExpectationMessage.expectedActualValueTo("be called with \(arguments)") - guard let calls = try await expression.evaluate()?.calls else { - return MatcherResult(status: .fail, message: message.appendedBeNilHint()) - } - - return MatcherResult(bool: calls.contains(args), message: message.appended(details: "called with \(calls)")) - } -} -``` - -In this example, we created an actor to act as an object to record calls to an -async function. Then, we created the `beCalled(with:)` matcher to check if the -actor has received a call with the given arguments. - ## Supporting Objective-C To use a custom matcher written in Swift from Objective-C, you'll have -to extend the `NMBMatcher` class, adding a new class method for your +to extend the `NMBPredicate` class, adding a new class method for your custom matcher. The example below defines the class method -`+[NMBMatcher beNilMatcher]`: +`+[NMBPredicate beNilMatcher]`: ```swift // Swift -extension NMBMatcher { - @objc public class func beNilMatcher() -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beNilMatcher() -> NMBPredicate { + return NMBPredicate { actualExpression in return try beNil().satisfies(actualExpression).toObjectiveC() } } @@ -1936,7 +1588,7 @@ The above allows you to use the matcher from Objective-C: ```objc // Objective-C -expect(actual).to([NMBMatcher beNilMatcher]()); +expect(actual).to([NMBPredicate beNilMatcher]()); ``` To make the syntax easier to use, define a C function that calls the @@ -1945,8 +1597,8 @@ class method: ```objc // Objective-C -FOUNDATION_EXPORT NMBMatcher *beNil() { - return [NMBMatcher beNilMatcher]; +FOUNDATION_EXPORT NMBPredicate *beNil() { + return [NMBPredicate beNilMatcher]; } ``` @@ -1968,22 +1620,22 @@ expect(nil).to(equal(nil)); // fails expect(nil).to(beNil()); // passes ``` -If your matcher does not want to match with nil, you use `Matcher.define` or `Matcher.simple`. +If your matcher does not want to match with nil, you use `Predicate.define` or `Predicate.simple`. Using those factory methods will automatically generate expected value failure messages when they're nil. ```swift -public func beginWith(_ startingElement: S.Element) -> Matcher where S.Element: Equatable { - return Matcher.simple("begin with <\(startingElement)>") { actualExpression in +public func beginWith(_ startingElement: S.Element) -> Predicate where S.Element: Equatable { + return Predicate.simple("begin with <\(startingElement)>") { actualExpression in guard let actualValue = try actualExpression.evaluate() else { return .fail } var actualGenerator = actualValue.makeIterator() - return MatcherStatus(bool: actualGenerator.next() == startingElement) + return PredicateStatus(bool: actualGenerator.next() == startingElement) } } -extension NMBMatcher { - @objc public class func beginWithMatcher(_ expected: Any) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beginWithMatcher(_ expected: Any) -> NMBPredicate { + return NMBPredicate { actualExpression in let actual = try actualExpression.evaluate() let expr = actualExpression.cast { $0 as? NMBOrderedCollection } return try beginWith(expected).satisfies(expr).toObjectiveC() @@ -1992,6 +1644,17 @@ extension NMBMatcher { } ``` +## Migrating from the Old Matcher API + +Previously (`<7.0.0`), Nimble supported matchers via the following types: + +- `Matcher` +- `NonNilMatcherFunc` +- `MatcherFunc` + +All of those types have been replaced by `Predicate`. The old API has been +removed completely in Nimble v10. + # Installing Nimble > Nimble can be used on its own, or in conjunction with its sister @@ -2019,7 +1682,7 @@ install just Nimble. ## Installing Nimble via CocoaPods -To use Nimble in CocoaPods to test your macOS, iOS, tvOS or watchOS applications, add +To use Nimble in CocoaPods to test your macOS, iOS or tvOS applications, add Nimble to your podfile and add the ```use_frameworks!``` line to enable Swift support for CocoaPods. @@ -2038,51 +1701,6 @@ end Finally run `pod install`. -## Installing Nimble via Swift Package Manager - -### Xcode - -To install Nimble via Xcode's Swift Package Manager Integration: -Select your project configuration, then the project tab, then the Package -Dependencies tab. Click on the "plus" button at the bottom of the list, -then follow the wizard to add Quick to your project. Specify -`https://github.com/Quick/Nimble.git` as the url, and be sure to add -Nimble as a dependency of your unit test target, not your app target. - -### Package.Swift - -To use Nimble with Swift Package Manager to test your applications, add Nimble -to your `Package.Swift` and link it with your test target: - -```swift -// swift-tools-version:5.5 - -import PackageDescription - -let package = Package( - name: "MyAwesomeLibrary", - products: [ - // ... - ], - dependencies: [ - // ... - .package(url: "https://github.com/Quick/Nimble.git", from: "12.0.0"), - ], - targets: [ - // Targets are the basic building blocks of a package. A target can define a module or a test suite. - // Targets can depend on other targets in this package, and on products in packages this package depends on. - .target( - name: "MyAwesomeLibrary", - dependencies: ...), - .testTarget( - name: "MyAwesomeLibraryTests", - dependencies: ["MyAwesomeLibrary", "Nimble"]), - ] -) -``` - -Please note that if you install Nimble using Swift Package Manager, then `raiseException` is not available. - ## Using Nimble without XCTest Nimble is integrated with XCTest to allow it work well when used in Xcode test @@ -2119,11 +1737,3 @@ rm "${SWIFT_STDLIB_TOOL_DESTINATION_DIR}/libswiftXCTest.dylib" You can now use Nimble assertions in your code and handle failures as you see fit. - -## Privacy Statement - -Nimble is a library that is only used for testing and should never be included -in the binary submitted to App Store Connect. - -Despite not being shipped to Apple, Nimble does not and will never collect any -kind of analytics or tracking. diff --git a/Pods/Nimble/Sources/Nimble/Adapters/AssertionRecorder.swift b/Pods/Nimble/Sources/Nimble/Adapters/AssertionRecorder.swift index 239393e..ac75467 100644 --- a/Pods/Nimble/Sources/Nimble/Adapters/AssertionRecorder.swift +++ b/Pods/Nimble/Sources/Nimble/Adapters/AssertionRecorder.swift @@ -54,11 +54,6 @@ extension NMBExceptionCapture { /// Allows you to temporarily replace the current Nimble assertion handler with /// the one provided for the scope of the closure. /// -/// @warning -/// This form of `withAssertionHandler` does not work in any kind of -/// async context. Use the async form of `withAssertionHandler` -/// if you are running tests in an async context. -/// /// Once the closure finishes, then the original Nimble assertion handler is restored. /// /// @see AssertionHandler @@ -91,11 +86,6 @@ public func withAssertionHandler(_ tempAssertionHandler: AssertionHandler, /// This can be useful if you want to gather information about expectations /// that occur within a closure. /// -/// @warning -/// This form of `gatherExpectations` does not work in any kind of -/// async context. Use the async form of `gatherExpectations` -/// if you are running tests in an async context. -/// /// @param silently expectations are no longer send to the default Nimble /// assertion handler when this is true. Defaults to false. /// @@ -122,11 +112,6 @@ public func gatherExpectations(silently: Bool = false, closure: () -> Void) -> [ /// This can be useful if you want to gather information about failed /// expectations that occur within a closure. /// -/// @warning -/// This form of `gatherFailingExpectations` does not work in any kind of -/// async context. Use the async form of `gatherFailingExpectations` -/// if you are running tests in an async context. -/// /// @param silently expectations are no longer send to the default Nimble /// assertion handler when this is true. Defaults to false. /// diff --git a/Pods/Nimble/Sources/Nimble/Adapters/NMBExpectation.swift b/Pods/Nimble/Sources/Nimble/Adapters/NMBExpectation.swift index 44ced65..6d7d9b9 100644 --- a/Pods/Nimble/Sources/Nimble/Adapters/NMBExpectation.swift +++ b/Pods/Nimble/Sources/Nimble/Adapters/NMBExpectation.swift @@ -1,12 +1,13 @@ #if !os(WASI) -#if canImport(Darwin) +#if canImport(Darwin) && !SWIFT_PACKAGE import class Foundation.NSObject import typealias Foundation.TimeInterval +import enum Dispatch.DispatchTimeInterval -private func from(objcMatcher: NMBMatcher) -> Matcher { - return Matcher { actualExpression in - let result = objcMatcher.satisfies(({ try actualExpression.evaluate() }), +private func from(objcPredicate: NMBPredicate) -> Predicate { + return Predicate { actualExpression in + let result = objcPredicate.satisfies(({ try actualExpression.evaluate() }), location: actualExpression.location) return result.toSwift() } @@ -18,7 +19,7 @@ public class NMBExpectation: NSObject { internal var _negative: Bool internal let _file: FileString internal let _line: UInt - internal var _timeout: NimbleTimeInterval = .seconds(1) + internal var _timeout: DispatchTimeInterval = .seconds(1) @objc public init(actualBlock: @escaping () -> NSObject?, negative: Bool, file: FileString, line: UInt) { self._actualBlock = actualBlock @@ -27,149 +28,149 @@ public class NMBExpectation: NSObject { self._line = line } - private var expectValue: SyncExpectation { + private var expectValue: Expectation { return expect(file: _file, line: _line, self._actualBlock() as NSObject?) } @objc public var withTimeout: (TimeInterval) -> NMBExpectation { - return { timeout in self._timeout = timeout.nimbleInterval + return { timeout in self._timeout = timeout.dispatchInterval return self } } - @objc public var to: (NMBMatcher) -> NMBExpectation { - return { matcher in - self.expectValue.to(from(objcMatcher: matcher)) + @objc public var to: (NMBPredicate) -> NMBExpectation { + return { predicate in + self.expectValue.to(from(objcPredicate: predicate)) return self } } - @objc public var toWithDescription: (NMBMatcher, String) -> NMBExpectation { - return { matcher, description in - self.expectValue.to(from(objcMatcher: matcher), description: description) + @objc public var toWithDescription: (NMBPredicate, String) -> NMBExpectation { + return { predicate, description in + self.expectValue.to(from(objcPredicate: predicate), description: description) return self } } - @objc public var toNot: (NMBMatcher) -> NMBExpectation { - return { matcher in - self.expectValue.toNot(from(objcMatcher: matcher)) + @objc public var toNot: (NMBPredicate) -> NMBExpectation { + return { predicate in + self.expectValue.toNot(from(objcPredicate: predicate)) return self } } - @objc public var toNotWithDescription: (NMBMatcher, String) -> NMBExpectation { - return { matcher, description in - self.expectValue.toNot(from(objcMatcher: matcher), description: description) + @objc public var toNotWithDescription: (NMBPredicate, String) -> NMBExpectation { + return { predicate, description in + self.expectValue.toNot(from(objcPredicate: predicate), description: description) return self } } - @objc public var notTo: (NMBMatcher) -> NMBExpectation { return toNot } + @objc public var notTo: (NMBPredicate) -> NMBExpectation { return toNot } - @objc public var notToWithDescription: (NMBMatcher, String) -> NMBExpectation { return toNotWithDescription } + @objc public var notToWithDescription: (NMBPredicate, String) -> NMBExpectation { return toNotWithDescription } - @objc public var toEventually: (NMBMatcher) -> Void { - return { matcher in + @objc public var toEventually: (NMBPredicate) -> Void { + return { predicate in self.expectValue.toEventually( - from(objcMatcher: matcher), + from(objcPredicate: predicate), timeout: self._timeout, description: nil ) } } - @objc public var toEventuallyWithDescription: (NMBMatcher, String) -> Void { - return { matcher, description in + @objc public var toEventuallyWithDescription: (NMBPredicate, String) -> Void { + return { predicate, description in self.expectValue.toEventually( - from(objcMatcher: matcher), + from(objcPredicate: predicate), timeout: self._timeout, description: description ) } } - @objc public var toEventuallyNot: (NMBMatcher) -> Void { - return { matcher in + @objc public var toEventuallyNot: (NMBPredicate) -> Void { + return { predicate in self.expectValue.toEventuallyNot( - from(objcMatcher: matcher), + from(objcPredicate: predicate), timeout: self._timeout, description: nil ) } } - @objc public var toEventuallyNotWithDescription: (NMBMatcher, String) -> Void { - return { matcher, description in + @objc public var toEventuallyNotWithDescription: (NMBPredicate, String) -> Void { + return { predicate, description in self.expectValue.toEventuallyNot( - from(objcMatcher: matcher), + from(objcPredicate: predicate), timeout: self._timeout, description: description ) } } - @objc public var toNotEventually: (NMBMatcher) -> Void { + @objc public var toNotEventually: (NMBPredicate) -> Void { return toEventuallyNot } - @objc public var toNotEventuallyWithDescription: (NMBMatcher, String) -> Void { + @objc public var toNotEventuallyWithDescription: (NMBPredicate, String) -> Void { return toEventuallyNotWithDescription } - @objc public var toNever: (NMBMatcher) -> Void { - return { matcher in + @objc public var toNever: (NMBPredicate) -> Void { + return { predicate in self.expectValue.toNever( - from(objcMatcher: matcher), + from(objcPredicate: predicate), until: self._timeout, description: nil ) } } - @objc public var toNeverWithDescription: (NMBMatcher, String) -> Void { - return { matcher, description in + @objc public var toNeverWithDescription: (NMBPredicate, String) -> Void { + return { predicate, description in self.expectValue.toNever( - from(objcMatcher: matcher), + from(objcPredicate: predicate), until: self._timeout, description: description ) } } - @objc public var neverTo: (NMBMatcher) -> Void { + @objc public var neverTo: (NMBPredicate) -> Void { return toNever } - @objc public var neverToWithDescription: (NMBMatcher, String) -> Void { + @objc public var neverToWithDescription: (NMBPredicate, String) -> Void { return toNeverWithDescription } - @objc public var toAlways: (NMBMatcher) -> Void { - return { matcher in + @objc public var toAlways: (NMBPredicate) -> Void { + return { predicate in self.expectValue.toAlways( - from(objcMatcher: matcher), + from(objcPredicate: predicate), until: self._timeout, description: nil ) } } - @objc public var toAlwaysWithDescription: (NMBMatcher, String) -> Void { - return { matcher, description in + @objc public var toAlwaysWithDescription: (NMBPredicate, String) -> Void { + return { predicate, description in self.expectValue.toAlways( - from(objcMatcher: matcher), + from(objcPredicate: predicate), until: self._timeout, description: description ) } } - @objc public var alwaysTo: (NMBMatcher) -> Void { + @objc public var alwaysTo: (NMBPredicate) -> Void { return toAlways } - @objc public var alwaysToWithDescription: (NMBMatcher, String) -> Void { + @objc public var alwaysToWithDescription: (NMBPredicate, String) -> Void { return toAlwaysWithDescription } diff --git a/Pods/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift b/Pods/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift index aa515f2..d20dd31 100644 --- a/Pods/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift +++ b/Pods/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift @@ -35,7 +35,6 @@ internal class NimbleEnvironment: NSObject { } var suppressTVOSAssertionWarning: Bool = false - var suppressWatchOSAssertionWarning: Bool = false #if !os(WASI) var awaiter: Awaiter #endif diff --git a/Pods/Nimble/Sources/Nimble/Adapters/NimbleXCTestHandler.swift b/Pods/Nimble/Sources/Nimble/Adapters/NimbleXCTestHandler.swift index 286ae7e..18ec18b 100644 --- a/Pods/Nimble/Sources/Nimble/Adapters/NimbleXCTestHandler.swift +++ b/Pods/Nimble/Sources/Nimble/Adapters/NimbleXCTestHandler.swift @@ -35,17 +35,17 @@ class NimbleXCTestUnavailableHandler: AssertionHandler { } } -#if canImport(Darwin) +#if !SWIFT_PACKAGE /// Helper class providing access to the currently executing XCTestCase instance, if any -@objc final public class CurrentTestCaseTracker: NSObject, XCTestObservation { - @objc public static let sharedInstance = CurrentTestCaseTracker() +@objc final internal class CurrentTestCaseTracker: NSObject, XCTestObservation { + @objc static let sharedInstance = CurrentTestCaseTracker() private(set) var currentTestCase: XCTestCase? private var stashed_swift_reportFatalErrorsToDebugger: Bool = false - @objc public func testCaseWillStart(_ testCase: XCTestCase) { - #if (os(macOS) || os(iOS) || os(visionOS)) && !SWIFT_PACKAGE + @objc func testCaseWillStart(_ testCase: XCTestCase) { + #if os(macOS) || os(iOS) stashed_swift_reportFatalErrorsToDebugger = _swift_reportFatalErrorsToDebugger _swift_reportFatalErrorsToDebugger = false #endif @@ -53,10 +53,10 @@ class NimbleXCTestUnavailableHandler: AssertionHandler { currentTestCase = testCase } - @objc public func testCaseDidFinish(_ testCase: XCTestCase) { + @objc func testCaseDidFinish(_ testCase: XCTestCase) { currentTestCase = nil - #if (os(macOS) || os(iOS) || os(visionOS)) && !SWIFT_PACKAGE + #if os(macOS) || os(iOS) _swift_reportFatalErrorsToDebugger = stashed_swift_reportFatalErrorsToDebugger #endif } @@ -73,7 +73,7 @@ func isXCTestAvailable() -> Bool { } public func recordFailure(_ message: String, location: SourceLocation) { -#if !canImport(Darwin) +#if SWIFT_PACKAGE XCTFail("\(message)", file: location.file, line: location.line) #else if let testCase = CurrentTestCaseTracker.sharedInstance.currentTestCase { diff --git a/Pods/Nimble/Sources/Nimble/DSL+Wait.swift b/Pods/Nimble/Sources/Nimble/DSL+Wait.swift index 7fc5089..a1b51c3 100644 --- a/Pods/Nimble/Sources/Nimble/DSL+Wait.swift +++ b/Pods/Nimble/Sources/Nimble/DSL+Wait.swift @@ -12,23 +12,24 @@ private enum ErrorResult { /// Only classes, protocols, methods, properties, and subscript declarations can be /// bridges to Objective-C via the @objc keyword. This class encapsulates callback-style /// asynchronous waiting logic so that it may be called from Objective-C and Swift. -public class NMBWait: NSObject { +internal class NMBWait: NSObject { // About these kind of lines, `@objc` attributes are only required for Objective-C -// support, so that should be conditional on Darwin platforms. -#if canImport(Darwin) +// support, so that should be conditional on Darwin platforms and normal Xcode builds +// (non-SwiftPM builds). +#if canImport(Darwin) && !SWIFT_PACKAGE @objc - public class func until( + internal class func until( timeout: TimeInterval, file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) -> Void) { - // Convert TimeInterval to NimbleTimeInterval - until(timeout: timeout.nimbleInterval, file: file, line: line, action: action) + // Convert TimeInterval to DispatchTimeInterval + until(timeout: timeout.dispatchInterval, file: file, line: line, action: action) } #endif - public class func until( - timeout: NimbleTimeInterval, + internal class func until( + timeout: DispatchTimeInterval, file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) -> Void) { @@ -38,8 +39,8 @@ public class NMBWait: NSObject { } // Using a throwable closure makes this method not objc compatible. - public class func throwableUntil( - timeout: NimbleTimeInterval, + internal class func throwableUntil( + timeout: DispatchTimeInterval, file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) throws -> Void) { @@ -85,16 +86,16 @@ public class NMBWait: NSObject { } } -#if canImport(Darwin) +#if canImport(Darwin) && !SWIFT_PACKAGE @objc(untilFile:line:action:) - public class func until( + internal class func until( _ file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) -> Void) { until(timeout: .seconds(1), file: file, line: line, action: action) } #else - public class func until( + internal class func until( _ file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) -> Void) { @@ -103,7 +104,7 @@ public class NMBWait: NSObject { #endif } -internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: NimbleTimeInterval) -> String { +internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: DispatchTimeInterval) -> String { // swiftlint:disable:next line_length return "\(fnName) timed out but was unable to run the timeout handler because the main thread is unresponsive (\(leeway.description) is allow after the wait times out). Conditions that may cause this include processing blocking IO on the main thread, calls to sleep(), deadlocks, and synchronous IPC. Nimble forcefully stopped run loop which may cause future failures in test run." } @@ -115,8 +116,7 @@ internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: NimbleTime /// /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. -@available(*, noasync, message: "the sync variant of `waitUntil` does not work in async contexts. Use the async variant as a drop-in replacement") -public func waitUntil(timeout: NimbleTimeInterval = PollingDefaults.timeout, file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) -> Void) { +public func waitUntil(timeout: DispatchTimeInterval = AsyncDefaults.timeout, file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) -> Void) { NMBWait.until(timeout: timeout, file: file, line: line, action: action) } diff --git a/Pods/Nimble/Sources/Nimble/DSL.swift b/Pods/Nimble/Sources/Nimble/DSL.swift index d61ac60..4df36a4 100644 --- a/Pods/Nimble/Sources/Nimble/DSL.swift +++ b/Pods/Nimble/Sources/Nimble/DSL.swift @@ -1,73 +1,33 @@ -/// Make a ``SyncExpectation`` on a given actual value. The value given is lazily evaluated. -public func expect(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure @escaping () throws -> T?) -> SyncExpectation { - return SyncExpectation( +/// Make an expectation on a given actual value. The value given is lazily evaluated. +public func expect(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure @escaping () throws -> T?) -> Expectation { + return Expectation( expression: Expression( expression: expression, location: SourceLocation(file: file, line: line), isClosure: true)) } -/// Make a ``SyncExpectation`` on a given actual value. The closure is lazily invoked. -public func expect(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (() throws -> T)) -> SyncExpectation { - return SyncExpectation( +/// Make an expectation on a given actual value. The closure is lazily invoked. +public func expect(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (() throws -> T)) -> Expectation { + return Expectation( expression: Expression( expression: expression(), location: SourceLocation(file: file, line: line), isClosure: true)) } -/// Make a ``SyncExpectation`` on a given actual value. The closure is lazily invoked. -public func expect(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (() throws -> T?)) -> SyncExpectation { - return SyncExpectation( +/// Make an expectation on a given actual value. The closure is lazily invoked. +public func expect(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (() throws -> T?)) -> Expectation { + return Expectation( expression: Expression( expression: expression(), location: SourceLocation(file: file, line: line), isClosure: true)) } -/// Make a ``SyncExpectation`` on a given actual value. The closure is lazily invoked. -public func expect(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (() throws -> Void)) -> SyncExpectation { - return SyncExpectation( - expression: Expression( - expression: expression(), - location: SourceLocation(file: file, line: line), - isClosure: true)) -} - -/// Make a ``SyncExpectation`` on a given actual value. The value given is lazily evaluated. -/// This is provided as an alternative to `expect` which avoids overloading with `expect -> AsyncExpectation`. -public func expects(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure @escaping () throws -> T?) -> SyncExpectation { - return SyncExpectation( - expression: Expression( - expression: expression, - location: SourceLocation(file: file, line: line), - isClosure: true)) -} - -/// Make a ``SyncExpectation`` on a given actual value. The closure is lazily invoked. -/// This is provided as an alternative to `expect` which avoids overloading with `expect -> AsyncExpectation`. -public func expects(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (() throws -> T)) -> SyncExpectation { - return SyncExpectation( - expression: Expression( - expression: expression(), - location: SourceLocation(file: file, line: line), - isClosure: true)) -} - -/// Make a ``SyncExpectation`` on a given actual value. The closure is lazily invoked. -/// This is provided as an alternative to `expect` which avoids overloading with `expect -> AsyncExpectation`. -public func expects(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (() throws -> T?)) -> SyncExpectation { - return SyncExpectation( - expression: Expression( - expression: expression(), - location: SourceLocation(file: file, line: line), - isClosure: true)) -} - -/// Make a ``SyncExpectation`` on a given actual value. The closure is lazily invoked. -/// This is provided as an alternative to `expect` which avoids overloading with `expect -> AsyncExpectation`. -public func expects(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (() throws -> Void)) -> SyncExpectation { - return SyncExpectation( +/// Make an expectation on a given actual value. The closure is lazily invoked. +public func expect(file: FileString = #file, line: UInt = #line, _ expression: @autoclosure () -> (() throws -> Void)) -> Expectation { + return Expectation( expression: Expression( expression: expression(), location: SourceLocation(file: file, line: line), @@ -111,6 +71,7 @@ internal func internalError(_ msg: String, file: FileString = #file, line: UInt Please file a bug to Nimble: https://github.com/Quick/Nimble/issues with the code snippet that caused this error. """ ) + // swiftlint:enable line_length } #if canImport(Darwin) diff --git a/Pods/Nimble/Sources/Nimble/Expectation.swift b/Pods/Nimble/Sources/Nimble/Expectation.swift index 732e0c5..e4a12fa 100644 --- a/Pods/Nimble/Sources/Nimble/Expectation.swift +++ b/Pods/Nimble/Sources/Nimble/Expectation.swift @@ -1,10 +1,10 @@ -internal func execute(_ expression: Expression, _ style: ExpectationStyle, _ matcher: Matcher, to: String, description: String?, captureExceptions: Bool = true) -> (Bool, FailureMessage) { +internal func execute(_ expression: Expression, _ style: ExpectationStyle, _ predicate: Predicate, to: String, description: String?, captureExceptions: Bool = true) -> (Bool, FailureMessage) { func run() -> (Bool, FailureMessage) { let msg = FailureMessage() msg.userDescription = description msg.to = to do { - let result = try matcher.satisfies(expression) + let result = try predicate.satisfies(expression) result.message.update(failureMessage: msg) if msg.actualValue == "" { msg.actualValue = "<\(stringify(try expression.evaluate()))>" @@ -33,300 +33,44 @@ internal func execute(_ expression: Expression, _ style: ExpectationStyle, return result } -internal func execute(_ expression: AsyncExpression, _ style: ExpectationStyle, _ matcher: AsyncMatcher, to: String, description: String?) async -> (Bool, FailureMessage) { - let msg = FailureMessage() - msg.userDescription = description - msg.to = to - do { - let result = try await matcher.satisfies(expression) - result.message.update(failureMessage: msg) - if msg.actualValue == "" { - msg.actualValue = "<\(stringify(try await expression.evaluate()))>" - } - return (result.toBoolean(expectation: style), msg) - } catch let error { - msg.stringValue = "unexpected error thrown: <\(error)>" - return (false, msg) - } -} - -public enum ExpectationStatus: Equatable { - - /// No matchers have been performed. - case pending - - /// All matchers have passed. - case passed - - /// All matchers have failed. - case failed +public struct Expectation { - /// Multiple matchers have been peformed, with at least one passing and one failing. - case mixed -} + public let expression: Expression -extension ExpectationStatus { - /// Applies a new status to the current one to produce a combined status. - /// - /// This method is meant to advance the state from `.pending` to either `.passed` or`.failed`. - /// When called multiple times with different values, the result will be `.mixed`. - /// E.g., `status.applying(.passed).applying(.failed) == .mixed`. - func applying(_ newerStatus: ExpectationStatus) -> ExpectationStatus { - if newerStatus == .pending { return self } - if self == .pending || self == newerStatus { return newerStatus } - return .mixed - } -} - -public protocol Expectation { - var location: SourceLocation { get } - - /// The status of the test after matchers have been evaluated. - /// - /// This property can be used for changing test behavior based whether an expectation has - /// passed. - /// - /// In the below example, we perform additional tests on an array only if it has enough - /// elements. - /// - /// ``` - /// if expect(array).to(haveCount(10)).status == .passed { - /// expect(array[9]).to(...) - /// } - /// ``` - /// - /// - Remark: Similar functionality can be achieved using the `onFailure(throw:)` method. - var status: ExpectationStatus { get } - - /// Takes the result of a test and passes it to the assertion handler. - /// - /// - Returns: An updated `Expression` with the result of the test applied to the `status` - /// property. - @discardableResult - func verify(_ pass: Bool, _ message: FailureMessage) -> Self -} - -extension Expectation { - /// Throws the supplied error if the expectation has previously failed. - /// - /// This provides a mechanism for halting tests when a failure occurs. This can be used in - /// conjunction with `Quick.StopTest` to halt a test when a failure would cause subsequent test - /// code to fail. - /// - /// In the below example, the test will stop in the first line if `array.count == 5` rather - /// than crash on the second line. - /// - /// ``` - /// try expect(array).to(haveCount(10)).onFailure(throw: StopTest.silently) - /// expect(array[9]).to(...) - /// ``` - /// - /// - Warning: This method **MUST** be called after a matcher method like `to` or `not`. - /// Otherwise, this expectation will be in an indeterminate state and will - /// unconditionally log an error. - /// - /// - Remark: Similar functionality can be achieved using the `status` property. - /// - Attention: This is deprecated in favor of the `require` dsl (``require``, ``unwrap``, - /// ``pollUnwrap``), which integrates the matcher seemlessly, or, in the case of - /// `unwrap` and `pollUnwrap`, acts as a shorthand when you require that an - /// expression evaluate to some non-nil value. `onFailure` will be removed in - /// Nimble 15. - @available(*, deprecated, message: "Use the require dsl") - public func onFailure(`throw` error: Error) throws { - switch status { - case .pending: - let msg = """ - Attempted to call `Expectation.onFailure(throw:) before a matcher has been applied. - Try using `expect(...).to(...).onFailure(throw: ...`) instead. - """ - - let handler = NimbleEnvironment.activeInstance.assertionHandler - handler.assert(false, message: .init(stringValue: msg), location: location) - case .passed: - break - case .failed, .mixed: - throw error - } - } -} - -public struct SyncExpectation: Expectation { - public let expression: Expression - - /// The status of the test after matchers have been evaluated. - /// - /// This property can be used for changing test behavior based whether an expectation has - /// passed. - /// - /// In the below example, we perform additional tests on an array only if it has enough - /// elements. - /// - /// ``` - /// if expect(array).to(haveCount(10)).status == .passed { - /// expect(array[9]).to(...) - /// } - /// ``` - /// - /// - Remark: Similar functionality can be achieved using the `onFailure(throw:)` method. - public let status: ExpectationStatus - - private init(expression: Expression, status: ExpectationStatus) { + public init(expression: Expression) { self.expression = expression - self.status = status - } - - public init(expression: Expression) { - self.init(expression: expression, status: .pending) } - /// Takes the result of a test and passes it to the assertion handler. - /// - /// - Returns: An updated `Expression` with the result of the test applied to the `status` - /// property. - @discardableResult - public func verify(_ pass: Bool, _ message: FailureMessage) -> Self { + public func verify(_ pass: Bool, _ message: FailureMessage) { let handler = NimbleEnvironment.activeInstance.assertionHandler handler.assert(pass, message: message, location: expression.location) - - return .init(expression: expression, status: status.applying(pass ? .passed : .failed)) - } - - public var location: SourceLocation { expression.location } - - /// Tests the actual value using a matcher to match. - @discardableResult - public func to(_ matcher: Matcher, description: String? = nil) -> Self { - let (pass, msg) = execute(expression, .toMatch, matcher, to: "to", description: description) - return verify(pass, msg) - } - - /// Tests the actual value using a matcher to not match. - @discardableResult - public func toNot(_ matcher: Matcher, description: String? = nil) -> Self { - let (pass, msg) = execute(expression, .toNotMatch, matcher, to: "to not", description: description) - return verify(pass, msg) - } - - /// Tests the actual value using a matcher to not match. - /// - /// Alias to toNot(). - @discardableResult - public func notTo(_ matcher: Matcher, description: String? = nil) -> Self { - toNot(matcher, description: description) } - // MARK: - AsyncMatchers /// Tests the actual value using a matcher to match. @discardableResult - public func to(_ matcher: AsyncMatcher, description: String? = nil) async -> Self { - let (pass, msg) = await execute(expression.toAsyncExpression(), .toMatch, matcher, to: "to", description: description) - return verify(pass, msg) + public func to(_ predicate: Predicate, description: String? = nil) -> Self { + let (pass, msg) = execute(expression, .toMatch, predicate, to: "to", description: description) + verify(pass, msg) + return self } /// Tests the actual value using a matcher to not match. @discardableResult - public func toNot(_ matcher: AsyncMatcher, description: String? = nil) async -> Self { - let (pass, msg) = await execute(expression.toAsyncExpression(), .toNotMatch, matcher, to: "to not", description: description) - return verify(pass, msg) + public func toNot(_ predicate: Predicate, description: String? = nil) -> Self { + let (pass, msg) = execute(expression, .toNotMatch, predicate, to: "to not", description: description) + verify(pass, msg) + return self } /// Tests the actual value using a matcher to not match. /// /// Alias to toNot(). @discardableResult - public func notTo(_ matcher: AsyncMatcher, description: String? = nil) async -> Self { - await toNot(matcher, description: description) + public func notTo(_ predicate: Predicate, description: String? = nil) -> Self { + return toNot(predicate, description: description) } // see: - // - `Polling.swift` for toEventually and older-style polling-based approach to "async" + // - `async` for extension // - NMBExpectation for Objective-C interface } - -public struct AsyncExpectation: Expectation { - public let expression: AsyncExpression - - /// The status of the test after matchers have been evaluated. - /// - /// This property can be used for changing test behavior based whether an expectation has - /// passed. - /// - /// In the below example, we perform additional tests on an array only if it has enough - /// elements. - /// - /// ``` - /// if expect(array).to(haveCount(10)).status == .passed { - /// expect(array[9]).to(...) - /// } - /// ``` - /// - /// - Remark: Similar functionality can be achieved using the `onFailure(throw:)` method. - public let status: ExpectationStatus - - private init(expression: AsyncExpression, status: ExpectationStatus) { - self.expression = expression - self.status = status - } - - public init(expression: AsyncExpression) { - self.init(expression: expression, status: .pending) - } - - public var location: SourceLocation { expression.location } - - /// Takes the result of a test and passes it to the assertion handler. - /// - /// - Returns: An updated `Expression` with the result of the test applied to the `status` - /// property. - @discardableResult - public func verify(_ pass: Bool, _ message: FailureMessage) -> Self { - let handler = NimbleEnvironment.activeInstance.assertionHandler - handler.assert(pass, message: message, location: expression.location) - - return .init(expression: expression, status: status.applying(pass ? .passed : .failed)) - } - - /// Tests the actual value using a matcher to match. - @discardableResult - public func to(_ matcher: Matcher, description: String? = nil) async -> Self { - let (pass, msg) = execute(await expression.toSynchronousExpression(), .toMatch, matcher, to: "to", description: description) - return verify(pass, msg) - } - - /// Tests the actual value using a matcher to not match. - @discardableResult - public func toNot(_ matcher: Matcher, description: String? = nil) async -> Self { - let (pass, msg) = execute(await expression.toSynchronousExpression(), .toNotMatch, matcher, to: "to not", description: description) - return verify(pass, msg) - } - - /// Tests the actual value using a matcher to not match. - /// - /// Alias to toNot(). - @discardableResult - public func notTo(_ matcher: Matcher, description: String? = nil) async -> Self { - await toNot(matcher, description: description) - } - - /// Tests the actual value using a matcher to match. - @discardableResult - public func to(_ matcher: AsyncMatcher, description: String? = nil) async -> Self { - let (pass, msg) = await execute(expression, .toMatch, matcher, to: "to", description: description) - return verify(pass, msg) - } - - /// Tests the actual value using a matcher to not match. - @discardableResult - public func toNot(_ matcher: AsyncMatcher, description: String? = nil) async -> Self { - let (pass, msg) = await execute(expression, .toNotMatch, matcher, to: "to not", description: description) - return verify(pass, msg) - } - - /// Tests the actual value using a matcher to not match. - /// - /// Alias to toNot(). - @discardableResult - public func notTo(_ matcher: AsyncMatcher, description: String? = nil) async -> Self { - await toNot(matcher, description: description) - } -} diff --git a/Pods/Nimble/Sources/Nimble/Expression.swift b/Pods/Nimble/Sources/Nimble/Expression.swift index 1bab44f..ecef26f 100644 --- a/Pods/Nimble/Sources/Nimble/Expression.swift +++ b/Pods/Nimble/Sources/Nimble/Expression.swift @@ -1,6 +1,6 @@ // Memoizes the given closure, only calling the passed // closure once; even if repeat calls to the returned closure -private func memoizedClosure(_ closure: @escaping () throws -> T) -> (Bool) throws -> T { +internal func memoizedClosure(_ closure: @escaping () throws -> T) -> (Bool) throws -> T { var cache: T? return { withoutCaching in if withoutCaching || cache == nil { @@ -15,14 +15,14 @@ private func memoizedClosure(_ closure: @escaping () throws -> T) -> (Bool) t /// evaluate() multiple times without causing a re-evaluation of the underlying /// closure. /// -/// - Warning: Since the closure can be any code, Objective-C code may choose -/// to raise an exception. Currently, SyncExpression does not memoize +/// @warning Since the closure can be any code, Objective-C code may choose +/// to raise an exception. Currently, Expression does not memoize /// exception raising. /// /// This provides a common consumable API for matchers to utilize to allow /// Nimble to change internals to how the captured closure is managed. -public struct Expression { - internal let _expression: (Bool) throws -> Value? +public struct Expression { + internal let _expression: (Bool) throws -> T? internal let _withoutCaching: Bool public let location: SourceLocation public let isClosure: Bool @@ -30,15 +30,15 @@ public struct Expression { /// Creates a new expression struct. Normally, expect(...) will manage this /// creation process. The expression is memoized. /// - /// - Parameter expression: The closure that produces a given value. - /// - Parameter location: The source location that this closure originates from. - /// - Parameter isClosure: A bool indicating if the captured expression is a + /// @param expression The closure that produces a given value. + /// @param location The source location that this closure originates from. + /// @param isClosure A bool indicating if the captured expression is a /// closure or internally produced closure. Some matchers /// may require closures. For example, toEventually() /// requires an explicit closure. This gives Nimble /// flexibility if @autoclosure behavior changes between /// Swift versions. Nimble internals always sets this true. - public init(expression: @escaping () throws -> Value?, location: SourceLocation, isClosure: Bool = true) { + public init(expression: @escaping () throws -> T?, location: SourceLocation, isClosure: Bool = true) { self._expression = memoizedClosure(expression) self.location = location self._withoutCaching = false @@ -48,18 +48,18 @@ public struct Expression { /// Creates a new expression struct. Normally, expect(...) will manage this /// creation process. /// - /// - Parameter expression: The closure that produces a given value. - /// - Parameter location: The source location that this closure originates from. - /// - Parameter withoutCaching: Indicates if the struct should memoize the given + /// @param expression The closure that produces a given value. + /// @param location The source location that this closure originates from. + /// @param withoutCaching Indicates if the struct should memoize the given /// closure's result. Subsequent evaluate() calls will /// not call the given closure if this is true. - /// - Parameter isClosure: A bool indicating if the captured expression is a + /// @param isClosure A bool indicating if the captured expression is a /// closure or internally produced closure. Some matchers /// may require closures. For example, toEventually() /// requires an explicit closure. This gives Nimble /// flexibility if @autoclosure behavior changes between /// Swift versions. Nimble internals always sets this true. - public init(memoizedExpression: @escaping (Bool) throws -> Value?, location: SourceLocation, withoutCaching: Bool, isClosure: Bool = true) { + public init(memoizedExpression: @escaping (Bool) throws -> T?, location: SourceLocation, withoutCaching: Bool, isClosure: Bool = true) { self._expression = memoizedExpression self.location = location self._withoutCaching = withoutCaching @@ -72,44 +72,26 @@ public struct Expression { /// /// The returned expression will preserve location and isClosure. /// - /// - Parameter block: The block that can cast the current Expression value to a + /// @param block The block that can cast the current Expression value to a /// new type. - public func cast(_ block: @escaping (Value?) throws -> U?) -> Expression { - Expression( + public func cast(_ block: @escaping (T?) throws -> U?) -> Expression { + return Expression( expression: ({ try block(self.evaluate()) }), location: self.location, isClosure: self.isClosure ) } - public func evaluate() throws -> Value? { - try self._expression(_withoutCaching) + public func evaluate() throws -> T? { + return try self._expression(_withoutCaching) } - public func withoutCaching() -> Expression { - Expression( + public func withoutCaching() -> Expression { + return Expression( memoizedExpression: self._expression, location: location, withoutCaching: true, isClosure: isClosure ) } - - public func withCaching() -> Expression { - Expression( - memoizedExpression: memoizedClosure { try self.evaluate() }, - location: self.location, - withoutCaching: false, - isClosure: isClosure - ) - } - - public func toAsyncExpression() -> AsyncExpression { - AsyncExpression( - memoizedExpression: { @MainActor memoize in try _expression(memoize) }, - location: location, - withoutCaching: _withoutCaching, - isClosure: isClosure - ) - } } diff --git a/Pods/Nimble/Sources/Nimble/FailureMessage.swift b/Pods/Nimble/Sources/Nimble/FailureMessage.swift index 8b60b9c..2bc57eb 100644 --- a/Pods/Nimble/Sources/Nimble/FailureMessage.swift +++ b/Pods/Nimble/Sources/Nimble/FailureMessage.swift @@ -56,7 +56,7 @@ public class FailureMessage: NSObject { value = stripNewlines(value) if let extendedMessage = extendedMessage { - value += "\n\(extendedMessage)" + value += "\n\(stripNewlines(extendedMessage))" } if let userDescription = userDescription { diff --git a/Pods/Nimble/Sources/Nimble/Matchers/AllPass.swift b/Pods/Nimble/Sources/Nimble/Matchers/AllPass.swift index 133c21e..104fc9f 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/AllPass.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/AllPass.swift @@ -1,36 +1,36 @@ public func allPass( _ passFunc: @escaping (S.Element) throws -> Bool -) -> Matcher { - let matcher = Matcher.define("pass a condition") { actualExpression, message in +) -> Predicate { + let matcher = Predicate.define("pass a condition") { actualExpression, message in guard let actual = try actualExpression.evaluate() else { - return MatcherResult(status: .fail, message: message) + return PredicateResult(status: .fail, message: message) } - return MatcherResult(bool: try passFunc(actual), message: message) + return PredicateResult(bool: try passFunc(actual), message: message) } - return createMatcher(matcher) + return createPredicate(matcher) } public func allPass( _ passName: String, _ passFunc: @escaping (S.Element) throws -> Bool -) -> Matcher { - let matcher = Matcher.define(passName) { actualExpression, message in +) -> Predicate { + let matcher = Predicate.define(passName) { actualExpression, message in guard let actual = try actualExpression.evaluate() else { - return MatcherResult(status: .fail, message: message) + return PredicateResult(status: .fail, message: message) } - return MatcherResult(bool: try passFunc(actual), message: message) + return PredicateResult(bool: try passFunc(actual), message: message) } - return createMatcher(matcher) + return createPredicate(matcher) } -public func allPass(_ elementMatcher: Matcher) -> Matcher { - return createMatcher(elementMatcher) +public func allPass(_ elementPredicate: Predicate) -> Predicate { + return createPredicate(elementPredicate) } -private func createMatcher(_ elementMatcher: Matcher) -> Matcher { - return Matcher { actualExpression in +private func createPredicate(_ elementMatcher: Predicate) -> Predicate { + return Predicate { actualExpression in guard let actualValue = try actualExpression.evaluate() else { - return MatcherResult( + return PredicateResult( status: .fail, message: .appends(.expectedTo("all pass"), " (use beNil() to match nils)") ) @@ -42,24 +42,24 @@ private func createMatcher(_ elementMatcher: Matcher) -> expression: { currentElement }, location: actualExpression.location ) - let matcherResult = try elementMatcher.satisfies(exp) - if matcherResult.status == .matches { - failure = matcherResult.message.prepended(expectation: "all ") + let predicateResult = try elementMatcher.satisfies(exp) + if predicateResult.status == .matches { + failure = predicateResult.message.prepended(expectation: "all ") } else { - failure = matcherResult.message + failure = predicateResult.message .replacedExpectation({ .expectedTo($0.expectedMessage) }) .wrappedExpectation( before: "all ", after: ", but failed first at element <\(stringify(currentElement))>" + " in <\(stringify(actualValue))>" ) - return MatcherResult(status: .doesNotMatch, message: failure) + return PredicateResult(status: .doesNotMatch, message: failure) } } failure = failure.replacedExpectation({ expectation in return .expectedTo(expectation.expectedMessage) }) - return MatcherResult(status: .matches, message: failure) + return PredicateResult(status: .matches, message: failure) } } @@ -68,9 +68,9 @@ import class Foundation.NSObject import struct Foundation.NSFastEnumerationIterator import protocol Foundation.NSFastEnumeration -extension NMBMatcher { - @objc public class func allPassMatcher(_ matcher: NMBMatcher) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func allPassMatcher(_ predicate: NMBPredicate) -> NMBPredicate { + return NMBPredicate { actualExpression in let location = actualExpression.location let actualValue = try actualExpression.evaluate() var nsObjects = [NSObject]() @@ -91,8 +91,8 @@ extension NMBMatcher { } if !collectionIsUsable { - return NMBMatcherResult( - status: NMBMatcherStatus.fail, + return NMBPredicateResult( + status: NMBPredicateStatus.fail, message: NMBExpectationMessage( // swiftlint:disable:next line_length fail: "allPass can only be used with types which implement NSFastEnumeration (NSArray, NSSet, ...), and whose elements subclass NSObject, got <\(actualValue?.description ?? "nil")>" @@ -101,8 +101,8 @@ extension NMBMatcher { } let expr = Expression(expression: ({ nsObjects }), location: location) - let pred: Matcher<[NSObject]> = createMatcher(Matcher { expr in - return matcher.satisfies(({ try expr.evaluate() }), location: expr.location).toSwift() + let pred: Predicate<[NSObject]> = createPredicate(Predicate { expr in + return predicate.satisfies(({ try expr.evaluate() }), location: expr.location).toSwift() }) return try pred.satisfies(expr).toObjectiveC() } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/Async.swift b/Pods/Nimble/Sources/Nimble/Matchers/Async.swift new file mode 100644 index 0000000..2f86e32 --- /dev/null +++ b/Pods/Nimble/Sources/Nimble/Matchers/Async.swift @@ -0,0 +1,232 @@ +#if !os(WASI) + +import Foundation +import Dispatch + +/// If you are running on a slower machine, it could be useful to increase the default timeout value +/// or slow down poll interval. Default timeout interval is 1, and poll interval is 0.01. +public struct AsyncDefaults { + public static var timeout: DispatchTimeInterval = .seconds(1) + public static var pollInterval: DispatchTimeInterval = .milliseconds(10) +} + +private enum AsyncMatchStyle { + case eventually, never, always +} + +// swiftlint:disable:next function_parameter_count +private func async( + style: ExpectationStyle, + matchStyle: AsyncMatchStyle, + predicate: Predicate, + timeout: DispatchTimeInterval, + poll: DispatchTimeInterval, + fnName: String +) -> Predicate { + return Predicate { actualExpression in + let uncachedExpression = actualExpression.withoutCaching() + let fnName = "expect(...).\(fnName)(...)" + var lastPredicateResult: PredicateResult? + let result = pollBlock( + pollInterval: poll, + timeoutInterval: timeout, + file: actualExpression.location.file, + line: actualExpression.location.line, + fnName: fnName) { + lastPredicateResult = try predicate.satisfies(uncachedExpression) + return lastPredicateResult!.toBoolean(expectation: style) + } + switch result { + case .completed: + switch matchStyle { + case .eventually: + return lastPredicateResult! + case .never: + return PredicateResult( + status: .fail, + message: lastPredicateResult?.message ?? .fail("matched the predicate when it shouldn't have") + ) + case .always: + return PredicateResult( + status: .fail, + message: lastPredicateResult?.message ?? .fail("didn't match the predicate when it should have") + ) + } + case .timedOut: + switch matchStyle { + case .eventually: + let message = lastPredicateResult?.message ?? .fail("timed out before returning a value") + return PredicateResult(status: .fail, message: message) + case .never: + return PredicateResult(status: .doesNotMatch, message: .expectedTo("never match the predicate")) + case .always: + return PredicateResult(status: .matches, message: .expectedTo("always match the predicate")) + } + case let .errorThrown(error): + return PredicateResult(status: .fail, message: .fail("unexpected error thrown: <\(error)>")) + case let .raisedException(exception): + return PredicateResult(status: .fail, message: .fail("unexpected exception raised: \(exception)")) + case .blockedRunLoop: + let message = lastPredicateResult?.message.appended(message: " (timed out, but main run loop was unresponsive).") ?? + .fail("main run loop was unresponsive") + return PredicateResult(status: .fail, message: message) + case .incomplete: + internalError("Reached .incomplete state for \(fnName)(...).") + } + } +} + +private let toEventuallyRequiresClosureError = FailureMessage( + stringValue: """ + expect(...).toEventually(...) requires an explicit closure (eg - expect { ... }.toEventually(...) ) + Swift 1.2 @autoclosure behavior has changed in an incompatible way for Nimble to function + """ +) + +extension Expectation { + /// Tests the actual value using a matcher to match by checking continuously + /// at each pollInterval until the timeout is reached. + /// + /// @discussion + /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function + /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. + public func toEventually(_ predicate: Predicate, timeout: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil) { + nimblePrecondition(expression.isClosure, "NimbleInternalError", toEventuallyRequiresClosureError.stringValue) + + let (pass, msg) = execute( + expression, + .toMatch, + async( + style: .toMatch, + matchStyle: .eventually, + predicate: predicate, + timeout: timeout, + poll: pollInterval, + fnName: "toEventually" + ), + to: "to eventually", + description: description, + captureExceptions: false + ) + verify(pass, msg) + } + + /// Tests the actual value using a matcher to not match by checking + /// continuously at each pollInterval until the timeout is reached. + /// + /// @discussion + /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function + /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. + public func toEventuallyNot(_ predicate: Predicate, timeout: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil) { + nimblePrecondition(expression.isClosure, "NimbleInternalError", toEventuallyRequiresClosureError.stringValue) + + let (pass, msg) = execute( + expression, + .toNotMatch, + async( + style: .toNotMatch, + matchStyle: .eventually, + predicate: predicate, + timeout: timeout, + poll: pollInterval, + fnName: "toEventuallyNot" + ), + to: "to eventually not", + description: description, + captureExceptions: false + ) + verify(pass, msg) + } + + /// Tests the actual value using a matcher to not match by checking + /// continuously at each pollInterval until the timeout is reached. + /// + /// Alias of toEventuallyNot() + /// + /// @discussion + /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function + /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. + public func toNotEventually(_ predicate: Predicate, timeout: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil) { + return toEventuallyNot(predicate, timeout: timeout, pollInterval: pollInterval, description: description) + } + + /// Tests the actual value using a matcher to never match by checking + /// continuously at each pollInterval until the timeout is reached. + /// + /// @discussion + /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function + /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. + public func toNever(_ predicate: Predicate, until: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil) { + nimblePrecondition(expression.isClosure, "NimbleInternalError", toEventuallyRequiresClosureError.stringValue) + + let (pass, msg) = execute( + expression, + .toNotMatch, + async( + style: .toMatch, + matchStyle: .never, + predicate: predicate, + timeout: until, + poll: pollInterval, + fnName: "toNever" + ), + to: "to never", + description: description, + captureExceptions: false + ) + verify(pass, msg) + } + + /// Tests the actual value using a matcher to never match by checking + /// continuously at each pollInterval until the timeout is reached. + /// + /// Alias of toNever() + /// + /// @discussion + /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function + /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. + public func neverTo(_ predicate: Predicate, until: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil) { + return toNever(predicate, until: until, pollInterval: pollInterval, description: description) + } + + /// Tests the actual value using a matcher to always match by checking + /// continusouly at each pollInterval until the timeout is reached + /// + /// @discussion + /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function + /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. + public func toAlways(_ predicate: Predicate, until: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil) { + nimblePrecondition(expression.isClosure, "NimbleInternalError", toEventuallyRequiresClosureError.stringValue) + + let (pass, msg) = execute( + expression, + .toMatch, + async( + style: .toNotMatch, + matchStyle: .always, + predicate: predicate, + timeout: until, + poll: pollInterval, + fnName: "toAlways" + ), + to: "to always", + description: description, + captureExceptions: false + ) + verify(pass, msg) + } + + /// Tests the actual value using a matcher to always match by checking + /// continusouly at each pollInterval until the timeout is reached + /// + /// Alias of toAlways() + /// + /// @discussion + /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function + /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. + public func alwaysTo(_ predicate: Predicate, until: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil) { + return toAlways(predicate, until: until, pollInterval: pollInterval, description: description) + } +} + +#endif // #if !os(WASI) diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeAKindOf.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeAKindOf.swift index 6b010ec..f01ca77 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeAKindOf.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeAKindOf.swift @@ -6,21 +6,21 @@ private func matcherMessage(forClass expectedClass: AnyClass) -> String { } /// A Nimble matcher that succeeds when the actual value is an instance of the given class. -public func beAKindOf(_ expectedType: T.Type) -> Matcher { - return Matcher.define { actualExpression in +public func beAKindOf(_ expectedType: T.Type) -> Predicate { + return Predicate.define { actualExpression in let message: ExpectationMessage let instance = try actualExpression.evaluate() guard let validInstance = instance else { message = .expectedCustomValueTo(matcherMessage(forType: expectedType), actual: "") - return MatcherResult(status: .fail, message: message) + return PredicateResult(status: .fail, message: message) } message = .expectedCustomValueTo( "be a kind of \(String(describing: expectedType))", actual: "<\(String(describing: type(of: validInstance))) instance>" ) - return MatcherResult( + return PredicateResult( bool: validInstance is T, message: message ) @@ -32,14 +32,14 @@ import class Foundation.NSObject /// A Nimble matcher that succeeds when the actual value is an instance of the given class. /// @see beAnInstanceOf if you want to match against the exact class -public func beAKindOf(_ expectedClass: AnyClass) -> Matcher { - return Matcher.define { actualExpression in +public func beAKindOf(_ expectedClass: AnyClass) -> Predicate { + return Predicate.define { actualExpression in let message: ExpectationMessage - let status: MatcherStatus + let status: PredicateStatus let instance = try actualExpression.evaluate() if let validInstance = instance { - status = MatcherStatus(bool: instance != nil && instance!.isKind(of: expectedClass)) + status = PredicateStatus(bool: instance != nil && instance!.isKind(of: expectedClass)) message = .expectedCustomValueTo( matcherMessage(forClass: expectedClass), actual: "<\(String(describing: type(of: validInstance))) instance>" @@ -52,13 +52,13 @@ public func beAKindOf(_ expectedClass: AnyClass) -> Matcher { ) } - return MatcherResult(status: status, message: message) + return PredicateResult(status: status, message: message) } } -extension NMBMatcher { - @objc public class func beAKindOfMatcher(_ expected: AnyClass) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beAKindOfMatcher(_ expected: AnyClass) -> NMBPredicate { + return NMBPredicate { actualExpression in return try beAKindOf(expected).satisfies(actualExpression).toObjectiveC() } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeAnInstanceOf.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeAnInstanceOf.swift index d8a1311..47ea663 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeAnInstanceOf.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeAnInstanceOf.swift @@ -1,12 +1,12 @@ import Foundation /// A Nimble matcher that succeeds when the actual value is an _exact_ instance of the given class. -public func beAnInstanceOf(_ expectedType: T.Type) -> Matcher { +public func beAnInstanceOf(_ expectedType: T.Type) -> Predicate { let errorMessage = "be an instance of \(String(describing: expectedType))" - return Matcher.define { actualExpression in + return Predicate.define { actualExpression in let instance = try actualExpression.evaluate() guard let validInstance = instance else { - return MatcherResult( + return PredicateResult( status: .doesNotMatch, message: .expectedActualValueTo(errorMessage) ) @@ -14,8 +14,8 @@ public func beAnInstanceOf(_ expectedType: T.Type) -> Matcher { let actualString = "<\(String(describing: type(of: validInstance))) instance>" - return MatcherResult( - status: MatcherStatus(bool: type(of: validInstance) == expectedType), + return PredicateResult( + status: PredicateStatus(bool: type(of: validInstance) == expectedType), message: .expectedCustomValueTo(errorMessage, actual: actualString) ) } @@ -23,9 +23,9 @@ public func beAnInstanceOf(_ expectedType: T.Type) -> Matcher { /// A Nimble matcher that succeeds when the actual value is an instance of the given class. /// @see beAKindOf if you want to match against subclasses -public func beAnInstanceOf(_ expectedClass: AnyClass) -> Matcher { +public func beAnInstanceOf(_ expectedClass: AnyClass) -> Predicate { let errorMessage = "be an instance of \(String(describing: expectedClass))" - return Matcher.define { actualExpression in + return Predicate.define { actualExpression in let instance = try actualExpression.evaluate() let actualString: String if let validInstance = instance { @@ -38,17 +38,17 @@ public func beAnInstanceOf(_ expectedClass: AnyClass) -> Matcher { #else let matches = instance != nil && type(of: instance!) == expectedClass #endif - return MatcherResult( - status: MatcherStatus(bool: matches), + return PredicateResult( + status: PredicateStatus(bool: matches), message: .expectedCustomValueTo(errorMessage, actual: actualString) ) } } #if canImport(Darwin) -extension NMBMatcher { - @objc public class func beAnInstanceOfMatcher(_ expected: AnyClass) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beAnInstanceOfMatcher(_ expected: AnyClass) -> NMBPredicate { + return NMBPredicate { actualExpression in return try beAnInstanceOf(expected).satisfies(actualExpression).toObjectiveC() } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeCloseTo.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeCloseTo.swift index 36dc0e0..e7fd2d1 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeCloseTo.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeCloseTo.swift @@ -9,9 +9,9 @@ internal func isCloseTo( _ actualValue: Value?, expectedValue: Value, delta: Value -) -> MatcherResult { +) -> PredicateResult { let errorMessage = "be close to <\(stringify(expectedValue))> (within \(stringify(delta)))" - return MatcherResult( + return PredicateResult( bool: actualValue != nil && abs(actualValue! - expectedValue) < delta, message: .expectedCustomValueTo(errorMessage, actual: "<\(stringify(actualValue))>") @@ -22,9 +22,9 @@ internal func isCloseTo( _ actualValue: NMBDoubleConvertible?, expectedValue: NMBDoubleConvertible, delta: Double -) -> MatcherResult { +) -> PredicateResult { let errorMessage = "be close to <\(stringify(expectedValue))> (within \(stringify(delta)))" - return MatcherResult( + return PredicateResult( bool: actualValue != nil && abs(actualValue!.doubleValue - expectedValue.doubleValue) < delta, message: .expectedCustomValueTo(errorMessage, actual: "<\(stringify(actualValue))>") @@ -38,8 +38,8 @@ internal func isCloseTo( public func beCloseTo( _ expectedValue: Value, within delta: Value = defaultDelta() -) -> Matcher { - return Matcher.define { actualExpression in +) -> Predicate { + return Predicate.define { actualExpression in return isCloseTo(try actualExpression.evaluate(), expectedValue: expectedValue, delta: delta) } } @@ -51,8 +51,8 @@ public func beCloseTo( public func beCloseTo( _ expectedValue: Value, within delta: Double = DefaultDelta -) -> Matcher { - return Matcher.define { actualExpression in +) -> Predicate { + return Predicate.define { actualExpression in return isCloseTo(try actualExpression.evaluate(), expectedValue: expectedValue, delta: delta) } } @@ -60,38 +60,38 @@ public func beCloseTo( private func beCloseTo( _ expectedValue: NMBDoubleConvertible, within delta: Double = DefaultDelta -) -> Matcher { - return Matcher.define { actualExpression in +) -> Predicate { + return Predicate.define { actualExpression in return isCloseTo(try actualExpression.evaluate(), expectedValue: expectedValue, delta: delta) } } #if canImport(Darwin) -public class NMBObjCBeCloseToMatcher: NMBMatcher { +public class NMBObjCBeCloseToPredicate: NMBPredicate { private let _expected: NSNumber fileprivate init(expected: NSNumber, within: CDouble) { _expected = expected - let matcher = beCloseTo(expected, within: within) - let matcherBlock: MatcherBlock = { actualExpression in + let predicate = beCloseTo(expected, within: within) + let predicateBlock: PredicateBlock = { actualExpression in let expr = actualExpression.cast { $0 as? NMBDoubleConvertible } - return try matcher.satisfies(expr).toObjectiveC() + return try predicate.satisfies(expr).toObjectiveC() } - super.init(matcher: matcherBlock) + super.init(predicate: predicateBlock) } - @objc public var within: (CDouble) -> NMBObjCBeCloseToMatcher { + @objc public var within: (CDouble) -> NMBObjCBeCloseToPredicate { let expected = _expected return { delta in - return NMBObjCBeCloseToMatcher(expected: expected, within: delta) + return NMBObjCBeCloseToPredicate(expected: expected, within: delta) } } } -extension NMBMatcher { - @objc public class func beCloseToMatcher(_ expected: NSNumber, within: CDouble) -> NMBObjCBeCloseToMatcher { - return NMBObjCBeCloseToMatcher(expected: expected, within: within) +extension NMBPredicate { + @objc public class func beCloseToMatcher(_ expected: NSNumber, within: CDouble) -> NMBObjCBeCloseToPredicate { + return NMBObjCBeCloseToPredicate(expected: expected, within: within) } } #endif @@ -99,9 +99,9 @@ extension NMBMatcher { public func beCloseTo( _ expectedValues: Values, within delta: Value = defaultDelta() -) -> Matcher where Values.Element == Value { +) -> Predicate where Values.Element == Value { let errorMessage = "be close to <\(stringify(expectedValues))> (each within \(stringify(delta)))" - return Matcher.simple(errorMessage) { actualExpression in + return Predicate.simple(errorMessage) { actualExpression in guard let actualValues = try actualExpression.evaluate() else { return .doesNotMatch } @@ -110,8 +110,10 @@ public func beCloseTo( return .doesNotMatch } - for index in actualValues.indices where abs(actualValues[index] - expectedValues[index]) > delta { - return .doesNotMatch + for index in actualValues.indices { + if abs(actualValues[index] - expectedValues[index]) > delta { + return .doesNotMatch + } } return .matches } @@ -121,61 +123,43 @@ public func beCloseTo( infix operator ≈ : ComparisonPrecedence -// swiftlint:disable identifier_name -public func ≈ (lhs: SyncExpectation, rhs: Value) where Value: Collection, Value.Element: FloatingPoint { - lhs.to(beCloseTo(rhs)) -} - -public func ≈ (lhs: AsyncExpectation, rhs: Value) async where Value: Collection, Value.Element: FloatingPoint { - await lhs.to(beCloseTo(rhs)) -} - -public func ≈ (lhs: SyncExpectation, rhs: Value) { - lhs.to(beCloseTo(rhs)) -} - -public func ≈ (lhs: AsyncExpectation, rhs: Value) async { - await lhs.to(beCloseTo(rhs)) -} - -public func ≈ (lhs: SyncExpectation, rhs: (expected: Value, delta: Value)) { - lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) -} - -public func ≈ (lhs: AsyncExpectation, rhs: (expected: Value, delta: Value)) async { - await lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) -} - -public func == (lhs: SyncExpectation, rhs: (expected: Value, delta: Value)) { - lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) -} - -public func == (lhs: AsyncExpectation, rhs: (expected: Value, delta: Value)) async { - await lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) +extension Expectation where T: Collection, T.Element: FloatingPoint { + // swiftlint:disable:next identifier_name + public static func ≈(lhs: Expectation, rhs: T) { + lhs.to(beCloseTo(rhs)) + } } -public func ≈ (lhs: SyncExpectation, rhs: Value) { - lhs.to(beCloseTo(rhs)) -} +extension Expectation where T: FloatingPoint { + // swiftlint:disable:next identifier_name + public static func ≈(lhs: Expectation, rhs: T) { + lhs.to(beCloseTo(rhs)) + } -public func ≈ (lhs: AsyncExpectation, rhs: Value) async { - await lhs.to(beCloseTo(rhs)) -} + // swiftlint:disable:next identifier_name + public static func ≈(lhs: Expectation, rhs: (expected: T, delta: T)) { + lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) + } -public func ≈ (lhs: SyncExpectation, rhs: (expected: Value, delta: Double)) { - lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) + public static func == (lhs: Expectation, rhs: (expected: T, delta: T)) { + lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) + } } -public func ≈ (lhs: AsyncExpectation, rhs: (expected: Value, delta: Double)) async { - await lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) -} +extension Expectation where T: NMBDoubleConvertible { + // swiftlint:disable:next identifier_name + public static func ≈(lhs: Expectation, rhs: T) { + lhs.to(beCloseTo(rhs)) + } -public func == (lhs: SyncExpectation, rhs: (expected: Value, delta: Double)) { - lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) -} + // swiftlint:disable:next identifier_name + public static func ≈(lhs: Expectation, rhs: (expected: T, delta: Double)) { + lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) + } -public func == (lhs: AsyncExpectation, rhs: (expected: Value, delta: Double)) async { - await lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) + public static func == (lhs: Expectation, rhs: (expected: T, delta: Double)) { + lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) + } } // make this higher precedence than exponents so the Doubles either end aren't pulled in @@ -185,11 +169,11 @@ precedencegroup PlusMinusOperatorPrecedence { } infix operator ± : PlusMinusOperatorPrecedence -public func ± (lhs: Value, rhs: Value) -> (expected: Value, delta: Value) { +// swiftlint:disable:next identifier_name +public func ±(lhs: Value, rhs: Value) -> (expected: Value, delta: Value) { return (expected: lhs, delta: rhs) } -public func ± (lhs: Value, rhs: Double) -> (expected: Value, delta: Double) { +// swiftlint:disable:next identifier_name +public func ±(lhs: Value, rhs: Double) -> (expected: Value, delta: Double) { return (expected: lhs, delta: rhs) } - -// swiftlint:enable identifier_name diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeEmpty.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeEmpty.swift index 571797c..4036471 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeEmpty.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeEmpty.swift @@ -2,48 +2,48 @@ import Foundation /// A Nimble matcher that succeeds when a value is "empty". For collections, this /// means the are no items in that collection. For strings, it is an empty string. -public func beEmpty() -> Matcher { - return Matcher.simple("be empty") { actualExpression in +public func beEmpty() -> Predicate { + return Predicate.simple("be empty") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } var generator = actual.makeIterator() - return MatcherStatus(bool: generator.next() == nil) + return PredicateStatus(bool: generator.next() == nil) } } /// A Nimble matcher that succeeds when a value is "empty". For collections, this /// means the are no items in that collection. For strings, it is an empty string. -public func beEmpty() -> Matcher { - return Matcher.simple("be empty") { actualExpression in +public func beEmpty() -> Predicate { + return Predicate.simple("be empty") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } - return MatcherStatus(bool: actual.isEmpty) + return PredicateStatus(bool: actual.isEmpty) } } /// A Nimble matcher that succeeds when a value is "empty". For collections, this /// means the are no items in that collection. For strings, it is an empty string. -public func beEmpty() -> Matcher { - return Matcher.simple("be empty") { actualExpression in +public func beEmpty() -> Predicate { + return Predicate.simple("be empty") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } - return MatcherStatus(bool: actual.isEmpty) + return PredicateStatus(bool: actual.isEmpty) } } /// A Nimble matcher that succeeds when a value is "empty". For collections, this /// means the are no items in that collection. For strings, it is an empty string. -public func beEmpty() -> Matcher { - return Matcher.simple("be empty") { actualExpression in +public func beEmpty() -> Predicate { + return Predicate.simple("be empty") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } - return MatcherStatus(bool: actual.isEmpty) + return PredicateStatus(bool: actual.isEmpty) } } /// A Nimble matcher that succeeds when a value is "empty". For collections, this /// means the are no items in that collection. For NSString instances, it is an empty string. -public func beEmpty() -> Matcher { - return Matcher.simple("be empty") { actualExpression in +public func beEmpty() -> Predicate { + return Predicate.simple("be empty") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } - return MatcherStatus(bool: actual.length == 0) + return PredicateStatus(bool: actual.length == 0) } } @@ -52,35 +52,35 @@ public func beEmpty() -> Matcher { /// A Nimble matcher that succeeds when a value is "empty". For collections, this /// means the are no items in that collection. For strings, it is an empty string. -public func beEmpty() -> Matcher { - return Matcher.simple("be empty") { actualExpression in +public func beEmpty() -> Predicate { + return Predicate.simple("be empty") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } - return MatcherStatus(bool: actual.count == 0) + return PredicateStatus(bool: actual.count == 0) } } /// A Nimble matcher that succeeds when a value is "empty". For collections, this /// means the are no items in that collection. For strings, it is an empty string. -public func beEmpty() -> Matcher { - return Matcher.simple("be empty") { actualExpression in +public func beEmpty() -> Predicate { + return Predicate.simple("be empty") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } - return MatcherStatus(bool: actual.count == 0) + return PredicateStatus(bool: actual.count == 0) } } /// A Nimble matcher that succeeds when a value is "empty". For collections, this /// means the are no items in that collection. For strings, it is an empty string. -public func beEmpty() -> Matcher { - return Matcher.simple("be empty") { actualExpression in +public func beEmpty() -> Predicate { + return Predicate.simple("be empty") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } - return MatcherStatus(bool: actual.count == 0) + return PredicateStatus(bool: actual.count == 0) } } #if canImport(Darwin) -extension NMBMatcher { - @objc public class func beEmptyMatcher() -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beEmptyMatcher() -> NMBPredicate { + return NMBPredicate { actualExpression in let location = actualExpression.location let actualValue = try actualExpression.evaluate() @@ -92,16 +92,16 @@ extension NMBMatcher { return try beEmpty().satisfies(expr).toObjectiveC() } else if let actualValue = actualValue { let badTypeErrorMsg = "be empty (only works for NSArrays, NSSets, NSIndexSets, NSDictionaries, NSHashTables, and NSStrings)" - return NMBMatcherResult( - status: NMBMatcherStatus.fail, + return NMBPredicateResult( + status: NMBPredicateStatus.fail, message: NMBExpectationMessage( expectedActualValueTo: badTypeErrorMsg, customActualValue: "\(String(describing: type(of: actualValue))) type" ) ) } - return NMBMatcherResult( - status: NMBMatcherStatus.fail, + return NMBPredicateResult( + status: NMBPredicateStatus.fail, message: NMBExpectationMessage(expectedActualValueTo: "be empty").appendedBeNilHint() ) } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThan.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThan.swift index dc96d58..a8d1212 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThan.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThan.swift @@ -1,46 +1,38 @@ /// A Nimble matcher that succeeds when the actual value is greater than the expected value. -public func beGreaterThan(_ expectedValue: T?) -> Matcher { +public func beGreaterThan(_ expectedValue: T?) -> Predicate { let errorMessage = "be greater than <\(stringify(expectedValue))>" - return Matcher.simple(errorMessage) { actualExpression in + return Predicate.simple(errorMessage) { actualExpression in guard let actual = try actualExpression.evaluate(), let expected = expectedValue else { return .fail } - return MatcherStatus(bool: actual > expected) + return PredicateStatus(bool: actual > expected) } } -public func > (lhs: SyncExpectation, rhs: T) { +public func >(lhs: Expectation, rhs: T) { lhs.to(beGreaterThan(rhs)) } -public func > (lhs: AsyncExpectation, rhs: T) async { - await lhs.to(beGreaterThan(rhs)) -} - #if canImport(Darwin) import enum Foundation.ComparisonResult /// A Nimble matcher that succeeds when the actual value is greater than the expected value. -public func beGreaterThan(_ expectedValue: T?) -> Matcher { +public func beGreaterThan(_ expectedValue: NMBComparable?) -> Predicate { let errorMessage = "be greater than <\(stringify(expectedValue))>" - return Matcher.simple(errorMessage) { actualExpression in + return Predicate.simple(errorMessage) { actualExpression in let actualValue = try actualExpression.evaluate() let matches = actualValue != nil && actualValue!.NMB_compare(expectedValue) == ComparisonResult.orderedDescending - return MatcherStatus(bool: matches) + return PredicateStatus(bool: matches) } } -public func > (lhs: SyncExpectation, rhs: T?) { +public func > (lhs: Expectation, rhs: NMBComparable?) { lhs.to(beGreaterThan(rhs)) } -public func > (lhs: AsyncExpectation, rhs: T?) async { - await lhs.to(beGreaterThan(rhs)) -} - -extension NMBMatcher { - @objc public class func beGreaterThanMatcher(_ expected: NMBComparable?) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beGreaterThanMatcher(_ expected: NMBComparable?) -> NMBPredicate { + return NMBPredicate { actualExpression in let expr = actualExpression.cast { $0 as? NMBComparable } return try beGreaterThan(expected).satisfies(expr).toObjectiveC() } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThanOrEqualTo.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThanOrEqualTo.swift index 14821de..affa58c 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThanOrEqualTo.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThanOrEqualTo.swift @@ -1,47 +1,39 @@ /// A Nimble matcher that succeeds when the actual value is greater than /// or equal to the expected value. -public func beGreaterThanOrEqualTo(_ expectedValue: T?) -> Matcher { +public func beGreaterThanOrEqualTo(_ expectedValue: T?) -> Predicate { let message = "be greater than or equal to <\(stringify(expectedValue))>" - return Matcher.simple(message) { actualExpression in + return Predicate.simple(message) { actualExpression in guard let actual = try actualExpression.evaluate(), let expected = expectedValue else { return .fail } - return MatcherStatus(bool: actual >= expected) + return PredicateStatus(bool: actual >= expected) } } -public func >= (lhs: SyncExpectation, rhs: T) { +public func >=(lhs: Expectation, rhs: T) { lhs.to(beGreaterThanOrEqualTo(rhs)) } -public func >= (lhs: AsyncExpectation, rhs: T) async { - await lhs.to(beGreaterThanOrEqualTo(rhs)) -} - #if canImport(Darwin) import enum Foundation.ComparisonResult /// A Nimble matcher that succeeds when the actual value is greater than /// or equal to the expected value. -public func beGreaterThanOrEqualTo(_ expectedValue: T?) -> Matcher { +public func beGreaterThanOrEqualTo(_ expectedValue: T?) -> Predicate { let message = "be greater than or equal to <\(stringify(expectedValue))>" - return Matcher.simple(message) { actualExpression in + return Predicate.simple(message) { actualExpression in let actualValue = try actualExpression.evaluate() let matches = actualValue != nil && actualValue!.NMB_compare(expectedValue) != ComparisonResult.orderedAscending - return MatcherStatus(bool: matches) + return PredicateStatus(bool: matches) } } -public func >= (lhs: SyncExpectation, rhs: T) { +public func >=(lhs: Expectation, rhs: T) { lhs.to(beGreaterThanOrEqualTo(rhs)) } -public func >= (lhs: AsyncExpectation, rhs: T) async { - await lhs.to(beGreaterThanOrEqualTo(rhs)) -} - -extension NMBMatcher { - @objc public class func beGreaterThanOrEqualToMatcher(_ expected: NMBComparable?) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beGreaterThanOrEqualToMatcher(_ expected: NMBComparable?) -> NMBPredicate { + return NMBPredicate { actualExpression in let expr = actualExpression.cast { $0 as? NMBComparable } return try beGreaterThanOrEqualTo(expected).satisfies(expr).toObjectiveC() } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeIdenticalTo.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeIdenticalTo.swift index 3f00b18..f3db774 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeIdenticalTo.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeIdenticalTo.swift @@ -1,11 +1,11 @@ /// A Nimble matcher that succeeds when the actual value is the same instance /// as the expected instance. -public func beIdenticalTo(_ expected: AnyObject?) -> Matcher { - return Matcher.define { actualExpression in +public func beIdenticalTo(_ expected: AnyObject?) -> Predicate { + return Predicate.define { actualExpression in let actual = try actualExpression.evaluate() let bool = actual === expected && actual !== nil - return MatcherResult( + return PredicateResult( bool: bool, message: .expectedCustomValueTo( "be identical to \(identityAsString(expected))", @@ -15,36 +15,30 @@ public func beIdenticalTo(_ expected: AnyObject?) -> Matcher { } } -public func === (lhs: SyncExpectation, rhs: AnyObject?) { - lhs.to(beIdenticalTo(rhs)) -} - -public func === (lhs: AsyncExpectation, rhs: AnyObject?) async { - await lhs.to(beIdenticalTo(rhs)) -} - -public func !== (lhs: SyncExpectation, rhs: AnyObject?) { - lhs.toNot(beIdenticalTo(rhs)) -} +extension Expectation where T == AnyObject { + public static func === (lhs: Expectation, rhs: AnyObject?) { + lhs.to(beIdenticalTo(rhs)) + } -public func !== (lhs: AsyncExpectation, rhs: AnyObject?) async { - await lhs.toNot(beIdenticalTo(rhs)) + public static func !== (lhs: Expectation, rhs: AnyObject?) { + lhs.toNot(beIdenticalTo(rhs)) + } } /// A Nimble matcher that succeeds when the actual value is the same instance /// as the expected instance. /// /// Alias for "beIdenticalTo". -public func be(_ expected: AnyObject?) -> Matcher { +public func be(_ expected: AnyObject?) -> Predicate { return beIdenticalTo(expected) } #if canImport(Darwin) import class Foundation.NSObject -extension NMBMatcher { - @objc public class func beIdenticalToMatcher(_ expected: NSObject?) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beIdenticalToMatcher(_ expected: NSObject?) -> NMBPredicate { + return NMBPredicate { actualExpression in let aExpr = actualExpression.cast { $0 as AnyObject? } return try beIdenticalTo(expected).satisfies(aExpr).toObjectiveC() } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeLessThan.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeLessThan.swift index 4be83c9..256f3a6 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeLessThan.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeLessThan.swift @@ -1,45 +1,37 @@ /// A Nimble matcher that succeeds when the actual value is less than the expected value. -public func beLessThan(_ expectedValue: T?) -> Matcher { +public func beLessThan(_ expectedValue: T?) -> Predicate { let message = "be less than <\(stringify(expectedValue))>" - return Matcher.simple(message) { actualExpression in + return Predicate.simple(message) { actualExpression in guard let actual = try actualExpression.evaluate(), let expected = expectedValue else { return .fail } - return MatcherStatus(bool: actual < expected) + return PredicateStatus(bool: actual < expected) } } -public func < (lhs: SyncExpectation, rhs: V) { +public func <(lhs: Expectation, rhs: T) { lhs.to(beLessThan(rhs)) } -public func < (lhs: AsyncExpectation, rhs: V) async { - await lhs.to(beLessThan(rhs)) -} - #if canImport(Darwin) import enum Foundation.ComparisonResult /// A Nimble matcher that succeeds when the actual value is less than the expected value. -public func beLessThan(_ expectedValue: T?) -> Matcher { +public func beLessThan(_ expectedValue: NMBComparable?) -> Predicate { let message = "be less than <\(stringify(expectedValue))>" - return Matcher.simple(message) { actualExpression in + return Predicate.simple(message) { actualExpression in let actualValue = try actualExpression.evaluate() let matches = actualValue != nil && actualValue!.NMB_compare(expectedValue) == ComparisonResult.orderedAscending - return MatcherStatus(bool: matches) + return PredicateStatus(bool: matches) } } -public func < (lhs: SyncExpectation, rhs: V?) { +public func < (lhs: Expectation, rhs: NMBComparable?) { lhs.to(beLessThan(rhs)) } -public func < (lhs: AsyncExpectation, rhs: V?) async { - await lhs.to(beLessThan(rhs)) -} - -extension NMBMatcher { - @objc public class func beLessThanMatcher(_ expected: NMBComparable?) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beLessThanMatcher(_ expected: NMBComparable?) -> NMBPredicate { + return NMBPredicate { actualExpression in let expr = actualExpression.cast { $0 as? NMBComparable } return try beLessThan(expected).satisfies(expr).toObjectiveC() } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeLessThanOrEqual.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeLessThanOrEqual.swift index 830e9e6..6174be5 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeLessThanOrEqual.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeLessThanOrEqual.swift @@ -1,45 +1,37 @@ /// A Nimble matcher that succeeds when the actual value is less than /// or equal to the expected value. -public func beLessThanOrEqualTo(_ expectedValue: T?) -> Matcher { - return Matcher.simple("be less than or equal to <\(stringify(expectedValue))>") { actualExpression in +public func beLessThanOrEqualTo(_ expectedValue: T?) -> Predicate { + return Predicate.simple("be less than or equal to <\(stringify(expectedValue))>") { actualExpression in guard let actual = try actualExpression.evaluate(), let expected = expectedValue else { return .fail } - return MatcherStatus(bool: actual <= expected) + return PredicateStatus(bool: actual <= expected) } } -public func <= (lhs: SyncExpectation, rhs: T) { +public func <=(lhs: Expectation, rhs: T) { lhs.to(beLessThanOrEqualTo(rhs)) } -public func <= (lhs: AsyncExpectation, rhs: T) async { - await lhs.to(beLessThanOrEqualTo(rhs)) -} - #if canImport(Darwin) import enum Foundation.ComparisonResult /// A Nimble matcher that succeeds when the actual value is less than /// or equal to the expected value. -public func beLessThanOrEqualTo(_ expectedValue: T?) -> Matcher { - return Matcher.simple("be less than or equal to <\(stringify(expectedValue))>") { actualExpression in +public func beLessThanOrEqualTo(_ expectedValue: T?) -> Predicate { + return Predicate.simple("be less than or equal to <\(stringify(expectedValue))>") { actualExpression in let actualValue = try actualExpression.evaluate() let matches = actualValue.map { $0.NMB_compare(expectedValue) != .orderedDescending } ?? false - return MatcherStatus(bool: matches) + return PredicateStatus(bool: matches) } } -public func <= (lhs: SyncExpectation, rhs: T) { +public func <=(lhs: Expectation, rhs: T) { lhs.to(beLessThanOrEqualTo(rhs)) } -public func <= (lhs: AsyncExpectation, rhs: T) async { - await lhs.to(beLessThanOrEqualTo(rhs)) -} - -extension NMBMatcher { - @objc public class func beLessThanOrEqualToMatcher(_ expected: NMBComparable?) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beLessThanOrEqualToMatcher(_ expected: NMBComparable?) -> NMBPredicate { + return NMBPredicate { actualExpression in let expr = actualExpression.cast { $0 as? NMBComparable } return try beLessThanOrEqualTo(expected).satisfies(expr).toObjectiveC() } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeLogical.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeLogical.swift index 5170299..a4094d5 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeLogical.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeLogical.swift @@ -72,10 +72,10 @@ extension UInt: ExpressibleByBooleanLiteral { } } -internal func rename(_ matcher: Matcher, failureMessage message: ExpectationMessage) -> Matcher { - return Matcher { actualExpression in +internal func rename(_ matcher: Predicate, failureMessage message: ExpectationMessage) -> Predicate { + return Predicate { actualExpression in let result = try matcher.satisfies(actualExpression) - return MatcherResult(status: result.status, message: message) + return PredicateResult(status: result.status, message: message) }.requireNonNil } @@ -83,60 +83,60 @@ internal func rename(_ matcher: Matcher, failureMessage message: Expectati /// A Nimble matcher that succeeds when the actual value is exactly true. /// This matcher will not match against nils. -public func beTrue() -> Matcher { +public func beTrue() -> Predicate { return rename(equal(true), failureMessage: .expectedActualValueTo("be true")) } /// A Nimble matcher that succeeds when the actual value is exactly false. /// This matcher will not match against nils. -public func beFalse() -> Matcher { +public func beFalse() -> Predicate { return rename(equal(false), failureMessage: .expectedActualValueTo("be false")) } // MARK: beTruthy() / beFalsy() /// A Nimble matcher that succeeds when the actual value is not logically false. -public func beTruthy() -> Matcher { - return Matcher.simpleNilable("be truthy") { actualExpression in +public func beTruthy() -> Predicate { + return Predicate.simpleNilable("be truthy") { actualExpression in let actualValue = try actualExpression.evaluate() - return MatcherStatus(bool: actualValue == (true as T)) + return PredicateStatus(bool: actualValue == (true as T)) } } /// A Nimble matcher that succeeds when the actual value is logically false. /// This matcher will match against nils. -public func beFalsy() -> Matcher { - return Matcher.simpleNilable("be falsy") { actualExpression in +public func beFalsy() -> Predicate { + return Predicate.simpleNilable("be falsy") { actualExpression in let actualValue = try actualExpression.evaluate() - return MatcherStatus(bool: actualValue != (true as T)) + return PredicateStatus(bool: actualValue != (true as T)) } } #if canImport(Darwin) -extension NMBMatcher { - @objc public class func beTruthyMatcher() -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beTruthyMatcher() -> NMBPredicate { + return NMBPredicate { actualExpression in let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } return try beTruthy().satisfies(expr).toObjectiveC() } } - @objc public class func beFalsyMatcher() -> NMBMatcher { - return NMBMatcher { actualExpression in + @objc public class func beFalsyMatcher() -> NMBPredicate { + return NMBPredicate { actualExpression in let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } return try beFalsy().satisfies(expr).toObjectiveC() } } - @objc public class func beTrueMatcher() -> NMBMatcher { - return NMBMatcher { actualExpression in + @objc public class func beTrueMatcher() -> NMBPredicate { + return NMBPredicate { actualExpression in let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } return try beTrue().satisfies(expr).toObjectiveC() } } - @objc public class func beFalseMatcher() -> NMBMatcher { - return NMBMatcher { actualExpression in + @objc public class func beFalseMatcher() -> NMBPredicate { + return NMBPredicate { actualExpression in let expr = actualExpression.cast { value -> Bool? in guard let value = value else { return nil } return (value as? NSNumber)?.boolValue ?? false diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeNil.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeNil.swift index eea1440..c87099d 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeNil.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeNil.swift @@ -8,47 +8,37 @@ extension Optional: _OptionalProtocol { } /// A Nimble matcher that succeeds when the actual value is nil. -public func beNil() -> Matcher { - return Matcher.simpleNilable("be nil") { actualExpression in +public func beNil() -> Predicate { + return Predicate.simpleNilable("be nil") { actualExpression in let actualValue = try actualExpression.evaluate() if let actual = actualValue, let nestedOptionl = actual as? _OptionalProtocol { - return MatcherStatus(bool: nestedOptionl.isNil) + return PredicateStatus(bool: nestedOptionl.isNil) } - return MatcherStatus(bool: actualValue == nil) + return PredicateStatus(bool: actualValue == nil) } } -/// Represents `nil` value to be used with the operator overloads for `beNil`. -public struct ExpectationNil: ExpressibleByNilLiteral { - public init(nilLiteral: ()) {} -} +extension Expectation { + /// Represents `nil` value to be used with the operator overloads for `beNil`. + public struct Nil: ExpressibleByNilLiteral { + public init(nilLiteral: ()) {} + } -extension SyncExpectation { - public static func == (lhs: SyncExpectation, rhs: ExpectationNil) { + public static func == (lhs: Expectation, rhs: Expectation.Nil) { lhs.to(beNil()) } - public static func != (lhs: SyncExpectation, rhs: ExpectationNil) { + public static func != (lhs: Expectation, rhs: Expectation.Nil) { lhs.toNot(beNil()) } } -extension AsyncExpectation { - public static func == (lhs: AsyncExpectation, rhs: ExpectationNil) async { - await lhs.to(beNil()) - } - - public static func != (lhs: AsyncExpectation, rhs: ExpectationNil) async { - await lhs.toNot(beNil()) - } -} - #if canImport(Darwin) import Foundation -extension NMBMatcher { - @objc public class func beNilMatcher() -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beNilMatcher() -> NMBPredicate { + return NMBPredicate { actualExpression in return try beNil().satisfies(actualExpression).toObjectiveC() } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeResult.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeResult.swift index 7f90dfc..b05db7f 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeResult.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeResult.swift @@ -6,8 +6,8 @@ import Foundation /// The closure only gets called when the result is success. public func beSuccess( test: ((Success) -> Void)? = nil -) -> Matcher> { - return Matcher.define { expression in +) -> Predicate> { + return Predicate.define { expression in var rawMessage = "be " if test != nil { rawMessage += " that satisfies block" @@ -15,7 +15,7 @@ public func beSuccess( let message = ExpectationMessage.expectedActualValueTo(rawMessage) guard case let .success(value)? = try expression.evaluate() else { - return MatcherResult(status: .doesNotMatch, message: message) + return PredicateResult(status: .doesNotMatch, message: message) } var matches = true @@ -29,7 +29,7 @@ public func beSuccess( } } - return MatcherResult(bool: matches, message: message) + return PredicateResult(bool: matches, message: message) } } @@ -39,8 +39,8 @@ public func beSuccess( /// The closure only gets called when the result is failure. public func beFailure( test: ((Failure) -> Void)? = nil -) -> Matcher> { - return Matcher.define { expression in +) -> Predicate> { + return Predicate.define { expression in var rawMessage = "be " if test != nil { rawMessage += " that satisfies block" @@ -48,7 +48,7 @@ public func beFailure( let message = ExpectationMessage.expectedActualValueTo(rawMessage) guard case let .failure(error)? = try expression.evaluate() else { - return MatcherResult(status: .doesNotMatch, message: message) + return PredicateResult(status: .doesNotMatch, message: message) } var matches = true @@ -62,6 +62,6 @@ public func beFailure( } } - return MatcherResult(bool: matches, message: message) + return PredicateResult(bool: matches, message: message) } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeVoid.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeVoid.swift index 19bf4e9..c4bbaf6 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeVoid.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeVoid.swift @@ -1,23 +1,17 @@ /// A Nimble matcher that succeeds when the actual value is Void. -public func beVoid() -> Matcher<()> { - return Matcher.simpleNilable("be void") { actualExpression in +public func beVoid() -> Predicate<()> { + return Predicate.simpleNilable("be void") { actualExpression in let actualValue: ()? = try actualExpression.evaluate() - return MatcherStatus(bool: actualValue != nil) + return PredicateStatus(bool: actualValue != nil) } } -public func == (lhs: SyncExpectation<()>, rhs: ()) { - lhs.to(beVoid()) -} - -public func == (lhs: AsyncExpectation<()>, rhs: ()) async { - await lhs.to(beVoid()) -} - -public func != (lhs: SyncExpectation<()>, rhs: ()) { - lhs.toNot(beVoid()) -} +extension Expectation where T == () { + public static func == (lhs: Expectation<()>, rhs: ()) { + lhs.to(beVoid()) + } -public func != (lhs: AsyncExpectation<()>, rhs: ()) async { - await lhs.toNot(beVoid()) + public static func != (lhs: Expectation<()>, rhs: ()) { + lhs.toNot(beVoid()) + } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeWithin.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeWithin.swift index a4e2d7c..9c56e9e 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeWithin.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeWithin.swift @@ -1,20 +1,20 @@ /// A Nimble matcher that succeeds when the actual value is within given range. -public func beWithin(_ range: Range) -> Matcher { +public func beWithin(_ range: Range) -> Predicate { let errorMessage = "be within range <(\(range.lowerBound)..<\(range.upperBound))>" - return Matcher.simple(errorMessage) { actualExpression in + return Predicate.simple(errorMessage) { actualExpression in if let actual = try actualExpression.evaluate() { - return MatcherStatus(bool: range.contains(actual)) + return PredicateStatus(bool: range.contains(actual)) } return .fail } } /// A Nimble matcher that succeeds when the actual value is within given range. -public func beWithin(_ range: ClosedRange) -> Matcher { +public func beWithin(_ range: ClosedRange) -> Predicate { let errorMessage = "be within range <(\(range.lowerBound)...\(range.upperBound))>" - return Matcher.simple(errorMessage) { actualExpression in + return Predicate.simple(errorMessage) { actualExpression in if let actual = try actualExpression.evaluate() { - return MatcherStatus(bool: range.contains(actual)) + return PredicateStatus(bool: range.contains(actual)) } return .fail } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeginWith.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeginWith.swift index 05e1b82..90b6b5d 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeginWith.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeginWith.swift @@ -2,46 +2,46 @@ import Foundation /// A Nimble matcher that succeeds when the actual sequence's first element /// is equal to the expected value. -public func beginWith(_ startingElement: S.Element) -> Matcher where S.Element: Equatable { - return Matcher.simple("begin with <\(startingElement)>") { actualExpression in +public func beginWith(_ startingElement: S.Element) -> Predicate where S.Element: Equatable { + return Predicate.simple("begin with <\(startingElement)>") { actualExpression in guard let actualValue = try actualExpression.evaluate() else { return .fail } var actualGenerator = actualValue.makeIterator() - return MatcherStatus(bool: actualGenerator.next() == startingElement) + return PredicateStatus(bool: actualGenerator.next() == startingElement) } } /// A Nimble matcher that succeeds when the actual collection's first element /// is equal to the expected object. -public func beginWith(_ startingElement: Any) -> Matcher { - return Matcher.simple("begin with <\(startingElement)>") { actualExpression in +public func beginWith(_ startingElement: Any) -> Predicate { + return Predicate.simple("begin with <\(startingElement)>") { actualExpression in guard let collection = try actualExpression.evaluate() else { return .fail } guard collection.count > 0 else { return .doesNotMatch } - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) + #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) let collectionValue = collection.object(at: 0) as AnyObject #else guard let collectionValue = collection.object(at: 0) as? NSObject else { return .fail } #endif - return MatcherStatus(bool: collectionValue.isEqual(startingElement)) + return PredicateStatus(bool: collectionValue.isEqual(startingElement)) } } /// A Nimble matcher that succeeds when the actual string contains expected substring /// where the expected substring's location is zero. -public func beginWith(_ startingSubstring: String) -> Matcher { - return Matcher.simple("begin with <\(startingSubstring)>") { actualExpression in +public func beginWith(_ startingSubstring: String) -> Predicate { + return Predicate.simple("begin with <\(startingSubstring)>") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } - return MatcherStatus(bool: actual.hasPrefix(startingSubstring)) + return PredicateStatus(bool: actual.hasPrefix(startingSubstring)) } } #if canImport(Darwin) -extension NMBMatcher { - @objc public class func beginWithMatcher(_ expected: Any) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func beginWithMatcher(_ expected: Any) -> NMBPredicate { + return NMBPredicate { actualExpression in let actual = try actualExpression.evaluate() if actual is String { let expr = actualExpression.cast { $0 as? String } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/BeginWithPrefix.swift b/Pods/Nimble/Sources/Nimble/Matchers/BeginWithPrefix.swift index 8ff068d..c3a79b1 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/BeginWithPrefix.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/BeginWithPrefix.swift @@ -2,38 +2,38 @@ /// /// This is a matcher abstraction for https://developer.apple.com/documentation/swift/sequence/2854218-starts public func beginWith(prefix expectedPrefix: Seq2?) - -> Matcher where Seq1.Element: Equatable, Seq1.Element == Seq2.Element { - return Matcher.define("begin with <\(stringify(expectedPrefix))>") { (actualExpression, msg) in + -> Predicate where Seq1.Element: Equatable, Seq1.Element == Seq2.Element { + return Predicate.define("begin with <\(stringify(expectedPrefix))>") { (actualExpression, msg) in let actualPrefix = try actualExpression.evaluate() switch (expectedPrefix, actualPrefix) { case (nil, _?): - return MatcherResult(status: .fail, message: msg.appendedBeNilHint()) + return PredicateResult(status: .fail, message: msg.appendedBeNilHint()) case (nil, nil), (_, nil): - return MatcherResult(status: .fail, message: msg) + return PredicateResult(status: .fail, message: msg) case (let expected?, let actual?): let matches = actual.starts(with: expected) - return MatcherResult(bool: matches, message: msg) + return PredicateResult(bool: matches, message: msg) } } } -/// A Nimble matcher that succeeds when the expected sequence is the prefix of the actual sequence, using the given matcher as the equivalence test. +/// A Nimble matcher that succeeds when the expected sequence is the prefix of the actual sequence, using the given predicate as the equivalence test. /// /// This is a matcher abstraction for https://developer.apple.com/documentation/swift/sequence/2996828-starts public func beginWith( prefix expectedPrefix: Seq2?, by areEquivalent: @escaping (Seq1.Element, Seq2.Element) -> Bool -) -> Matcher { - return Matcher.define("begin with <\(stringify(expectedPrefix))>") { (actualExpression, msg) in +) -> Predicate { + return Predicate.define("begin with <\(stringify(expectedPrefix))>") { (actualExpression, msg) in let actualPrefix = try actualExpression.evaluate() switch (expectedPrefix, actualPrefix) { case (nil, _?): - return MatcherResult(status: .fail, message: msg.appendedBeNilHint()) + return PredicateResult(status: .fail, message: msg.appendedBeNilHint()) case (nil, nil), (_, nil): - return MatcherResult(status: .fail, message: msg) + return PredicateResult(status: .fail, message: msg) case (let expected?, let actual?): let matches = actual.starts(with: expected, by: areEquivalent) - return MatcherResult(bool: matches, message: msg) + return PredicateResult(bool: matches, message: msg) } } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/Contain.swift b/Pods/Nimble/Sources/Nimble/Matchers/Contain.swift index 555d4d1..38d1dab 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/Contain.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/Contain.swift @@ -3,109 +3,109 @@ import Foundation #endif /// A Nimble matcher that succeeds when the actual sequence contains the expected values. -public func contain(_ items: S.Element...) -> Matcher where S.Element: Equatable { +public func contain(_ items: S.Element...) -> Predicate where S.Element: Equatable { return contain(items) } /// A Nimble matcher that succeeds when the actual sequence contains the expected values. -public func contain(_ items: [S.Element]) -> Matcher where S.Element: Equatable { - return Matcher.simple("contain <\(arrayAsString(items))>") { actualExpression in +public func contain(_ items: [S.Element]) -> Predicate where S.Element: Equatable { + return Predicate.simple("contain <\(arrayAsString(items))>") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } let matches = items.allSatisfy { return actual.contains($0) } - return MatcherStatus(bool: matches) + return PredicateStatus(bool: matches) } } /// A Nimble matcher that succeeds when the actual set contains the expected values. -public func contain(_ items: S.Element...) -> Matcher where S.Element: Equatable { +public func contain(_ items: S.Element...) -> Predicate where S.Element: Equatable { return contain(items) } /// A Nimble matcher that succeeds when the actual set contains the expected values. -public func contain(_ items: [S.Element]) -> Matcher where S.Element: Equatable { - return Matcher.simple("contain <\(arrayAsString(items))>") { actualExpression in +public func contain(_ items: [S.Element]) -> Predicate where S.Element: Equatable { + return Predicate.simple("contain <\(arrayAsString(items))>") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } let matches = items.allSatisfy { return actual.contains($0) } - return MatcherStatus(bool: matches) + return PredicateStatus(bool: matches) } } /// A Nimble matcher that succeeds when the actual set contains the expected values. -public func contain(_ items: S.Element...) -> Matcher where S.Element: Equatable { +public func contain(_ items: S.Element...) -> Predicate where S.Element: Equatable { return contain(items) } /// A Nimble matcher that succeeds when the actual set contains the expected values. -public func contain(_ items: [S.Element]) -> Matcher where S.Element: Equatable { - return Matcher.simple("contain <\(arrayAsString(items))>") { actualExpression in +public func contain(_ items: [S.Element]) -> Predicate where S.Element: Equatable { + return Predicate.simple("contain <\(arrayAsString(items))>") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } let matches = items.allSatisfy { return actual.contains($0) } - return MatcherStatus(bool: matches) + return PredicateStatus(bool: matches) } } /// A Nimble matcher that succeeds when the actual string contains the expected substring. -public func contain(_ substrings: String...) -> Matcher { +public func contain(_ substrings: String...) -> Predicate { return contain(substrings) } -public func contain(_ substrings: [String]) -> Matcher { - return Matcher.simple("contain <\(arrayAsString(substrings))>") { actualExpression in +public func contain(_ substrings: [String]) -> Predicate { + return Predicate.simple("contain <\(arrayAsString(substrings))>") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } let matches = substrings.allSatisfy { let range = actual.range(of: $0) return range != nil && !range!.isEmpty } - return MatcherStatus(bool: matches) + return PredicateStatus(bool: matches) } } #if canImport(Foundation) /// A Nimble matcher that succeeds when the actual string contains the expected substring. -public func contain(_ substrings: NSString...) -> Matcher { +public func contain(_ substrings: NSString...) -> Predicate { return contain(substrings) } -public func contain(_ substrings: [NSString]) -> Matcher { - return Matcher.simple("contain <\(arrayAsString(substrings))>") { actualExpression in +public func contain(_ substrings: [NSString]) -> Predicate { + return Predicate.simple("contain <\(arrayAsString(substrings))>") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } let matches = substrings.allSatisfy { actual.range(of: $0.description).length != 0 } - return MatcherStatus(bool: matches) + return PredicateStatus(bool: matches) } } #endif /// A Nimble matcher that succeeds when the actual collection contains the expected object. -public func contain(_ items: Any?...) -> Matcher { +public func contain(_ items: Any?...) -> Predicate { return contain(items) } -public func contain(_ items: [Any?]) -> Matcher { - return Matcher.simple("contain <\(arrayAsString(items))>") { actualExpression in +public func contain(_ items: [Any?]) -> Predicate { + return Predicate.simple("contain <\(arrayAsString(items))>") { actualExpression in guard let actual = try actualExpression.evaluate() else { return .fail } let matches = items.allSatisfy { item in return item.map { actual.contains($0) } ?? false } - return MatcherStatus(bool: matches) + return PredicateStatus(bool: matches) } } #if canImport(Darwin) -extension NMBMatcher { - @objc public class func containMatcher(_ expected: [NSObject]) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func containMatcher(_ expected: [NSObject]) -> NMBPredicate { + return NMBPredicate { actualExpression in let location = actualExpression.location let actualValue = try actualExpression.evaluate() if let value = actualValue as? NMBContainer { @@ -130,7 +130,7 @@ extension NMBMatcher { .expectedActualValueTo("contain <\(arrayAsString(expected))>") .appendedBeNilHint() } - return NMBMatcherResult(status: .fail, message: message.toObjectiveC()) + return NMBPredicateResult(status: .fail, message: message.toObjectiveC()) } } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/ContainElementSatisfying.swift b/Pods/Nimble/Sources/Nimble/Matchers/ContainElementSatisfying.swift index 68cc753..2e7875b 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/ContainElementSatisfying.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/ContainElementSatisfying.swift @@ -1,46 +1,25 @@ public func containElementSatisfying( - _ matcher: @escaping ((S.Element) -> Bool), _ matcherDescription: String = "" -) -> Matcher { - return Matcher.define { actualExpression in + _ predicate: @escaping ((S.Element) -> Bool), _ predicateDescription: String = "" +) -> Predicate { + return Predicate.define { actualExpression in let message: ExpectationMessage - if matcherDescription == "" { - message = .expectedTo("find object in collection that satisfies matcher") + if predicateDescription == "" { + message = .expectedTo("find object in collection that satisfies predicate") } else { - message = .expectedTo("find object in collection \(matcherDescription)") + message = .expectedTo("find object in collection \(predicateDescription)") } if let sequence = try actualExpression.evaluate() { - for object in sequence where matcher(object) { - return MatcherResult(bool: true, message: message) - } - - return MatcherResult(bool: false, message: message) - } - - return MatcherResult(status: .fail, message: message) - } -} - -public func containElementSatisfying( - _ matcher: @escaping ((S.Element) async -> Bool), _ matcherDescription: String = "" -) -> AsyncMatcher { - return AsyncMatcher.define { actualExpression in - let message: ExpectationMessage - if matcherDescription == "" { - message = .expectedTo("find object in collection that satisfies matcher") - } else { - message = .expectedTo("find object in collection \(matcherDescription)") - } - - if let sequence = try await actualExpression.evaluate() { - for object in sequence where await matcher(object) { - return MatcherResult(bool: true, message: message) + for object in sequence { + if predicate(object) { + return PredicateResult(bool: true, message: message) + } } - return MatcherResult(bool: false, message: message) + return PredicateResult(bool: false, message: message) } - return MatcherResult(status: .fail, message: message) + return PredicateResult(status: .fail, message: message) } } @@ -49,19 +28,19 @@ import class Foundation.NSObject import struct Foundation.NSFastEnumerationIterator import protocol Foundation.NSFastEnumeration -extension NMBMatcher { - @objc public class func containElementSatisfyingMatcher(_ matcher: @escaping ((NSObject) -> Bool)) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func containElementSatisfyingMatcher(_ predicate: @escaping ((NSObject) -> Bool)) -> NMBPredicate { + return NMBPredicate { actualExpression in let value = try actualExpression.evaluate() guard let enumeration = value as? NSFastEnumeration else { let message = ExpectationMessage.fail( "containElementSatisfying must be provided an NSFastEnumeration object" ) - return NMBMatcherResult(status: .fail, message: message.toObjectiveC()) + return NMBPredicateResult(status: .fail, message: message.toObjectiveC()) } let message = ExpectationMessage - .expectedTo("find object in collection that satisfies matcher") + .expectedTo("find object in collection that satisfies predicate") .toObjectiveC() var iterator = NSFastEnumerationIterator(enumeration) @@ -70,12 +49,12 @@ extension NMBMatcher { continue } - if matcher(object) { - return NMBMatcherResult(status: .matches, message: message) + if predicate(object) { + return NMBPredicateResult(status: .matches, message: message) } } - return NMBMatcherResult(status: .doesNotMatch, message: message) + return NMBPredicateResult(status: .doesNotMatch, message: message) } } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/ElementsEqual.swift b/Pods/Nimble/Sources/Nimble/Matchers/ElementsEqual.swift index 39b2dbf..708cf1c 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/ElementsEqual.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/ElementsEqual.swift @@ -4,39 +4,39 @@ /// This is a matcher abstraction for https://developer.apple.com/documentation/swift/sequence/2854213-elementsequal public func elementsEqual( _ expectedValue: Seq2? -) -> Matcher where Seq1.Element: Equatable, Seq1.Element == Seq2.Element { - return Matcher.define("elementsEqual <\(stringify(expectedValue))>") { (actualExpression, msg) in +) -> Predicate where Seq1.Element: Equatable, Seq1.Element == Seq2.Element { + return Predicate.define("elementsEqual <\(stringify(expectedValue))>") { (actualExpression, msg) in let actualValue = try actualExpression.evaluate() switch (expectedValue, actualValue) { case (nil, _?): - return MatcherResult(status: .fail, message: msg.appendedBeNilHint()) + return PredicateResult(status: .fail, message: msg.appendedBeNilHint()) case (nil, nil), (_, nil): - return MatcherResult(status: .fail, message: msg) + return PredicateResult(status: .fail, message: msg) case (let expected?, let actual?): let matches = expected.elementsEqual(actual) - return MatcherResult(bool: matches, message: msg) + return PredicateResult(bool: matches, message: msg) } } } /// A Nimble matcher that succeeds when the actual sequence and the exepected sequence contain equivalent elements in -/// the same order, using the given matcher as the equivalence test. +/// the same order, using the given predicate as the equivalence test. /// /// This is a matcher abstraction for https://developer.apple.com/documentation/swift/sequence/2949668-elementsequal public func elementsEqual( _ expectedValue: Seq2?, by areEquivalent: @escaping (Seq1.Element, Seq2.Element) -> Bool -) -> Matcher { - return Matcher.define("elementsEqual <\(stringify(expectedValue))>") { (actualExpression, msg) in +) -> Predicate { + return Predicate.define("elementsEqual <\(stringify(expectedValue))>") { (actualExpression, msg) in let actualValue = try actualExpression.evaluate() switch (expectedValue, actualValue) { case (nil, _?): - return MatcherResult(status: .fail, message: msg.appendedBeNilHint()) + return PredicateResult(status: .fail, message: msg.appendedBeNilHint()) case (nil, nil), (_, nil): - return MatcherResult(status: .fail, message: msg) + return PredicateResult(status: .fail, message: msg) case (let expected?, let actual?): let matches = actual.elementsEqual(expected, by: areEquivalent) - return MatcherResult(bool: matches, message: msg) + return PredicateResult(bool: matches, message: msg) } } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/EndWith.swift b/Pods/Nimble/Sources/Nimble/Matchers/EndWith.swift index 0b61da9..950d9d5 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/EndWith.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/EndWith.swift @@ -2,8 +2,8 @@ import Foundation /// A Nimble matcher that succeeds when the actual sequence's last element /// is equal to the expected value. -public func endWith(_ endingElement: S.Element) -> Matcher where S.Element: Equatable { - return Matcher.simple("end with <\(endingElement)>") { actualExpression in +public func endWith(_ endingElement: S.Element) -> Predicate where S.Element: Equatable { + return Predicate.simple("end with <\(endingElement)>") { actualExpression in guard let actualValue = try actualExpression.evaluate() else { return .fail } var actualGenerator = actualValue.makeIterator() @@ -14,18 +14,18 @@ public func endWith(_ endingElement: S.Element) -> Matcher where item = actualGenerator.next() } while(item != nil) - return MatcherStatus(bool: lastItem == endingElement) + return PredicateStatus(bool: lastItem == endingElement) } } /// A Nimble matcher that succeeds when the actual collection's last element /// is equal to the expected object. -public func endWith(_ endingElement: Any) -> Matcher { - return Matcher.simple("end with <\(endingElement)>") { actualExpression in +public func endWith(_ endingElement: Any) -> Predicate { + return Predicate.simple("end with <\(endingElement)>") { actualExpression in guard let collection = try actualExpression.evaluate() else { return .fail } - guard collection.count > 0 else { return MatcherStatus(bool: false) } - #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) + guard collection.count > 0 else { return PredicateStatus(bool: false) } + #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) let collectionValue = collection.object(at: collection.count - 1) as AnyObject #else guard let collectionValue = collection.object(at: collection.count - 1) as? NSObject else { @@ -33,25 +33,25 @@ public func endWith(_ endingElement: Any) -> Matcher { } #endif - return MatcherStatus(bool: collectionValue.isEqual(endingElement)) + return PredicateStatus(bool: collectionValue.isEqual(endingElement)) } } /// A Nimble matcher that succeeds when the actual string contains the expected substring /// where the expected substring's location is the actual string's length minus the /// expected substring's length. -public func endWith(_ endingSubstring: String) -> Matcher { - return Matcher.simple("end with <\(endingSubstring)>") { actualExpression in +public func endWith(_ endingSubstring: String) -> Predicate { + return Predicate.simple("end with <\(endingSubstring)>") { actualExpression in guard let collection = try actualExpression.evaluate() else { return .fail } - return MatcherStatus(bool: collection.hasSuffix(endingSubstring)) + return PredicateStatus(bool: collection.hasSuffix(endingSubstring)) } } #if canImport(Darwin) -extension NMBMatcher { - @objc public class func endWithMatcher(_ expected: Any) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func endWithMatcher(_ expected: Any) -> NMBPredicate { + return NMBPredicate { actualExpression in let actual = try actualExpression.evaluate() if actual is String { let expr = actualExpression.cast { $0 as? String } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/Equal+Tuple.swift b/Pods/Nimble/Sources/Nimble/Matchers/Equal+Tuple.swift index 17b2f2e..0d05ba9 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/Equal+Tuple.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/Equal+Tuple.swift @@ -6,37 +6,24 @@ /// Values can support equal by supporting the Equatable protocol. public func equal( _ expectedValue: (T1, T2)? -) -> Matcher<(T1, T2)> { +) -> Predicate<(T1, T2)> { equal(expectedValue, by: ==) } -public func == ( - lhs: SyncExpectation<(T1, T2)>, +public func ==( + lhs: Expectation<(T1, T2)>, rhs: (T1, T2)? ) { lhs.to(equal(rhs)) } -public func == ( - lhs: AsyncExpectation<(T1, T2)>, - rhs: (T1, T2)? -) async { - await lhs.to(equal(rhs)) -} - -public func != ( - lhs: SyncExpectation<(T1, T2)>, +public func !=( + lhs: Expectation<(T1, T2)>, rhs: (T1, T2)? ) { lhs.toNot(equal(rhs)) } -public func != ( - lhs: AsyncExpectation<(T1, T2)>, - rhs: (T1, T2)? -) async { - await lhs.toNot(equal(rhs)) -} // MARK: Tuple3 @@ -44,39 +31,24 @@ public func != ( /// Values can support equal by supporting the Equatable protocol. public func equal( _ expectedValue: (T1, T2, T3)? -) -> Matcher<(T1, T2, T3)> { +) -> Predicate<(T1, T2, T3)> { equal(expectedValue, by: ==) } -public func == ( - lhs: SyncExpectation<(T1, T2, T3)>, +public func ==( + lhs: Expectation<(T1, T2, T3)>, rhs: (T1, T2, T3)? ) { lhs.to(equal(rhs)) } -public func == ( - lhs: AsyncExpectation<(T1, T2, T3)>, - rhs: (T1, T2, T3)? -) async { - await lhs.to(equal(rhs)) -} - - -public func != ( - lhs: SyncExpectation<(T1, T2, T3)>, +public func !=( + lhs: Expectation<(T1, T2, T3)>, rhs: (T1, T2, T3)? ) { lhs.toNot(equal(rhs)) } -public func != ( - lhs: AsyncExpectation<(T1, T2, T3)>, - rhs: (T1, T2, T3)? -) async { - await lhs.toNot(equal(rhs)) -} - // MARK: Tuple4 @@ -84,38 +56,24 @@ public func != ( /// Values can support equal by supporting the Equatable protocol. public func equal( _ expectedValue: (T1, T2, T3, T4)? -) -> Matcher<(T1, T2, T3, T4)> { +) -> Predicate<(T1, T2, T3, T4)> { equal(expectedValue, by: ==) } -public func == ( - lhs: SyncExpectation<(T1, T2, T3, T4)>, +public func ==( + lhs: Expectation<(T1, T2, T3, T4)>, rhs: (T1, T2, T3, T4)? ) { lhs.to(equal(rhs)) } -public func == ( - lhs: AsyncExpectation<(T1, T2, T3, T4)>, - rhs: (T1, T2, T3, T4)? -) async { - await lhs.to(equal(rhs)) -} - -public func != ( - lhs: SyncExpectation<(T1, T2, T3, T4)>, +public func !=( + lhs: Expectation<(T1, T2, T3, T4)>, rhs: (T1, T2, T3, T4)? ) { lhs.toNot(equal(rhs)) } -public func != ( - lhs: AsyncExpectation<(T1, T2, T3, T4)>, - rhs: (T1, T2, T3, T4)? -) async { - await lhs.toNot(equal(rhs)) -} - // MARK: Tuple5 @@ -123,39 +81,24 @@ public func != ( /// Values can support equal by supporting the Equatable protocol. public func equal( _ expectedValue: (T1, T2, T3, T4, T5)? -) -> Matcher<(T1, T2, T3, T4, T5)> { +) -> Predicate<(T1, T2, T3, T4, T5)> { equal(expectedValue, by: ==) } -public func == ( - lhs: SyncExpectation<(T1, T2, T3, T4, T5)>, +public func ==( + lhs: Expectation<(T1, T2, T3, T4, T5)>, rhs: (T1, T2, T3, T4, T5)? ) { lhs.to(equal(rhs)) } -public func == ( - lhs: AsyncExpectation<(T1, T2, T3, T4, T5)>, - rhs: (T1, T2, T3, T4, T5)? -) async { - await lhs.to(equal(rhs)) -} - - -public func != ( - lhs: SyncExpectation<(T1, T2, T3, T4, T5)>, +public func !=( + lhs: Expectation<(T1, T2, T3, T4, T5)>, rhs: (T1, T2, T3, T4, T5)? ) { lhs.toNot(equal(rhs)) } -public func != ( - lhs: AsyncExpectation<(T1, T2, T3, T4, T5)>, - rhs: (T1, T2, T3, T4, T5)? -) async { - await lhs.toNot(equal(rhs)) -} - // MARK: Tuple6 @@ -163,36 +106,22 @@ public func != ( _ expectedValue: (T1, T2, T3, T4, T5, T6)? -) -> Matcher<(T1, T2, T3, T4, T5, T6)> { +) -> Predicate<(T1, T2, T3, T4, T5, T6)> { equal(expectedValue, by: ==) } -public func == ( - lhs: SyncExpectation<(T1, T2, T3, T4, T5, T6)>, +public func ==( + lhs: Expectation<(T1, T2, T3, T4, T5, T6)>, rhs: (T1, T2, T3, T4, T5, T6)? ) { lhs.to(equal(rhs)) } -public func == ( - lhs: AsyncExpectation<(T1, T2, T3, T4, T5, T6)>, - rhs: (T1, T2, T3, T4, T5, T6)? -) async { - await lhs.to(equal(rhs)) -} - -public func != ( - lhs: SyncExpectation<(T1, T2, T3, T4, T5, T6)>, +public func !=( + lhs: Expectation<(T1, T2, T3, T4, T5, T6)>, rhs: (T1, T2, T3, T4, T5, T6)? ) { lhs.toNot(equal(rhs)) } -public func != ( - lhs: AsyncExpectation<(T1, T2, T3, T4, T5, T6)>, - rhs: (T1, T2, T3, T4, T5, T6)? -) async { - await lhs.toNot(equal(rhs)) -} - // swiftlint:enable large_tuple vertical_whitespace diff --git a/Pods/Nimble/Sources/Nimble/Matchers/Equal.swift b/Pods/Nimble/Sources/Nimble/Matchers/Equal.swift index 4ec21e3..7b89860 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/Equal.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/Equal.swift @@ -1,17 +1,17 @@ internal func equal( _ expectedValue: T?, by areEquivalent: @escaping (T, T) -> Bool -) -> Matcher { - Matcher.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in +) -> Predicate { + Predicate.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in let actualValue = try actualExpression.evaluate() switch (expectedValue, actualValue) { case (nil, _?): - return MatcherResult(status: .fail, message: msg.appendedBeNilHint()) + return PredicateResult(status: .fail, message: msg.appendedBeNilHint()) case (_, nil): - return MatcherResult(status: .fail, message: msg) + return PredicateResult(status: .fail, message: msg) case (let expected?, let actual?): let matches = areEquivalent(expected, actual) - return MatcherResult(bool: matches, message: msg) + return PredicateResult(bool: matches, message: msg) } } } @@ -20,22 +20,22 @@ internal func equal( /// Values can support equal by supporting the Equatable protocol. /// /// @see beCloseTo if you want to match imprecise types (eg - floats, doubles). -public func equal(_ expectedValue: T) -> Matcher { +public func equal(_ expectedValue: T) -> Predicate { equal(expectedValue as T?) } /// A Nimble matcher allowing comparison of collection with optional type -public func equal(_ expectedValue: [T?]) -> Matcher<[T?]> { - Matcher.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in +public func equal(_ expectedValue: [T?]) -> Predicate<[T?]> { + Predicate.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in guard let actualValue = try actualExpression.evaluate() else { - return MatcherResult( + return PredicateResult( status: .fail, message: msg.appendedBeNilHint() ) } let matches = expectedValue == actualValue - return MatcherResult(bool: matches, message: msg) + return PredicateResult(bool: matches, message: msg) } } @@ -43,46 +43,46 @@ public func equal(_ expectedValue: [T?]) -> Matcher<[T?]> { /// Values can support equal by supporting the Equatable protocol. /// /// @see beCloseTo if you want to match imprecise types (eg - floats, doubles). -public func equal(_ expectedValue: T?) -> Matcher { +public func equal(_ expectedValue: T?) -> Predicate { equal(expectedValue, by: ==) } /// A Nimble matcher that succeeds when the actual set is equal to the expected set. -public func equal(_ expectedValue: Set) -> Matcher> { +public func equal(_ expectedValue: Set) -> Predicate> { equal(expectedValue as Set?) } /// A Nimble matcher that succeeds when the actual set is equal to the expected set. -public func equal(_ expectedValue: Set?) -> Matcher> { +public func equal(_ expectedValue: Set?) -> Predicate> { equal(expectedValue, stringify: { stringify($0) }) } /// A Nimble matcher that succeeds when the actual set is equal to the expected set. -public func equal(_ expectedValue: Set) -> Matcher> { +public func equal(_ expectedValue: Set) -> Predicate> { equal(expectedValue as Set?) } /// A Nimble matcher that succeeds when the actual set is equal to the expected set. -public func equal(_ expectedValue: Set?) -> Matcher> { +public func equal(_ expectedValue: Set?) -> Predicate> { equal(expectedValue, stringify: { set in stringify(set.map { Array($0).sorted(by: <) }) }) } -private func equal(_ expectedValue: Set?, stringify: @escaping (Set?) -> String) -> Matcher> { - Matcher { actualExpression in +private func equal(_ expectedValue: Set?, stringify: @escaping (Set?) -> String) -> Predicate> { + Predicate { actualExpression in var errorMessage: ExpectationMessage = .expectedActualValueTo("equal <\(stringify(expectedValue))>") guard let expectedValue = expectedValue else { - return MatcherResult( + return PredicateResult( status: .fail, message: errorMessage.appendedBeNilHint() ) } guard let actualValue = try actualExpression.evaluate() else { - return MatcherResult( + return PredicateResult( status: .fail, message: errorMessage.appendedBeNilHint() ) @@ -94,7 +94,7 @@ private func equal(_ expectedValue: Set?, stringify: @escaping (Set?) - ) if expectedValue == actualValue { - return MatcherResult( + return PredicateResult( status: .matches, message: errorMessage ) @@ -109,7 +109,7 @@ private func equal(_ expectedValue: Set?, stringify: @escaping (Set?) - if extra.count > 0 { errorMessage = errorMessage.appended(message: ", extra <\(stringify(extra))>") } - return MatcherResult( + return PredicateResult( status: .doesNotMatch, message: errorMessage ) @@ -117,154 +117,90 @@ private func equal(_ expectedValue: Set?, stringify: @escaping (Set?) - } /// A Nimble matcher that succeeds when the actual dictionary is equal to the expected dictionary -public func equal(_ expectedValue: [K: V?]) -> Matcher<[K: V]> { - Matcher.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in +public func equal(_ expectedValue: [K: V?]) -> Predicate<[K: V]> { + Predicate.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in guard let actualValue = try actualExpression.evaluate() else { - return MatcherResult( + return PredicateResult( status: .fail, message: msg.appendedBeNilHint() ) } let matches = expectedValue == actualValue - return MatcherResult(bool: matches, message: msg) + return PredicateResult(bool: matches, message: msg) } } -public func == (lhs: SyncExpectation, rhs: T) { +public func ==(lhs: Expectation, rhs: T) { lhs.to(equal(rhs)) } -public func == (lhs: SyncExpectation, rhs: T?) { +public func ==(lhs: Expectation, rhs: T?) { lhs.to(equal(rhs)) } -public func != (lhs: SyncExpectation, rhs: T) { +public func !=(lhs: Expectation, rhs: T) { lhs.toNot(equal(rhs)) } -public func != (lhs: SyncExpectation, rhs: T?) { +public func !=(lhs: Expectation, rhs: T?) { lhs.toNot(equal(rhs)) } -public func == (lhs: SyncExpectation<[T]>, rhs: [T]?) { +public func ==(lhs: Expectation<[T]>, rhs: [T]?) { lhs.to(equal(rhs)) } -public func != (lhs: SyncExpectation<[T]>, rhs: [T]?) { +public func !=(lhs: Expectation<[T]>, rhs: [T]?) { lhs.toNot(equal(rhs)) } -public func == (lhs: SyncExpectation>, rhs: Set) { +public func == (lhs: Expectation>, rhs: Set) { lhs.to(equal(rhs)) } -public func == (lhs: SyncExpectation>, rhs: Set?) { +public func == (lhs: Expectation>, rhs: Set?) { lhs.to(equal(rhs)) } -public func != (lhs: SyncExpectation>, rhs: Set) { +public func != (lhs: Expectation>, rhs: Set) { lhs.toNot(equal(rhs)) } -public func != (lhs: SyncExpectation>, rhs: Set?) { +public func != (lhs: Expectation>, rhs: Set?) { lhs.toNot(equal(rhs)) } -public func == (lhs: SyncExpectation>, rhs: Set) { +public func ==(lhs: Expectation>, rhs: Set) { lhs.to(equal(rhs)) } -public func == (lhs: SyncExpectation>, rhs: Set?) { +public func ==(lhs: Expectation>, rhs: Set?) { lhs.to(equal(rhs)) } -public func != (lhs: SyncExpectation>, rhs: Set) { +public func !=(lhs: Expectation>, rhs: Set) { lhs.toNot(equal(rhs)) } -public func != (lhs: SyncExpectation>, rhs: Set?) { +public func !=(lhs: Expectation>, rhs: Set?) { lhs.toNot(equal(rhs)) } -public func == (lhs: SyncExpectation<[T: C]>, rhs: [T: C]?) { +public func ==(lhs: Expectation<[T: C]>, rhs: [T: C]?) { lhs.to(equal(rhs)) } -public func != (lhs: SyncExpectation<[T: C]>, rhs: [T: C]?) { +public func !=(lhs: Expectation<[T: C]>, rhs: [T: C]?) { lhs.toNot(equal(rhs)) } -public func == (lhs: AsyncExpectation, rhs: T) async { - await lhs.to(equal(rhs)) -} - -public func == (lhs: AsyncExpectation, rhs: T?) async { - await lhs.to(equal(rhs)) -} - -public func != (lhs: AsyncExpectation, rhs: T) async { - await lhs.toNot(equal(rhs)) -} - -public func != (lhs: AsyncExpectation, rhs: T?) async { - await lhs.toNot(equal(rhs)) -} - -public func == (lhs: AsyncExpectation<[T]>, rhs: [T]?) async { - await lhs.to(equal(rhs)) -} - -public func != (lhs: AsyncExpectation<[T]>, rhs: [T]?) async { - await lhs.toNot(equal(rhs)) -} - -public func == (lhs: AsyncExpectation>, rhs: Set) async { - await lhs.to(equal(rhs)) -} - -public func == (lhs: AsyncExpectation>, rhs: Set?) async { - await lhs.to(equal(rhs)) -} - -public func != (lhs: AsyncExpectation>, rhs: Set) async { - await lhs.toNot(equal(rhs)) -} - -public func != (lhs: AsyncExpectation>, rhs: Set?) async { - await lhs.toNot(equal(rhs)) -} - -public func == (lhs: AsyncExpectation>, rhs: Set) async { - await lhs.to(equal(rhs)) -} - -public func == (lhs: AsyncExpectation>, rhs: Set?) async { - await lhs.to(equal(rhs)) -} - -public func != (lhs: AsyncExpectation>, rhs: Set) async { - await lhs.toNot(equal(rhs)) -} - -public func != (lhs: AsyncExpectation>, rhs: Set?) async { - await lhs.toNot(equal(rhs)) -} - -public func == (lhs: AsyncExpectation<[T: C]>, rhs: [T: C]?) async { - await lhs.to(equal(rhs)) -} - -public func != (lhs: AsyncExpectation<[T: C]>, rhs: [T: C]?) async { - await lhs.toNot(equal(rhs)) -} - #if canImport(Darwin) import class Foundation.NSObject -extension NMBMatcher { - @objc public class func equalMatcher(_ expected: NSObject) -> NMBMatcher { - NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func equalMatcher(_ expected: NSObject) -> NMBPredicate { + NMBPredicate { actualExpression in try equal(expected).satisfies(actualExpression).toObjectiveC() } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/HaveCount.swift b/Pods/Nimble/Sources/Nimble/Matchers/HaveCount.swift index 7b476d7..20397f5 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/HaveCount.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/HaveCount.swift @@ -5,8 +5,8 @@ /// A Nimble matcher that succeeds when the actual Collection's count equals /// the expected value -public func haveCount(_ expectedValue: Int) -> Matcher { - return Matcher.define { actualExpression in +public func haveCount(_ expectedValue: Int) -> Predicate { + return Predicate.define { actualExpression in if let actualValue = try actualExpression.evaluate() { let message = ExpectationMessage .expectedCustomValueTo( @@ -16,28 +16,29 @@ public func haveCount(_ expectedValue: Int) -> Matcher { .appended(details: "Actual Value: \(stringify(actualValue))") let result = expectedValue == actualValue.count - return MatcherResult(bool: result, message: message) + return PredicateResult(bool: result, message: message) } else { - return MatcherResult(status: .fail, message: .fail("")) + return PredicateResult(status: .fail, message: .fail("")) } } } /// A Nimble matcher that succeeds when the actual collection's count equals /// the expected value -public func haveCount(_ expectedValue: Int) -> Matcher { - return Matcher { actualExpression in +public func haveCount(_ expectedValue: Int) -> Predicate { + return Predicate { actualExpression in if let actualValue = try actualExpression.evaluate() { let message = ExpectationMessage .expectedCustomValueTo( "have \(prettyCollectionType(actualValue)) with count \(stringify(expectedValue))", - actual: "\(actualValue.count). Actual Value: \(stringify(actualValue))" + actual: "\(actualValue.count)" ) + .appended(details: "Actual Value: \(stringify(actualValue))") let result = expectedValue == actualValue.count - return MatcherResult(bool: result, message: message) + return PredicateResult(bool: result, message: message) } else { - return MatcherResult(status: .fail, message: .fail("")) + return PredicateResult(status: .fail, message: .fail("")) } } } @@ -45,9 +46,9 @@ public func haveCount(_ expectedValue: Int) -> Matcher { #if canImport(Darwin) import Foundation -extension NMBMatcher { - @objc public class func haveCountMatcher(_ expected: NSNumber) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func haveCountMatcher(_ expected: NSNumber) -> NMBPredicate { + return NMBPredicate { actualExpression in let location = actualExpression.location let actualValue = try actualExpression.evaluate() if let value = actualValue as? NMBCollection { @@ -66,7 +67,7 @@ extension NMBMatcher { .expectedActualValueTo("have a collection with count \(stringify(expected.intValue))") .appendedBeNilHint() } - return NMBMatcherResult(status: .fail, message: message.toObjectiveC()) + return NMBPredicateResult(status: .fail, message: message.toObjectiveC()) } } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/Match.swift b/Pods/Nimble/Sources/Nimble/Matchers/Match.swift index b634ad3..93363b3 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/Match.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/Match.swift @@ -1,20 +1,20 @@ /// A Nimble matcher that succeeds when the actual string satisfies the regular expression /// described by the expected string. -public func match(_ expectedValue: String?) -> Matcher { - return Matcher.simple("match <\(stringify(expectedValue))>") { actualExpression in +public func match(_ expectedValue: String?) -> Predicate { + return Predicate.simple("match <\(stringify(expectedValue))>") { actualExpression in guard let actual = try actualExpression.evaluate(), let regexp = expectedValue else { return .fail } let bool = actual.range(of: regexp, options: .regularExpression) != nil - return MatcherStatus(bool: bool) + return PredicateStatus(bool: bool) } } #if canImport(Darwin) import class Foundation.NSString -extension NMBMatcher { - @objc public class func matchMatcher(_ expected: NSString) -> NMBMatcher { - return NMBMatcher { actualExpression in +extension NMBPredicate { + @objc public class func matchMatcher(_ expected: NSString) -> NMBPredicate { + return NMBPredicate { actualExpression in let actual = actualExpression.cast { $0 as? String } return try match(expected.description).satisfies(actual).toObjectiveC() } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/MatchError.swift b/Pods/Nimble/Sources/Nimble/Matchers/MatchError.swift index 10ed86b..3edc99b 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/MatchError.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/MatchError.swift @@ -3,8 +3,8 @@ /// /// Errors are tried to be compared by their implementation of Equatable, /// otherwise they fallback to comparison by _domain and _code. -public func matchError(_ error: T) -> Matcher { - return Matcher.define { actualExpression in +public func matchError(_ error: T) -> Predicate { + return Predicate.define { actualExpression in let actualError = try actualExpression.evaluate() let message = messageForError( @@ -18,7 +18,7 @@ public func matchError(_ error: T) -> Matcher { matches = true } - return MatcherResult(bool: matches, message: message) + return PredicateResult(bool: matches, message: message) } } @@ -27,8 +27,8 @@ public func matchError(_ error: T) -> Matcher { /// /// Errors are tried to be compared by their implementation of Equatable, /// otherwise they fallback to comparision by _domain and _code. -public func matchError(_ error: T) -> Matcher { - return Matcher.define { actualExpression in +public func matchError(_ error: T) -> Predicate { + return Predicate.define { actualExpression in let actualError = try actualExpression.evaluate() let message = messageForError( @@ -42,14 +42,14 @@ public func matchError(_ error: T) -> Matcher { matches = true } - return MatcherResult(bool: matches, message: message) + return PredicateResult(bool: matches, message: message) } } /// A Nimble matcher that succeeds when the actual expression evaluates to an /// error of the specified type -public func matchError(_ errorType: T.Type) -> Matcher { - return Matcher.define { actualExpression in +public func matchError(_ errorType: T.Type) -> Predicate { + return Predicate.define { actualExpression in let actualError = try actualExpression.evaluate() let message = messageForError( @@ -63,6 +63,6 @@ public func matchError(_ errorType: T.Type) -> Matcher { matches = true } - return MatcherResult(bool: matches, message: message) + return PredicateResult(bool: matches, message: message) } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/PostNotification.swift b/Pods/Nimble/Sources/Nimble/Matchers/PostNotification.swift index 5144cc1..e04bf55 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/PostNotification.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/PostNotification.swift @@ -5,7 +5,6 @@ import Foundation internal class NotificationCollector { private(set) var observedNotifications: [Notification] - private(set) var observedNotificationDescriptions: [String] private let notificationCenter: NotificationCenter private let names: Set private var tokens: [NSObjectProtocol] @@ -13,7 +12,6 @@ internal class NotificationCollector { required init(notificationCenter: NotificationCenter, names: Set = []) { self.notificationCenter = notificationCenter self.observedNotifications = [] - self.observedNotificationDescriptions = [] self.names = names self.tokens = [] } @@ -23,7 +21,6 @@ internal class NotificationCollector { return notificationCenter.addObserver(forName: name, object: nil, queue: nil) { [weak self] notification in // linux-swift gets confused by .append(n) self?.observedNotifications.append(notification) - self?.observedNotificationDescriptions.append(stringify(notification)) } } @@ -43,23 +40,19 @@ internal class NotificationCollector { } } -#if !os(Windows) private let mainThread = pthread_self() -#else -private let mainThread = Thread.mainThread -#endif private func _postNotifications( - _ matcher: Matcher<[Notification]>, + _ predicate: Predicate<[Notification]>, from center: NotificationCenter, names: Set = [] -) -> Matcher { +) -> Predicate { _ = mainThread // Force lazy-loading of this value let collector = NotificationCollector(notificationCenter: center, names: names) collector.startObserving() var once: Bool = false - return Matcher { actualExpression in + return Predicate { actualExpression in let collectorNotificationsExpression = Expression( memoizedExpression: { _ in return collector.observedNotifications @@ -68,7 +61,7 @@ private func _postNotifications( withoutCaching: true ) - assert(Thread.isMainThread, "Only expecting closure to be evaluated on main thread.") + assert(pthread_equal(mainThread, pthread_self()) != 0, "Only expecting closure to be evaluated on main thread.") if !once { once = true _ = try actualExpression.evaluate() @@ -78,10 +71,10 @@ private func _postNotifications( if collector.observedNotifications.isEmpty { actualValue = "no notifications" } else { - actualValue = "<\(stringify(collector.observedNotificationDescriptions))>" + actualValue = "<\(stringify(collector.observedNotifications))>" } - var result = try matcher.satisfies(collectorNotificationsExpression) + var result = try predicate.satisfies(collectorNotificationsExpression) result.message = result.message.replacedExpectation { message in return .expectedCustomValueTo(message.expectedMessage, actual: actualValue) } @@ -90,19 +83,19 @@ private func _postNotifications( } public func postNotifications( - _ matcher: Matcher<[Notification]>, + _ predicate: Predicate<[Notification]>, from center: NotificationCenter = .default -) -> Matcher { - _postNotifications(matcher, from: center) +) -> Predicate { + _postNotifications(predicate, from: center) } #if os(macOS) public func postDistributedNotifications( - _ matcher: Matcher<[Notification]>, + _ predicate: Predicate<[Notification]>, from center: DistributedNotificationCenter = .default(), names: Set -) -> Matcher { - _postNotifications(matcher, from: center, names: names) +) -> Predicate { + _postNotifications(predicate, from: center, names: names) } #endif diff --git a/Pods/Nimble/Sources/Nimble/Matchers/Predicate.swift b/Pods/Nimble/Sources/Nimble/Matchers/Predicate.swift new file mode 100644 index 0000000..ce20c6b --- /dev/null +++ b/Pods/Nimble/Sources/Nimble/Matchers/Predicate.swift @@ -0,0 +1,289 @@ +// New Matcher API +// + +/// A Predicate is part of the new matcher API that provides assertions to expectations. +/// +/// Given a code snippet: +/// +/// expect(1).to(equal(2)) +/// ^^^^^^^^ +/// Called a "matcher" +/// +/// A matcher consists of two parts a constructor function and the Predicate. The term Predicate +/// is used as a separate name from Matcher to help transition custom matchers to the new Nimble +/// matcher API. +/// +/// The Predicate provide the heavy lifting on how to assert against a given value. Internally, +/// predicates are simple wrappers around closures to provide static type information and +/// allow composition and wrapping of existing behaviors. +public struct Predicate { + fileprivate var matcher: (Expression) throws -> PredicateResult + + /// Constructs a predicate that knows how take a given value + public init(_ matcher: @escaping (Expression) throws -> PredicateResult) { + self.matcher = matcher + } + + /// Uses a predicate on a given value to see if it passes the predicate. + /// + /// @param expression The value to run the predicate's logic against + /// @returns A predicate result indicate passing or failing and an associated error message. + public func satisfies(_ expression: Expression) throws -> PredicateResult { + return try matcher(expression) + } +} + +/// Provides convenience helpers to defining predicates +extension Predicate { + /// Like Predicate() constructor, but automatically guard against nil (actual) values + public static func define(matcher: @escaping (Expression) throws -> PredicateResult) -> Predicate { + return Predicate { actual in + return try matcher(actual) + }.requireNonNil + } + + /// Defines a predicate with a default message that can be returned in the closure + /// Also ensures the predicate's actual value cannot pass with `nil` given. + public static func define(_ message: String = "match", matcher: @escaping (Expression, ExpectationMessage) throws -> PredicateResult) -> Predicate { + return Predicate { actual in + return try matcher(actual, .expectedActualValueTo(message)) + }.requireNonNil + } + + /// Defines a predicate with a default message that can be returned in the closure + /// Unlike `define`, this allows nil values to succeed if the given closure chooses to. + public static func defineNilable(_ message: String = "match", matcher: @escaping (Expression, ExpectationMessage) throws -> PredicateResult) -> Predicate { + return Predicate { actual in + return try matcher(actual, .expectedActualValueTo(message)) + } + } +} + +extension Predicate { + /// Provides a simple predicate definition that provides no control over the predefined + /// error message. + /// + /// Also ensures the predicate's actual value cannot pass with `nil` given. + public static func simple(_ message: String = "match", matcher: @escaping (Expression) throws -> PredicateStatus) -> Predicate { + return Predicate { actual in + return PredicateResult(status: try matcher(actual), message: .expectedActualValueTo(message)) + }.requireNonNil + } + + /// Provides a simple predicate definition that provides no control over the predefined + /// error message. + /// + /// Unlike `simple`, this allows nil values to succeed if the given closure chooses to. + public static func simpleNilable(_ message: String = "match", matcher: @escaping (Expression) throws -> PredicateStatus) -> Predicate { + return Predicate { actual in + return PredicateResult(status: try matcher(actual), message: .expectedActualValueTo(message)) + } + } +} + +// The Expectation style intended for comparison to a PredicateStatus. +public enum ExpectationStyle { + case toMatch, toNotMatch +} + +/// The value that a Predicates return to describe if the given (actual) value matches the +/// predicate. +public struct PredicateResult { + /// Status indicates if the predicate matches, does not match, or fails. + public var status: PredicateStatus + /// The error message that can be displayed if it does not match + public var message: ExpectationMessage + + /// Constructs a new PredicateResult with a given status and error message + public init(status: PredicateStatus, message: ExpectationMessage) { + self.status = status + self.message = message + } + + /// Shorthand to PredicateResult(status: PredicateStatus(bool: bool), message: message) + public init(bool: Bool, message: ExpectationMessage) { + self.status = PredicateStatus(bool: bool) + self.message = message + } + + /// Converts the result to a boolean based on what the expectation intended + public func toBoolean(expectation style: ExpectationStyle) -> Bool { + return status.toBoolean(expectation: style) + } +} + +/// PredicateStatus is a trinary that indicates if a Predicate matches a given value or not +public enum PredicateStatus { + /// Matches indicates if the predicate / matcher passes with the given value + /// + /// For example, `equals(1)` returns `.matches` for `expect(1).to(equal(1))`. + case matches + /// DoesNotMatch indicates if the predicate / matcher fails with the given value, but *would* + /// succeed if the expectation was inverted. + /// + /// For example, `equals(2)` returns `.doesNotMatch` for `expect(1).toNot(equal(2))`. + case doesNotMatch + /// Fail indicates the predicate will never satisfy with the given value in any case. + /// A perfect example is that most matchers fail whenever given `nil`. + /// + /// Using `equal(1)` fails both `expect(nil).to(equal(1))` and `expect(nil).toNot(equal(1))`. + /// Note: Predicate's `requireNonNil` property will also provide this feature mostly for free. + /// Your predicate will still need to guard against nils, but error messaging will be + /// handled for you. + case fail + + /// Converts a boolean to either .matches (if true) or .doesNotMatch (if false). + public init(bool matches: Bool) { + if matches { + self = .matches + } else { + self = .doesNotMatch + } + } + + private func shouldMatch() -> Bool { + switch self { + case .matches: return true + case .doesNotMatch, .fail: return false + } + } + + private func shouldNotMatch() -> Bool { + switch self { + case .doesNotMatch: return true + case .matches, .fail: return false + } + } + + /// Converts the PredicateStatus result to a boolean based on what the expectation intended + internal func toBoolean(expectation style: ExpectationStyle) -> Bool { + if style == .toMatch { + return shouldMatch() + } else { + return shouldNotMatch() + } + } +} + +extension Predicate { + // Someday, make this public? Needs documentation + internal func after(f: @escaping (Expression, PredicateResult) throws -> PredicateResult) -> Predicate { + // swiftlint:disable:previous identifier_name + return Predicate { actual -> PredicateResult in + let result = try self.satisfies(actual) + return try f(actual, result) + } + } + + /// Returns a new Predicate based on the current one that always fails if nil is given as + /// the actual value. + public var requireNonNil: Predicate { + return after { actual, result in + if try actual.evaluate() == nil { + return PredicateResult( + status: .fail, + message: result.message.appendedBeNilHint() + ) + } + return result + } + } +} + +#if canImport(Darwin) +import class Foundation.NSObject + +public typealias PredicateBlock = (_ actualExpression: Expression) throws -> NMBPredicateResult + +public class NMBPredicate: NSObject { + private let predicate: PredicateBlock + + public init(predicate: @escaping PredicateBlock) { + self.predicate = predicate + } + + func satisfies(_ expression: @escaping () throws -> NSObject?, location: SourceLocation) -> NMBPredicateResult { + let expr = Expression(expression: expression, location: location) + do { + return try self.predicate(expr) + } catch let error { + return PredicateResult(status: .fail, message: .fail("unexpected error thrown: <\(error)>")).toObjectiveC() + } + } +} + +final public class NMBPredicateResult: NSObject { + public var status: NMBPredicateStatus + public var message: NMBExpectationMessage + + public init(status: NMBPredicateStatus, message: NMBExpectationMessage) { + self.status = status + self.message = message + } + + public init(bool success: Bool, message: NMBExpectationMessage) { + self.status = NMBPredicateStatus.from(bool: success) + self.message = message + } + + public func toSwift() -> PredicateResult { + return PredicateResult(status: status.toSwift(), + message: message.toSwift()) + } +} + +extension PredicateResult { + public func toObjectiveC() -> NMBPredicateResult { + return NMBPredicateResult(status: status.toObjectiveC(), message: message.toObjectiveC()) + } +} + +final public class NMBPredicateStatus: NSObject { + private let status: Int + private init(status: Int) { + self.status = status + } + + public static let matches: NMBPredicateStatus = NMBPredicateStatus(status: 0) + public static let doesNotMatch: NMBPredicateStatus = NMBPredicateStatus(status: 1) + public static let fail: NMBPredicateStatus = NMBPredicateStatus(status: 2) + + public override var hash: Int { return self.status.hashValue } + + public override func isEqual(_ object: Any?) -> Bool { + guard let otherPredicate = object as? NMBPredicateStatus else { + return false + } + return self.status == otherPredicate.status + } + + public static func from(status: PredicateStatus) -> NMBPredicateStatus { + switch status { + case .matches: return self.matches + case .doesNotMatch: return self.doesNotMatch + case .fail: return self.fail + } + } + + public static func from(bool success: Bool) -> NMBPredicateStatus { + return self.from(status: PredicateStatus(bool: success)) + } + + public func toSwift() -> PredicateStatus { + switch status { + case NMBPredicateStatus.matches.status: return .matches + case NMBPredicateStatus.doesNotMatch.status: return .doesNotMatch + case NMBPredicateStatus.fail.status: return .fail + default: + internalError("Unhandle status for NMBPredicateStatus") + } + } +} + +extension PredicateStatus { + public func toObjectiveC() -> NMBPredicateStatus { + return NMBPredicateStatus.from(status: self) + } +} + +#endif diff --git a/Pods/Nimble/Sources/Nimble/Matchers/RaisesException.swift b/Pods/Nimble/Sources/Nimble/Matchers/RaisesException.swift index 2bb9409..7c1b2b2 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/RaisesException.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/RaisesException.swift @@ -18,7 +18,7 @@ public func raiseException( reason: String? = nil, userInfo: NSDictionary? = nil, closure: ((NSException) -> Void)? = nil -) -> Matcher { +) -> Predicate { return raiseException(named: named?.rawValue, reason: reason, userInfo: userInfo, closure: closure) } @@ -36,8 +36,8 @@ public func raiseException( reason: String? = nil, userInfo: NSDictionary? = nil, closure: ((NSException) -> Void)? = nil -) -> Matcher { - return Matcher { actualExpression in +) -> Predicate { + return Predicate { actualExpression in var exception: NSException? let capture = NMBExceptionCapture(handler: ({ e in exception = e @@ -48,7 +48,7 @@ public func raiseException( _ = try actualExpression.evaluate() } } catch { - return MatcherResult(status: .fail, message: .fail("unexpected error thrown: <\(error)>")) + return PredicateResult(status: .fail, message: .fail("unexpected error thrown: <\(error)>")) } let message = messageForException( @@ -66,7 +66,7 @@ public func raiseException( userInfo: userInfo, closure: closure ) - return MatcherResult(bool: matches, message: message) + return PredicateResult(bool: matches, message: message) } } @@ -141,7 +141,7 @@ internal func exceptionMatchesNonNilFieldsOrClosure( return matches } -public class NMBObjCRaiseExceptionMatcher: NMBMatcher { +public class NMBObjCRaiseExceptionPredicate: NMBPredicate { private let _name: String? private let _reason: String? private let _userInfo: NSDictionary? @@ -153,22 +153,22 @@ public class NMBObjCRaiseExceptionMatcher: NMBMatcher { _userInfo = userInfo _block = block - let matcher: Matcher = raiseException( + let predicate: Predicate = raiseException( named: name, reason: reason, userInfo: userInfo, closure: block ) - let matcherBlock: MatcherBlock = { actualExpression in - return try matcher.satisfies(actualExpression).toObjectiveC() + let predicateBlock: PredicateBlock = { actualExpression in + return try predicate.satisfies(actualExpression).toObjectiveC() } - super.init(matcher: matcherBlock) + super.init(predicate: predicateBlock) } - @objc public var named: (_ name: String) -> NMBObjCRaiseExceptionMatcher { + @objc public var named: (_ name: String) -> NMBObjCRaiseExceptionPredicate { let (reason, userInfo, block) = (_reason, _userInfo, _block) return { name in - return NMBObjCRaiseExceptionMatcher( + return NMBObjCRaiseExceptionPredicate( name: name, reason: reason, userInfo: userInfo, @@ -177,10 +177,10 @@ public class NMBObjCRaiseExceptionMatcher: NMBMatcher { } } - @objc public var reason: (_ reason: String?) -> NMBObjCRaiseExceptionMatcher { + @objc public var reason: (_ reason: String?) -> NMBObjCRaiseExceptionPredicate { let (name, userInfo, block) = (_name, _userInfo, _block) return { reason in - return NMBObjCRaiseExceptionMatcher( + return NMBObjCRaiseExceptionPredicate( name: name, reason: reason, userInfo: userInfo, @@ -189,10 +189,10 @@ public class NMBObjCRaiseExceptionMatcher: NMBMatcher { } } - @objc public var userInfo: (_ userInfo: NSDictionary?) -> NMBObjCRaiseExceptionMatcher { + @objc public var userInfo: (_ userInfo: NSDictionary?) -> NMBObjCRaiseExceptionPredicate { let (name, reason, block) = (_name, _reason, _block) return { userInfo in - return NMBObjCRaiseExceptionMatcher( + return NMBObjCRaiseExceptionPredicate( name: name, reason: reason, userInfo: userInfo, @@ -201,10 +201,10 @@ public class NMBObjCRaiseExceptionMatcher: NMBMatcher { } } - @objc public var satisfyingBlock: (_ block: ((NSException) -> Void)?) -> NMBObjCRaiseExceptionMatcher { + @objc public var satisfyingBlock: (_ block: ((NSException) -> Void)?) -> NMBObjCRaiseExceptionPredicate { let (name, reason, userInfo) = (_name, _reason, _userInfo) return { block in - return NMBObjCRaiseExceptionMatcher( + return NMBObjCRaiseExceptionPredicate( name: name, reason: reason, userInfo: userInfo, @@ -214,9 +214,9 @@ public class NMBObjCRaiseExceptionMatcher: NMBMatcher { } } -extension NMBMatcher { - @objc public class func raiseExceptionMatcher() -> NMBObjCRaiseExceptionMatcher { - return NMBObjCRaiseExceptionMatcher(name: nil, reason: nil, userInfo: nil, block: nil) +extension NMBPredicate { + @objc public class func raiseExceptionMatcher() -> NMBObjCRaiseExceptionPredicate { + return NMBObjCRaiseExceptionPredicate(name: nil, reason: nil, userInfo: nil, block: nil) } } #endif diff --git a/Pods/Nimble/Sources/Nimble/Matchers/SatisfyAllOf.swift b/Pods/Nimble/Sources/Nimble/Matchers/SatisfyAllOf.swift index 30f9045..50ab641 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/SatisfyAllOf.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/SatisfyAllOf.swift @@ -1,18 +1,17 @@ /// A Nimble matcher that succeeds when the actual value matches with all of the matchers /// provided in the variable list of matchers. -public func satisfyAllOf(_ matchers: Matcher...) -> Matcher { - return satisfyAllOf(matchers) +public func satisfyAllOf(_ predicates: Predicate...) -> Predicate { + return satisfyAllOf(predicates) } /// A Nimble matcher that succeeds when the actual value matches with all of the matchers /// provided in the array of matchers. -public func satisfyAllOf(_ matchers: [Matcher]) -> Matcher { - return Matcher.define { actualExpression in - let cachedExpression = actualExpression.withCaching() +public func satisfyAllOf(_ predicates: [Predicate]) -> Predicate { + return Predicate.define { actualExpression in var postfixMessages = [String]() - var status: MatcherStatus = .matches - for matcher in matchers { - let result = try matcher.satisfies(cachedExpression) + var status: PredicateStatus = .matches + for predicate in predicates { + let result = try predicate.satisfies(actualExpression) if result.status == .fail { status = .fail } else if result.status == .doesNotMatch, status != .fail { @@ -22,7 +21,7 @@ public func satisfyAllOf(_ matchers: [Matcher]) -> Matcher { } var msg: ExpectationMessage - if let actualValue = try cachedExpression.evaluate() { + if let actualValue = try actualExpression.evaluate() { msg = .expectedCustomValueTo( "match all of: " + postfixMessages.joined(separator: ", and "), actual: "\(actualValue)" @@ -33,84 +32,33 @@ public func satisfyAllOf(_ matchers: [Matcher]) -> Matcher { ) } - return MatcherResult(status: status, message: msg) + return PredicateResult(status: status, message: msg) } } -public func && (left: Matcher, right: Matcher) -> Matcher { +public func && (left: Predicate, right: Predicate) -> Predicate { return satisfyAllOf(left, right) } -// There's a compiler bug in swift 5.7.2 and earlier (xcode 14.2 and earlier) -// which causes runtime crashes when you use `[any AsyncableMatcher]`. -// https://github.com/apple/swift/issues/61403 -#if swift(>=5.8.0) -/// A Nimble matcher that succeeds when the actual value matches with all of the matchers -/// provided in the variable list of matchers. -@available(macOS 13.0.0, iOS 16.0.0, tvOS 16.0.0, watchOS 9.0.0, *) -public func satisfyAllOf(_ matchers: any AsyncableMatcher...) -> AsyncMatcher { - return satisfyAllOf(matchers) -} - -/// A Nimble matcher that succeeds when the actual value matches with all of the matchers -/// provided in the array of matchers. -@available(macOS 13.0.0, iOS 16.0.0, tvOS 16.0.0, watchOS 9.0.0, *) -public func satisfyAllOf(_ matchers: [any AsyncableMatcher]) -> AsyncMatcher { - return AsyncMatcher.define { actualExpression in - let cachedExpression = actualExpression.withCaching() - var postfixMessages = [String]() - var status: MatcherStatus = .matches - for matcher in matchers { - let result = try await matcher.satisfies(cachedExpression) - if result.status == .fail { - status = .fail - } else if result.status == .doesNotMatch, status != .fail { - status = .doesNotMatch - } - postfixMessages.append("{\(result.message.expectedMessage)}") - } - - var msg: ExpectationMessage - if let actualValue = try await cachedExpression.evaluate() { - msg = .expectedCustomValueTo( - "match all of: " + postfixMessages.joined(separator: ", and "), - actual: "\(actualValue)" - ) - } else { - msg = .expectedActualValueTo( - "match all of: " + postfixMessages.joined(separator: ", and ") - ) - } - - return MatcherResult(status: status, message: msg) - } -} - -@available(macOS 13.0.0, iOS 16.0.0, tvOS 16.0.0, watchOS 9.0.0, *) -public func && (left: some AsyncableMatcher, right: some AsyncableMatcher) -> AsyncMatcher { - return satisfyAllOf(left, right) -} -#endif // swift(>=5.8.0) - #if canImport(Darwin) import class Foundation.NSObject -extension NMBMatcher { - @objc public class func satisfyAllOfMatcher(_ matchers: [NMBMatcher]) -> NMBMatcher { - return NMBMatcher { actualExpression in - if matchers.isEmpty { - return NMBMatcherResult( - status: NMBMatcherStatus.fail, +extension NMBPredicate { + @objc public class func satisfyAllOfMatcher(_ predicates: [NMBPredicate]) -> NMBPredicate { + return NMBPredicate { actualExpression in + if predicates.isEmpty { + return NMBPredicateResult( + status: NMBPredicateStatus.fail, message: NMBExpectationMessage( fail: "satisfyAllOf must be called with at least one matcher" ) ) } - var elementEvaluators = [Matcher]() - for matcher in matchers { - let elementEvaluator = Matcher { expression in - return matcher.satisfies({ try expression.evaluate() }, location: actualExpression.location).toSwift() + var elementEvaluators = [Predicate]() + for predicate in predicates { + let elementEvaluator = Predicate { expression in + return predicate.satisfies({ try expression.evaluate() }, location: actualExpression.location).toSwift() } elementEvaluators.append(elementEvaluator) diff --git a/Pods/Nimble/Sources/Nimble/Matchers/SatisfyAnyOf.swift b/Pods/Nimble/Sources/Nimble/Matchers/SatisfyAnyOf.swift index 56ffdd1..bd027d2 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/SatisfyAnyOf.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/SatisfyAnyOf.swift @@ -1,116 +1,64 @@ /// A Nimble matcher that succeeds when the actual value matches with any of the matchers /// provided in the variable list of matchers. -public func satisfyAnyOf(_ matchers: Matcher...) -> Matcher { - return satisfyAnyOf(matchers) +public func satisfyAnyOf(_ predicates: Predicate...) -> Predicate { + return satisfyAnyOf(predicates) } /// A Nimble matcher that succeeds when the actual value matches with any of the matchers /// provided in the array of matchers. -public func satisfyAnyOf(_ matchers: [Matcher]) -> Matcher { - return Matcher.define { actualExpression in - let cachedExpression = actualExpression.withCaching() - var postfixMessages = [String]() - var status: MatcherStatus = .doesNotMatch - for matcher in matchers { - let result = try matcher.satisfies(cachedExpression) - if result.status == .fail { - status = .fail - } else if result.status == .matches, status != .fail { - status = .matches +public func satisfyAnyOf(_ predicates: [Predicate]) -> Predicate { + return Predicate.define { actualExpression in + var postfixMessages = [String]() + var status: PredicateStatus = .doesNotMatch + for predicate in predicates { + let result = try predicate.satisfies(actualExpression) + if result.status == .fail { + status = .fail + } else if result.status == .matches, status != .fail { + status = .matches + } + postfixMessages.append("{\(result.message.expectedMessage)}") } - postfixMessages.append("{\(result.message.expectedMessage)}") - } - - var msg: ExpectationMessage - if let actualValue = try cachedExpression.evaluate() { - msg = .expectedCustomValueTo( - "match one of: " + postfixMessages.joined(separator: ", or "), - actual: "\(actualValue)" - ) - } else { - msg = .expectedActualValueTo( - "match one of: " + postfixMessages.joined(separator: ", or ") - ) - } - return MatcherResult(status: status, message: msg) - } -} - -public func || (left: Matcher, right: Matcher) -> Matcher { - return satisfyAnyOf(left, right) -} - -// There's a compiler bug in swift 5.7.2 and earlier (xcode 14.2 and earlier) -// which causes runtime crashes when you use `[any AsyncableMatcher]`. -// https://github.com/apple/swift/issues/61403 -#if swift(>=5.8.0) -/// A Nimble matcher that succeeds when the actual value matches with any of the matchers -/// provided in the variable list of matchers. -@available(macOS 13.0.0, iOS 16.0.0, tvOS 16.0.0, watchOS 9.0.0, *) -public func satisfyAnyOf(_ matchers: any AsyncableMatcher...) -> AsyncMatcher { - return satisfyAnyOf(matchers) -} - -/// A Nimble matcher that succeeds when the actual value matches with any of the matchers -/// provided in the array of matchers. -@available(macOS 13.0.0, iOS 16.0.0, tvOS 16.0.0, watchOS 9.0.0, *) -public func satisfyAnyOf(_ matchers: [any AsyncableMatcher]) -> AsyncMatcher { - return AsyncMatcher.define { actualExpression in - let cachedExpression = actualExpression.withCaching() - var postfixMessages = [String]() - var status: MatcherStatus = .doesNotMatch - for matcher in matchers { - let result = try await matcher.satisfies(cachedExpression) - if result.status == .fail { - status = .fail - } else if result.status == .matches, status != .fail { - status = .matches + var msg: ExpectationMessage + if let actualValue = try actualExpression.evaluate() { + msg = .expectedCustomValueTo( + "match one of: " + postfixMessages.joined(separator: ", or "), + actual: "\(actualValue)" + ) + } else { + msg = .expectedActualValueTo( + "match one of: " + postfixMessages.joined(separator: ", or ") + ) } - postfixMessages.append("{\(result.message.expectedMessage)}") - } - var msg: ExpectationMessage - if let actualValue = try await cachedExpression.evaluate() { - msg = .expectedCustomValueTo( - "match one of: " + postfixMessages.joined(separator: ", or "), - actual: "\(actualValue)" - ) - } else { - msg = .expectedActualValueTo( - "match one of: " + postfixMessages.joined(separator: ", or ") - ) + return PredicateResult(status: status, message: msg) } - - return MatcherResult(status: status, message: msg) - } } -@available(macOS 13.0.0, iOS 16.0.0, tvOS 16.0.0, watchOS 9.0.0, *) -public func || (left: some AsyncableMatcher, right: some AsyncableMatcher) -> AsyncMatcher { +public func || (left: Predicate, right: Predicate) -> Predicate { return satisfyAnyOf(left, right) } -#endif // swift(>=5.8.0) #if canImport(Darwin) import class Foundation.NSObject -extension NMBMatcher { - @objc public class func satisfyAnyOfMatcher(_ matchers: [NMBMatcher]) -> NMBMatcher { - return NMBMatcher { actualExpression in - if matchers.isEmpty { - return NMBMatcherResult( - status: NMBMatcherStatus.fail, +extension NMBPredicate { + @objc public class func satisfyAnyOfMatcher(_ predicates: [NMBPredicate]) -> NMBPredicate { + return NMBPredicate { actualExpression in + if predicates.isEmpty { + return NMBPredicateResult( + status: NMBPredicateStatus.fail, message: NMBExpectationMessage( fail: "satisfyAnyOf must be called with at least one matcher" ) ) } - var elementEvaluators = [Matcher]() - for matcher in matchers { - let elementEvaluator = Matcher { expression in - return matcher.satisfies({ try expression.evaluate() }, location: actualExpression.location).toSwift() + var elementEvaluators = [Predicate]() + for predicate in predicates { + let elementEvaluator = Predicate { expression in + return predicate.satisfies({ try expression.evaluate() }, location: actualExpression.location).toSwift() } elementEvaluators.append(elementEvaluator) diff --git a/Pods/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift b/Pods/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift index b0c2245..34a94fb 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift @@ -1,9 +1,9 @@ -// swiftlint:disable all -#if canImport(CwlPreconditionTesting) && (os(macOS) || os(iOS) || os(visionOS)) +#if canImport(CwlPreconditionTesting) && (os(macOS) || os(iOS)) import CwlPreconditionTesting #elseif canImport(CwlPosixPreconditionTesting) import CwlPosixPreconditionTesting #elseif canImport(Glibc) +// swiftlint:disable all import Glibc // This function is called from the signal handler to shut down the thread and return 1 (indicating a SIGILL was received). @@ -79,12 +79,14 @@ public func catchBadInstruction(block: @escaping () -> Void) -> BadInstructionEx return caught ? BadInstructionException() : nil } +// swiftlint:enable all #endif -public func throwAssertion() -> Matcher { - return Matcher { actualExpression in - #if (arch(x86_64) || arch(arm64)) - #if (canImport(CwlPreconditionTesting) || canImport(CwlPosixPreconditionTesting) || canImport(Glibc)) +public func throwAssertion() -> Predicate { + return Predicate { actualExpression in + #if os(watchOS) + fatalError("Nimble currently doesn't support watchOS.") + #elseif (arch(x86_64) || arch(arm64)) && (canImport(Darwin) || canImport(Glibc)) let message = ExpectationMessage.expectedTo("throw an assertion") var actualError: Error? let caughtException: BadInstructionException? = catchBadInstruction { @@ -103,21 +105,6 @@ public func throwAssertion() -> Matcher { print() NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning = true } - #elseif os(watchOS) - if !NimbleEnvironment.activeInstance.suppressWatchOSAssertionWarning { - print() - print("[Nimble Warning]: If you're getting stuck on a debugger breakpoint for a " + - "fatal error while using throwAssertion(), please disable 'Debug Executable' " + - "in your scheme. Go to 'Edit Scheme > Test > Info' and uncheck " + - "'Debug Executable'. If you've already done that, suppress this warning " + - "by setting `NimbleEnvironment.activeInstance.suppressWatchOSAssertionWarning = true`. " + - "This is required because the standard methods of catching assertions " + - "(mach APIs) are unavailable for watchOS. Instead, the same mechanism the " + - "debugger uses is the fallback method for watchOS." - ) - print() - NimbleEnvironment.activeInstance.suppressWatchOSAssertionWarning = true - } #endif do { _ = try actualExpression.evaluate() @@ -127,21 +114,13 @@ public func throwAssertion() -> Matcher { } if let actualError = actualError { - return MatcherResult( + return PredicateResult( bool: false, message: message.appended(message: "; threw error instead <\(actualError)>") ) } else { - return MatcherResult(bool: caughtException != nil, message: message) + return PredicateResult(bool: caughtException != nil, message: message) } - #else - let message = """ - The throwAssertion Nimble matcher does not support your platform. - Note: throwAssertion no longer works on tvOS or watchOS platforms when you use Nimble with Cocoapods. - You will have to use Nimble with Swift Package Manager or Carthage. - """ - fatalError(message) - #endif #else let message = """ The throwAssertion Nimble matcher can only run on x86_64 and arm64 platforms. @@ -152,4 +131,3 @@ public func throwAssertion() -> Matcher { #endif } } -// swiftlint:enable all diff --git a/Pods/Nimble/Sources/Nimble/Matchers/ThrowError.swift b/Pods/Nimble/Sources/Nimble/Matchers/ThrowError.swift index 32c2f6c..d5ac732 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/ThrowError.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/ThrowError.swift @@ -9,8 +9,8 @@ /// /// nil arguments indicates that the matcher should not attempt to match against /// that parameter. -public func throwError() -> Matcher { - return Matcher { actualExpression in +public func throwError() -> Predicate { + return Predicate { actualExpression in var actualError: Error? do { _ = try actualExpression.evaluate() @@ -19,12 +19,12 @@ public func throwError() -> Matcher { } if let actualError = actualError { - return MatcherResult( + return PredicateResult( bool: true, message: .expectedCustomValueTo("throw any error", actual: "<\(actualError)>") ) } else { - return MatcherResult( + return PredicateResult( bool: false, message: .expectedCustomValueTo("throw any error", actual: "no error") ) @@ -43,8 +43,8 @@ public func throwError() -> Matcher { /// /// nil arguments indicates that the matcher should not attempt to match against /// that parameter. -public func throwError(_ error: T, closure: ((Error) -> Void)? = nil) -> Matcher { - return Matcher { actualExpression in +public func throwError(_ error: T, closure: ((Error) -> Void)? = nil) -> Predicate { + return Predicate { actualExpression in var actualError: Error? do { _ = try actualExpression.evaluate() @@ -74,7 +74,7 @@ public func throwError(_ error: T, closure: ((Error) -> Void)? = } } - return MatcherResult(bool: matches, message: message) + return PredicateResult(bool: matches, message: message) } } @@ -89,8 +89,8 @@ public func throwError(_ error: T, closure: ((Error) -> Void)? = /// /// nil arguments indicates that the matcher should not attempt to match against /// that parameter. -public func throwError(_ error: T, closure: ((T) -> Void)? = nil) -> Matcher { - return Matcher { actualExpression in +public func throwError(_ error: T, closure: ((T) -> Void)? = nil) -> Predicate { + return Predicate { actualExpression in var actualError: Error? do { _ = try actualExpression.evaluate() @@ -120,7 +120,7 @@ public func throwError(_ error: T, closure: ((T) -> V } } - return MatcherResult(bool: matches, message: message) + return PredicateResult(bool: matches, message: message) } } @@ -138,8 +138,8 @@ public func throwError(_ error: T, closure: ((T) -> V public func throwError( errorType: T.Type, closure: ((T) -> Void)? = nil -) -> Matcher { - return Matcher { actualExpression in +) -> Predicate { + return Predicate { actualExpression in var actualError: Error? do { _ = try actualExpression.evaluate() @@ -186,7 +186,7 @@ public func throwError( } } - return MatcherResult(bool: matches, message: message) + return PredicateResult(bool: matches, message: message) } } @@ -197,8 +197,8 @@ public func throwError( /// values of the existential type `Error` in the closure. /// /// The closure only gets called when an error was thrown. -public func throwError(closure: @escaping ((Error) -> Void)) -> Matcher { - return Matcher { actualExpression in +public func throwError(closure: @escaping ((Error) -> Void)) -> Predicate { + return Predicate { actualExpression in var actualError: Error? do { _ = try actualExpression.evaluate() @@ -221,7 +221,7 @@ public func throwError(closure: @escaping ((Error) -> Void)) -> Matcher(closure: @escaping ((Error) -> Void)) -> Matcher(closure: @escaping ((T) -> Void)) -> Matcher { - return Matcher { actualExpression in +public func throwError(closure: @escaping ((T) -> Void)) -> Predicate { + return Predicate { actualExpression in var actualError: Error? do { _ = try actualExpression.evaluate() @@ -256,6 +256,6 @@ public func throwError(closure: @escaping ((T) -> Void)) -> Match } } - return MatcherResult(bool: matches, message: message) + return PredicateResult(bool: matches, message: message) } } diff --git a/Pods/Nimble/Sources/Nimble/Matchers/ToSucceed.swift b/Pods/Nimble/Sources/Nimble/Matchers/ToSucceed.swift index 2f22991..d9c616a 100644 --- a/Pods/Nimble/Sources/Nimble/Matchers/ToSucceed.swift +++ b/Pods/Nimble/Sources/Nimble/Matchers/ToSucceed.swift @@ -14,21 +14,21 @@ public enum ToSucceedResult { Return `.succeeded` when the validation succeeds. Return `.failed` with a failure reason when the validation fails. */ -public func succeed() -> Matcher { - return Matcher.define { actualExpression in +public func succeed() -> Predicate { + return Predicate.define { actualExpression in let optActual = try actualExpression.evaluate() guard let actual = optActual else { - return MatcherResult(status: .fail, message: .fail("expected a ToSucceedResult, got ")) + return PredicateResult(status: .fail, message: .fail("expected a ToSucceedResult, got ")) } switch actual { case .succeeded: - return MatcherResult( + return PredicateResult( bool: true, message: .expectedCustomValueTo("succeed", actual: "") ) case .failed(let reason): - return MatcherResult( + return PredicateResult( bool: false, message: .expectedCustomValueTo("succeed", actual: " because <\(reason)>") ) diff --git a/Pods/Nimble/Sources/Nimble/Nimble.h b/Pods/Nimble/Sources/Nimble/Nimble.h index 9fb6ca3..dc68ded 100644 --- a/Pods/Nimble/Sources/Nimble/Nimble.h +++ b/Pods/Nimble/Sources/Nimble/Nimble.h @@ -1,23 +1,11 @@ #import - -// When running below Xcode 15, TARGET_OS_VISION is not defined. Since the project has TREAT_WARNINGS_AS_ERROS enabled -// we need to workaround this warning. -#ifndef TARGET_OS_VISION - #define TARGET_OS_VISION 0 -#endif /* TARGET_OS_VISION */ - #import #import #import -#if TARGET_OS_OSX || TARGET_OS_IOS || TARGET_OS_VISION -#if COCOAPODS - #import - #import -#else - #import "CwlMachBadInstructionHandler.h" - #import "CwlCatchException.h" -#endif +#if TARGET_OS_OSX || TARGET_OS_IOS + #import + #import #endif FOUNDATION_EXPORT double NimbleVersionNumber; diff --git a/Pods/Nimble/Sources/Nimble/Utils/Await.swift b/Pods/Nimble/Sources/Nimble/Utils/Await.swift new file mode 100644 index 0000000..1933d99 --- /dev/null +++ b/Pods/Nimble/Sources/Nimble/Utils/Await.swift @@ -0,0 +1,375 @@ +#if !os(WASI) + +import CoreFoundation +import Dispatch +import Foundation + +private let timeoutLeeway = DispatchTimeInterval.milliseconds(1) +private let pollLeeway = DispatchTimeInterval.milliseconds(1) + +/// Stores debugging information about callers +internal struct WaitingInfo: CustomStringConvertible { + let name: String + let file: FileString + let lineNumber: UInt + + var description: String { + return "\(name) at \(file):\(lineNumber)" + } +} + +internal protocol WaitLock { + func acquireWaitingLock(_ fnName: String, file: FileString, line: UInt) + func releaseWaitingLock() + func isWaitingLocked() -> Bool +} + +internal class AssertionWaitLock: WaitLock { + private var currentWaiter: WaitingInfo? + init() { } + + func acquireWaitingLock(_ fnName: String, file: FileString, line: UInt) { + let info = WaitingInfo(name: fnName, file: file, lineNumber: line) + let isMainThread = Thread.isMainThread + nimblePrecondition( + isMainThread, + "InvalidNimbleAPIUsage", + "\(fnName) can only run on the main thread." + ) + nimblePrecondition( + currentWaiter == nil, + "InvalidNimbleAPIUsage", + """ + Nested async expectations are not allowed to avoid creating flaky tests. + + The call to + \t\(info) + triggered this exception because + \t\(currentWaiter!) + is currently managing the main run loop. + """ + ) + currentWaiter = info + } + + func isWaitingLocked() -> Bool { + return currentWaiter != nil + } + + func releaseWaitingLock() { + currentWaiter = nil + } +} + +internal enum AwaitResult { + /// Incomplete indicates None (aka - this value hasn't been fulfilled yet) + case incomplete + /// TimedOut indicates the result reached its defined timeout limit before returning + case timedOut + /// BlockedRunLoop indicates the main runloop is too busy processing other blocks to trigger + /// the timeout code. + /// + /// This may also mean the async code waiting upon may have never actually ran within the + /// required time because other timers & sources are running on the main run loop. + case blockedRunLoop + /// The async block successfully executed and returned a given result + case completed(T) + /// When a Swift Error is thrown + case errorThrown(Error) + /// When an Objective-C Exception is raised + case raisedException(NSException) + + func isIncomplete() -> Bool { + switch self { + case .incomplete: return true + default: return false + } + } + + func isCompleted() -> Bool { + switch self { + case .completed: return true + default: return false + } + } +} + +/// Holds the resulting value from an asynchronous expectation. +/// This class is thread-safe at receiving an "response" to this promise. +internal final class AwaitPromise { + private(set) internal var asyncResult: AwaitResult = .incomplete + private var signal: DispatchSemaphore + + init() { + signal = DispatchSemaphore(value: 1) + } + + deinit { + signal.signal() + } + + /// Resolves the promise with the given result if it has not been resolved. Repeated calls to + /// this method will resolve in a no-op. + /// + /// @returns a Bool that indicates if the async result was accepted or rejected because another + /// value was received first. + func resolveResult(_ result: AwaitResult) -> Bool { + if signal.wait(timeout: .now()) == .success { + self.asyncResult = result + return true + } else { + return false + } + } +} + +internal struct AwaitTrigger { + let timeoutSource: DispatchSourceTimer + let actionSource: DispatchSourceTimer? + let start: () throws -> Void +} + +/// Factory for building fully configured AwaitPromises and waiting for their results. +/// +/// This factory stores all the state for an async expectation so that Await doesn't +/// doesn't have to manage it. +internal class AwaitPromiseBuilder { + let awaiter: Awaiter + let waitLock: WaitLock + let trigger: AwaitTrigger + let promise: AwaitPromise + + internal init( + awaiter: Awaiter, + waitLock: WaitLock, + promise: AwaitPromise, + trigger: AwaitTrigger) { + self.awaiter = awaiter + self.waitLock = waitLock + self.promise = promise + self.trigger = trigger + } + + func timeout(_ timeoutInterval: DispatchTimeInterval, forcefullyAbortTimeout: DispatchTimeInterval) -> Self { + // = Discussion = + // + // There's a lot of technical decisions here that is useful to elaborate on. This is + // definitely more lower-level than the previous NSRunLoop based implementation. + // + // + // Why Dispatch Source? + // + // + // We're using a dispatch source to have better control of the run loop behavior. + // A timer source gives us deferred-timing control without having to rely as much on + // a run loop's traditional dispatching machinery (eg - NSTimers, DefaultRunLoopMode, etc.) + // which is ripe for getting corrupted by application code. + // + // And unlike dispatch_async(), we can control how likely our code gets prioritized to + // executed (see leeway parameter) + DISPATCH_TIMER_STRICT. + // + // This timer is assumed to run on the HIGH priority queue to ensure it maintains the + // highest priority over normal application / test code when possible. + // + // + // Run Loop Management + // + // In order to properly interrupt the waiting behavior performed by this factory class, + // this timer stops the main run loop to tell the waiter code that the result should be + // checked. + // + // In addition, stopping the run loop is used to halt code executed on the main run loop. + trigger.timeoutSource.schedule( + deadline: DispatchTime.now() + timeoutInterval, + repeating: .never, + leeway: timeoutLeeway + ) + trigger.timeoutSource.setEventHandler { + guard self.promise.asyncResult.isIncomplete() else { return } + let timedOutSem = DispatchSemaphore(value: 0) + let semTimedOutOrBlocked = DispatchSemaphore(value: 0) + semTimedOutOrBlocked.signal() + let runLoop = CFRunLoopGetMain() + #if canImport(Darwin) + let runLoopMode = CFRunLoopMode.defaultMode.rawValue + #else + let runLoopMode = kCFRunLoopDefaultMode + #endif + CFRunLoopPerformBlock(runLoop, runLoopMode) { + if semTimedOutOrBlocked.wait(timeout: .now()) == .success { + timedOutSem.signal() + semTimedOutOrBlocked.signal() + if self.promise.resolveResult(.timedOut) { + CFRunLoopStop(CFRunLoopGetMain()) + } + } + } + // potentially interrupt blocking code on run loop to let timeout code run + CFRunLoopStop(runLoop) + let now = DispatchTime.now() + forcefullyAbortTimeout + let didNotTimeOut = timedOutSem.wait(timeout: now) != .success + let timeoutWasNotTriggered = semTimedOutOrBlocked.wait(timeout: .now()) == .success + if didNotTimeOut && timeoutWasNotTriggered { + if self.promise.resolveResult(.blockedRunLoop) { + CFRunLoopStop(CFRunLoopGetMain()) + } + } + } + return self + } + + /// Blocks for an asynchronous result. + /// + /// @discussion + /// This function must be executed on the main thread and cannot be nested. This is because + /// this function (and it's related methods) coordinate through the main run loop. Tampering + /// with the run loop can cause undesirable behavior. + /// + /// This method will return an AwaitResult in the following cases: + /// + /// - The main run loop is blocked by other operations and the async expectation cannot be + /// be stopped. + /// - The async expectation timed out + /// - The async expectation succeeded + /// - The async expectation raised an unexpected exception (objc) + /// - The async expectation raised an unexpected error (swift) + /// + /// The returned AwaitResult will NEVER be .incomplete. + func wait(_ fnName: String = #function, file: FileString = #file, line: UInt = #line) -> AwaitResult { + waitLock.acquireWaitingLock( + fnName, + file: file, + line: line) + + let capture = NMBExceptionCapture(handler: ({ exception in + _ = self.promise.resolveResult(.raisedException(exception)) + }), finally: ({ + self.waitLock.releaseWaitingLock() + })) + capture.tryBlock { + do { + try self.trigger.start() + } catch let error { + _ = self.promise.resolveResult(.errorThrown(error)) + } + self.trigger.timeoutSource.resume() + while self.promise.asyncResult.isIncomplete() { + // Stopping the run loop does not work unless we run only 1 mode + _ = RunLoop.current.run(mode: .default, before: .distantFuture) + } + + self.trigger.timeoutSource.cancel() + if let asyncSource = self.trigger.actionSource { + asyncSource.cancel() + } + } + + return promise.asyncResult + } +} + +internal class Awaiter { + let waitLock: WaitLock + let timeoutQueue: DispatchQueue + let asyncQueue: DispatchQueue + + internal init( + waitLock: WaitLock, + asyncQueue: DispatchQueue, + timeoutQueue: DispatchQueue) { + self.waitLock = waitLock + self.asyncQueue = asyncQueue + self.timeoutQueue = timeoutQueue + } + + private func createTimerSource(_ queue: DispatchQueue) -> DispatchSourceTimer { + return DispatchSource.makeTimerSource(flags: .strict, queue: queue) + } + + func performBlock( + file: FileString, + line: UInt, + _ closure: @escaping (@escaping (T) -> Void) throws -> Void + ) -> AwaitPromiseBuilder { + let promise = AwaitPromise() + let timeoutSource = createTimerSource(timeoutQueue) + var completionCount = 0 + let trigger = AwaitTrigger(timeoutSource: timeoutSource, actionSource: nil) { + try closure { result in + completionCount += 1 + if completionCount < 2 { + func completeBlock() { + if promise.resolveResult(.completed(result)) { + CFRunLoopStop(CFRunLoopGetMain()) + } + } + + if Thread.isMainThread { + completeBlock() + } else { + DispatchQueue.main.async { completeBlock() } + } + } else { + fail("waitUntil(..) expects its completion closure to be only called once", + file: file, line: line) + } + } + } + + return AwaitPromiseBuilder( + awaiter: self, + waitLock: waitLock, + promise: promise, + trigger: trigger) + } + + func poll(_ pollInterval: DispatchTimeInterval, closure: @escaping () throws -> T?) -> AwaitPromiseBuilder { + let promise = AwaitPromise() + let timeoutSource = createTimerSource(timeoutQueue) + let asyncSource = createTimerSource(asyncQueue) + let trigger = AwaitTrigger(timeoutSource: timeoutSource, actionSource: asyncSource) { + let interval = pollInterval + asyncSource.schedule(deadline: .now(), repeating: interval, leeway: pollLeeway) + asyncSource.setEventHandler { + do { + if let result = try closure() { + if promise.resolveResult(.completed(result)) { + CFRunLoopStop(CFRunLoopGetCurrent()) + } + } + } catch let error { + if promise.resolveResult(.errorThrown(error)) { + CFRunLoopStop(CFRunLoopGetCurrent()) + } + } + } + asyncSource.resume() + } + + return AwaitPromiseBuilder( + awaiter: self, + waitLock: waitLock, + promise: promise, + trigger: trigger) + } +} + +internal func pollBlock( + pollInterval: DispatchTimeInterval, + timeoutInterval: DispatchTimeInterval, + file: FileString, + line: UInt, + fnName: String = #function, + expression: @escaping () throws -> Bool) -> AwaitResult { + let awaiter = NimbleEnvironment.activeInstance.awaiter + let result = awaiter.poll(pollInterval) { () throws -> Bool? in + if try expression() { + return true + } + return nil + }.timeout(timeoutInterval, forcefullyAbortTimeout: timeoutInterval.divided).wait(fnName, file: file, line: line) + + return result +} + +#endif // #if !os(WASI) diff --git a/Pods/Nimble/Sources/Nimble/Utils/DispatchTimeInterval.swift b/Pods/Nimble/Sources/Nimble/Utils/DispatchTimeInterval.swift new file mode 100644 index 0000000..9583683 --- /dev/null +++ b/Pods/Nimble/Sources/Nimble/Utils/DispatchTimeInterval.swift @@ -0,0 +1,45 @@ +#if !os(WASI) + +import Dispatch + +#if canImport(CDispatch) +import CDispatch +#endif + +extension DispatchTimeInterval { + // ** Note: We cannot simply divide the time interval because DispatchTimeInterval associated value type is Int + var divided: DispatchTimeInterval { + switch self { + case let .seconds(val): return val < 2 ? .milliseconds(Int(Float(val)/2*1000)) : .seconds(val/2) + case let .milliseconds(val): return .milliseconds(val/2) + case let .microseconds(val): return .microseconds(val/2) + case let .nanoseconds(val): return .nanoseconds(val/2) + case .never: return .never + @unknown default: fatalError("Unknown DispatchTimeInterval value") + } + } + + var description: String { + switch self { + case let .seconds(val): return val == 1 ? "\(Float(val)) second" : "\(Float(val)) seconds" + case let .milliseconds(val): return "\(Float(val)/1_000) seconds" + case let .microseconds(val): return "\(Float(val)/1_000_000) seconds" + case let .nanoseconds(val): return "\(Float(val)/1_000_000_000) seconds" + default: fatalError("Unknown DispatchTimeInterval value") + } + } +} + +#if canImport(Foundation) +import typealias Foundation.TimeInterval + +extension TimeInterval { + var dispatchInterval: DispatchTimeInterval { + let microseconds = Int64(self * TimeInterval(USEC_PER_SEC)) + // perhaps use nanoseconds, though would more often be > Int.max + return microseconds < Int.max ? .microseconds(Int(microseconds)) : .seconds(Int(self)) + } +} +#endif + +#endif // #if !os(WASI) diff --git a/Pods/Nimble/Sources/Nimble/Utils/SourceLocation.swift b/Pods/Nimble/Sources/Nimble/Utils/SourceLocation.swift index 64838ff..4e37aef 100644 --- a/Pods/Nimble/Sources/Nimble/Utils/SourceLocation.swift +++ b/Pods/Nimble/Sources/Nimble/Utils/SourceLocation.swift @@ -5,7 +5,7 @@ import Foundation // stdlib, and because recent versions of the XCTest overlay require `StaticString` // when calling `XCTFail`. Under the Objective-C runtime (i.e. building on Mac), we // have to use `String` instead because StaticString can't be generated from Objective-C -#if !canImport(Darwin) +#if SWIFT_PACKAGE public typealias FileString = StaticString #else public typealias FileString = String diff --git a/Pods/Nimble/Sources/NimbleObjectiveC/DSL.h b/Pods/Nimble/Sources/NimbleObjectiveC/DSL.h new file mode 100644 index 0000000..9ae06a4 --- /dev/null +++ b/Pods/Nimble/Sources/NimbleObjectiveC/DSL.h @@ -0,0 +1,389 @@ +#import + +@class NMBExpectation; +@class NMBPredicate; +@class NMBObjCBeCloseToPredicate; +@class NMBObjCRaiseExceptionPredicate; + + +NS_ASSUME_NONNULL_BEGIN + + +#define NIMBLE_OVERLOADABLE __attribute__((overloadable)) +#define NIMBLE_EXPORT FOUNDATION_EXPORT +#define NIMBLE_EXPORT_INLINE FOUNDATION_STATIC_INLINE + +#define NIMBLE_VALUE_OF(VAL) ({ \ + __typeof__((VAL)) val = (VAL); \ + [NSValue valueWithBytes:&val objCType:@encode(__typeof__((VAL)))]; \ +}) + +#ifdef NIMBLE_DISABLE_SHORT_SYNTAX +#define NIMBLE_SHORT(PROTO, ORIGINAL) +#define NIMBLE_SHORT_OVERLOADED(PROTO, ORIGINAL) +#else +#define NIMBLE_SHORT(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE PROTO { return (ORIGINAL); } +#define NIMBLE_SHORT_OVERLOADED(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE NIMBLE_OVERLOADABLE PROTO { return (ORIGINAL); } +#endif + + + +#define DEFINE_NMB_EXPECT_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBExpectation *NMB_expect(TYPE(^actualBlock)(void), NSString *file, NSUInteger line) { \ + return NMB_expect(^id { return EXPR; }, file, line); \ + } + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + NMBExpectation *NMB_expect(id(^actualBlock)(void), NSString *file, NSUInteger line); + + // overloaded dispatch for nils - expect(nil) + DEFINE_NMB_EXPECT_OVERLOAD(void*, nil) + DEFINE_NMB_EXPECT_OVERLOAD(NSRange, NIMBLE_VALUE_OF(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(int, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned int, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(float, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(double, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(long long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned long long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(char, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned char, @(actualBlock())) + // bool doesn't get the compiler to dispatch to BOOL types, but using BOOL here seems to allow + // the compiler to dispatch to bool. + DEFINE_NMB_EXPECT_OVERLOAD(BOOL, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(char *, @(actualBlock())) + + +#undef DEFINE_NMB_EXPECT_OVERLOAD + + + +NIMBLE_EXPORT NMBExpectation *NMB_expectAction(void(^actualBlock)(void), NSString *file, NSUInteger line); + + + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBPredicate *NMB_equal(TYPE expectedValue) { \ + return NMB_equal((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(NMBPredicate *equal(TYPE expectedValue), NMB_equal(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + NMBPredicate *NMB_equal(__nullable id expectedValue); + + NIMBLE_SHORT_OVERLOADED(NMBPredicate *equal(__nullable id expectedValue), + NMB_equal(expectedValue)); + + // overloaded dispatch for nils - expect(nil) + DEFINE_OVERLOAD(void*__nullable, (id)nil) + DEFINE_OVERLOAD(NSRange, NIMBLE_VALUE_OF(expectedValue)) + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + // bool doesn't get the compiler to dispatch to BOOL types, but using BOOL here seems to allow + // the compiler to dispatch to bool. + DEFINE_OVERLOAD(BOOL, @(expectedValue)) + DEFINE_OVERLOAD(char *, @(expectedValue)) + +#undef DEFINE_OVERLOAD + + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBPredicate *NMB_haveCount(TYPE expectedValue) { \ + return NMB_haveCount((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(NMBPredicate *haveCount(TYPE expectedValue), \ + NMB_haveCount(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + NMBPredicate *NMB_haveCount(id expectedValue); + + NIMBLE_SHORT_OVERLOADED(NMBPredicate *haveCount(id expectedValue), + NMB_haveCount(expectedValue)); + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBObjCBeCloseToPredicate *NMB_beCloseTo(TYPE expectedValue) { \ + return NMB_beCloseTo((NSNumber *)(EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(NMBObjCBeCloseToPredicate *beCloseTo(TYPE expectedValue), \ + NMB_beCloseTo(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBObjCBeCloseToPredicate *NMB_beCloseTo(NSNumber *expectedValue); + NIMBLE_SHORT_OVERLOADED(NMBObjCBeCloseToPredicate *beCloseTo(NSNumber *expectedValue), + NMB_beCloseTo(expectedValue)); + + // it would be better to only overload float & double, but zero becomes ambigious + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + +NIMBLE_EXPORT NMBPredicate *NMB_beAnInstanceOf(Class expectedClass); +NIMBLE_EXPORT_INLINE NMBPredicate *beAnInstanceOf(Class expectedClass) { + return NMB_beAnInstanceOf(expectedClass); +} + +NIMBLE_EXPORT NMBPredicate *NMB_beAKindOf(Class expectedClass); +NIMBLE_EXPORT_INLINE NMBPredicate *beAKindOf(Class expectedClass) { + return NMB_beAKindOf(expectedClass); +} + +NIMBLE_EXPORT NMBPredicate *NMB_beginWith(id itemElementOrSubstring); +NIMBLE_EXPORT_INLINE NMBPredicate *beginWith(id itemElementOrSubstring) { + return NMB_beginWith(itemElementOrSubstring); +} + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBPredicate *NMB_beGreaterThan(TYPE expectedValue) { \ + return NMB_beGreaterThan((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(NMBPredicate *beGreaterThan(TYPE expectedValue), NMB_beGreaterThan(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + NMBPredicate *NMB_beGreaterThan(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + NMBPredicate *beGreaterThan(NSNumber *expectedValue) { + return NMB_beGreaterThan(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBPredicate *NMB_beGreaterThanOrEqualTo(TYPE expectedValue) { \ + return NMB_beGreaterThanOrEqualTo((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(NMBPredicate *beGreaterThanOrEqualTo(TYPE expectedValue), \ + NMB_beGreaterThanOrEqualTo(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + NMBPredicate *NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + NMBPredicate *beGreaterThanOrEqualTo(NSNumber *expectedValue) { + return NMB_beGreaterThanOrEqualTo(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + + +#undef DEFINE_OVERLOAD + +NIMBLE_EXPORT NMBPredicate *NMB_beIdenticalTo(id expectedInstance); +NIMBLE_SHORT(NMBPredicate *beIdenticalTo(id expectedInstance), + NMB_beIdenticalTo(expectedInstance)); + +NIMBLE_EXPORT NMBPredicate *NMB_be(id expectedInstance); +NIMBLE_SHORT(NMBPredicate *be(id expectedInstance), + NMB_be(expectedInstance)); + + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBPredicate *NMB_beLessThan(TYPE expectedValue) { \ + return NMB_beLessThan((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(NMBPredicate *beLessThan(TYPE expectedValue), \ + NMB_beLessThan(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + NMBPredicate *NMB_beLessThan(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + NMBPredicate *beLessThan(NSNumber *expectedValue) { + return NMB_beLessThan(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBPredicate *NMB_beLessThanOrEqualTo(TYPE expectedValue) { \ + return NMB_beLessThanOrEqualTo((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(NMBPredicate *beLessThanOrEqualTo(TYPE expectedValue), \ + NMB_beLessThanOrEqualTo(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + NMBPredicate *NMB_beLessThanOrEqualTo(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + NMBPredicate *beLessThanOrEqualTo(NSNumber *expectedValue) { + return NMB_beLessThanOrEqualTo(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + +NIMBLE_EXPORT NMBPredicate *NMB_beTruthy(void); +NIMBLE_SHORT(NMBPredicate *beTruthy(void), + NMB_beTruthy()); + +NIMBLE_EXPORT NMBPredicate *NMB_beFalsy(void); +NIMBLE_SHORT(NMBPredicate *beFalsy(void), + NMB_beFalsy()); + +NIMBLE_EXPORT NMBPredicate *NMB_beTrue(void); +NIMBLE_SHORT(NMBPredicate *beTrue(void), + NMB_beTrue()); + +NIMBLE_EXPORT NMBPredicate *NMB_beFalse(void); +NIMBLE_SHORT(NMBPredicate *beFalse(void), + NMB_beFalse()); + +NIMBLE_EXPORT NMBPredicate *NMB_beNil(void); +NIMBLE_SHORT(NMBPredicate *beNil(void), + NMB_beNil()); + +NIMBLE_EXPORT NMBPredicate *NMB_beEmpty(void); +NIMBLE_SHORT(NMBPredicate *beEmpty(void), + NMB_beEmpty()); + +NIMBLE_EXPORT NMBPredicate *NMB_containWithNilTermination(id itemOrSubstring, ...) NS_REQUIRES_NIL_TERMINATION; +#define NMB_contain(...) NMB_containWithNilTermination(__VA_ARGS__, nil) +#ifndef NIMBLE_DISABLE_SHORT_SYNTAX +#define contain(...) NMB_contain(__VA_ARGS__) +#endif + +NIMBLE_EXPORT NMBPredicate *NMB_containElementSatisfying(BOOL(^predicate)(id)); +NIMBLE_SHORT(NMBPredicate *containElementSatisfying(BOOL(^predicate)(id)), + NMB_containElementSatisfying(predicate)); + +NIMBLE_EXPORT NMBPredicate *NMB_endWith(id itemElementOrSubstring); +NIMBLE_SHORT(NMBPredicate *endWith(id itemElementOrSubstring), + NMB_endWith(itemElementOrSubstring)); + +NIMBLE_EXPORT NMBObjCRaiseExceptionPredicate *NMB_raiseException(void); +NIMBLE_SHORT(NMBObjCRaiseExceptionPredicate *raiseException(void), + NMB_raiseException()); + +NIMBLE_EXPORT NMBPredicate *NMB_match(id expectedValue); +NIMBLE_SHORT(NMBPredicate *match(id expectedValue), + NMB_match(expectedValue)); + +NIMBLE_EXPORT NMBPredicate *NMB_allPass(id matcher); +NIMBLE_SHORT(NMBPredicate *allPass(id matcher), + NMB_allPass(matcher)); + +NIMBLE_EXPORT NMBPredicate *NMB_satisfyAnyOfWithMatchers(id matchers); +#define NMB_satisfyAnyOf(...) NMB_satisfyAnyOfWithMatchers(@[__VA_ARGS__]) +#ifndef NIMBLE_DISABLE_SHORT_SYNTAX +#define satisfyAnyOf(...) NMB_satisfyAnyOf(__VA_ARGS__) +#endif + +NIMBLE_EXPORT NMBPredicate *NMB_satisfyAllOfWithMatchers(id matchers); +#define NMB_satisfyAllOf(...) NMB_satisfyAllOfWithMatchers(@[__VA_ARGS__]) +#ifndef NIMBLE_DISABLE_SHORT_SYNTAX +#define satisfyAllOf(...) NMB_satisfyAllOf(__VA_ARGS__) +#endif + +// In order to preserve breakpoint behavior despite using macros to fill in __FILE__ and __LINE__, +// define a builder that populates __FILE__ and __LINE__, and returns a block that takes timeout +// and action arguments. See https://github.com/Quick/Quick/pull/185 for details. +typedef void (^NMBWaitUntilTimeoutBlock)(NSTimeInterval timeout, void (^action)(void (^)(void))); +typedef void (^NMBWaitUntilBlock)(void (^action)(void (^)(void))); + +NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line); + +NIMBLE_EXPORT NMBWaitUntilTimeoutBlock NMB_waitUntilTimeoutBuilder(NSString *file, NSUInteger line); +NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger line); + +NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line); + +#define NMB_waitUntilTimeout NMB_waitUntilTimeoutBuilder(@(__FILE__), __LINE__) +#define NMB_waitUntil NMB_waitUntilBuilder(@(__FILE__), __LINE__) + +#ifndef NIMBLE_DISABLE_SHORT_SYNTAX +#define expect(...) NMB_expect(^{ return (__VA_ARGS__); }, @(__FILE__), __LINE__) +#define expectAction(BLOCK) NMB_expectAction((BLOCK), @(__FILE__), __LINE__) +#define failWithMessage(msg) NMB_failWithMessage(msg, @(__FILE__), __LINE__) +#define fail() failWithMessage(@"fail() always fails") + + +#define waitUntilTimeout NMB_waitUntilTimeout +#define waitUntil NMB_waitUntil + +#undef NIMBLE_VALUE_OF + +#endif + +NS_ASSUME_NONNULL_END diff --git a/Pods/Nimble/Sources/NimbleObjectiveC/DSL.m b/Pods/Nimble/Sources/NimbleObjectiveC/DSL.m index 2ab37ef..6f7572f 100644 --- a/Pods/Nimble/Sources/NimbleObjectiveC/DSL.m +++ b/Pods/Nimble/Sources/NimbleObjectiveC/DSL.m @@ -1,14 +1,10 @@ -#import "DSL.h" +#import -#if SWIFT_PACKAGE -@import Nimble; -#else #if __has_include("Nimble-Swift.h") #import "Nimble-Swift.h" #else #import #endif -#endif NS_ASSUME_NONNULL_BEGIN @@ -32,71 +28,71 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBExpectation failWithMessage:msg file:file line:line]; } -NIMBLE_EXPORT NMBMatcher *NMB_beAnInstanceOf(Class expectedClass) { - return [NMBMatcher beAnInstanceOfMatcher:expectedClass]; +NIMBLE_EXPORT NMBPredicate *NMB_beAnInstanceOf(Class expectedClass) { + return [NMBPredicate beAnInstanceOfMatcher:expectedClass]; } -NIMBLE_EXPORT NMBMatcher *NMB_beAKindOf(Class expectedClass) { - return [NMBMatcher beAKindOfMatcher:expectedClass]; +NIMBLE_EXPORT NMBPredicate *NMB_beAKindOf(Class expectedClass) { + return [NMBPredicate beAKindOfMatcher:expectedClass]; } -NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue) { - return [NMBMatcher beCloseToMatcher:expectedValue within:0.001]; +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBObjCBeCloseToPredicate *NMB_beCloseTo(NSNumber *expectedValue) { + return [NMBPredicate beCloseToMatcher:expectedValue within:0.001]; } -NIMBLE_EXPORT NMBMatcher *NMB_beginWith(id itemElementOrSubstring) { - return [NMBMatcher beginWithMatcher:itemElementOrSubstring]; +NIMBLE_EXPORT NMBPredicate *NMB_beginWith(id itemElementOrSubstring) { + return [NMBPredicate beginWithMatcher:itemElementOrSubstring]; } -NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBMatcher *NMB_beGreaterThan(NSNumber *expectedValue) { - return [NMBMatcher beGreaterThanMatcher:expectedValue]; +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBPredicate *NMB_beGreaterThan(NSNumber *expectedValue) { + return [NMBPredicate beGreaterThanMatcher:expectedValue]; } -NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBMatcher *NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue) { - return [NMBMatcher beGreaterThanOrEqualToMatcher:expectedValue]; +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBPredicate *NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue) { + return [NMBPredicate beGreaterThanOrEqualToMatcher:expectedValue]; } -NIMBLE_EXPORT NMBMatcher *NMB_beIdenticalTo(id expectedInstance) { - return [NMBMatcher beIdenticalToMatcher:expectedInstance]; +NIMBLE_EXPORT NMBPredicate *NMB_beIdenticalTo(id expectedInstance) { + return [NMBPredicate beIdenticalToMatcher:expectedInstance]; } -NIMBLE_EXPORT NMBMatcher *NMB_be(id expectedInstance) { - return [NMBMatcher beIdenticalToMatcher:expectedInstance]; +NIMBLE_EXPORT NMBPredicate *NMB_be(id expectedInstance) { + return [NMBPredicate beIdenticalToMatcher:expectedInstance]; } -NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBMatcher *NMB_beLessThan(NSNumber *expectedValue) { - return [NMBMatcher beLessThanMatcher:expectedValue]; +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBPredicate *NMB_beLessThan(NSNumber *expectedValue) { + return [NMBPredicate beLessThanMatcher:expectedValue]; } -NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBMatcher *NMB_beLessThanOrEqualTo(NSNumber *expectedValue) { - return [NMBMatcher beLessThanOrEqualToMatcher:expectedValue]; +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBPredicate *NMB_beLessThanOrEqualTo(NSNumber *expectedValue) { + return [NMBPredicate beLessThanOrEqualToMatcher:expectedValue]; } -NIMBLE_EXPORT NMBMatcher *NMB_beTruthy(void) { - return [NMBMatcher beTruthyMatcher]; +NIMBLE_EXPORT NMBPredicate *NMB_beTruthy() { + return [NMBPredicate beTruthyMatcher]; } -NIMBLE_EXPORT NMBMatcher *NMB_beFalsy(void) { - return [NMBMatcher beFalsyMatcher]; +NIMBLE_EXPORT NMBPredicate *NMB_beFalsy() { + return [NMBPredicate beFalsyMatcher]; } -NIMBLE_EXPORT NMBMatcher *NMB_beTrue(void) { - return [NMBMatcher beTrueMatcher]; +NIMBLE_EXPORT NMBPredicate *NMB_beTrue() { + return [NMBPredicate beTrueMatcher]; } -NIMBLE_EXPORT NMBMatcher *NMB_beFalse(void) { - return [NMBMatcher beFalseMatcher]; +NIMBLE_EXPORT NMBPredicate *NMB_beFalse() { + return [NMBPredicate beFalseMatcher]; } -NIMBLE_EXPORT NMBMatcher *NMB_beNil(void) { - return [NMBMatcher beNilMatcher]; +NIMBLE_EXPORT NMBPredicate *NMB_beNil() { + return [NMBPredicate beNilMatcher]; } -NIMBLE_EXPORT NMBMatcher *NMB_beEmpty(void) { - return [NMBMatcher beEmptyMatcher]; +NIMBLE_EXPORT NMBPredicate *NMB_beEmpty() { + return [NMBPredicate beEmptyMatcher]; } -NIMBLE_EXPORT NMBMatcher *NMB_containWithNilTermination(id itemOrSubstring, ...) { +NIMBLE_EXPORT NMBPredicate *NMB_containWithNilTermination(id itemOrSubstring, ...) { NSMutableArray *itemOrSubstringArray = [NSMutableArray array]; if (itemOrSubstring) { @@ -111,46 +107,44 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger va_end(args); } - return [NMBMatcher containMatcher:itemOrSubstringArray]; + return [NMBPredicate containMatcher:itemOrSubstringArray]; } -NIMBLE_EXPORT NMBMatcher *NMB_containElementSatisfying(BOOL(^matcher)(id)) { - return [NMBMatcher containElementSatisfyingMatcher:matcher]; +NIMBLE_EXPORT NMBPredicate *NMB_containElementSatisfying(BOOL(^predicate)(id)) { + return [NMBPredicate containElementSatisfyingMatcher:predicate]; } -NIMBLE_EXPORT NMBMatcher *NMB_endWith(id itemElementOrSubstring) { - return [NMBMatcher endWithMatcher:itemElementOrSubstring]; +NIMBLE_EXPORT NMBPredicate *NMB_endWith(id itemElementOrSubstring) { + return [NMBPredicate endWithMatcher:itemElementOrSubstring]; } -NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBMatcher *NMB_equal(__nullable id expectedValue) { - return [NMBMatcher equalMatcher:expectedValue]; +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBPredicate *NMB_equal(__nullable id expectedValue) { + return [NMBPredicate equalMatcher:expectedValue]; } -NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBMatcher *NMB_haveCount(id expectedValue) { - return [NMBMatcher haveCountMatcher:expectedValue]; +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBPredicate *NMB_haveCount(id expectedValue) { + return [NMBPredicate haveCountMatcher:expectedValue]; } -NIMBLE_EXPORT NMBMatcher *NMB_match(id expectedValue) { - return [NMBMatcher matchMatcher:expectedValue]; +NIMBLE_EXPORT NMBPredicate *NMB_match(id expectedValue) { + return [NMBPredicate matchMatcher:expectedValue]; } -NIMBLE_EXPORT NMBMatcher *NMB_allPass(id expectedValue) { - return [NMBMatcher allPassMatcher:expectedValue]; +NIMBLE_EXPORT NMBPredicate *NMB_allPass(id expectedValue) { + return [NMBPredicate allPassMatcher:expectedValue]; } -NIMBLE_EXPORT NMBMatcher *NMB_satisfyAnyOfWithMatchers(id matchers) { - return [NMBMatcher satisfyAnyOfMatcher:matchers]; +NIMBLE_EXPORT NMBPredicate *NMB_satisfyAnyOfWithMatchers(id matchers) { + return [NMBPredicate satisfyAnyOfMatcher:matchers]; } -NIMBLE_EXPORT NMBMatcher *NMB_satisfyAllOfWithMatchers(id matchers) { - return [NMBMatcher satisfyAllOfMatcher:matchers]; +NIMBLE_EXPORT NMBPredicate *NMB_satisfyAllOfWithMatchers(id matchers) { + return [NMBPredicate satisfyAllOfMatcher:matchers]; } -#if !SWIFT_PACKAGE -NIMBLE_EXPORT NMBObjCRaiseExceptionMatcher *NMB_raiseException(void) { - return [NMBMatcher raiseExceptionMatcher]; +NIMBLE_EXPORT NMBObjCRaiseExceptionPredicate *NMB_raiseException() { + return [NMBPredicate raiseExceptionMatcher]; } -#endif NIMBLE_EXPORT NMBWaitUntilTimeoutBlock NMB_waitUntilTimeoutBuilder(NSString *file, NSUInteger line) { return ^(NSTimeInterval timeout, void (^ _Nonnull action)(void (^ _Nonnull)(void))) { diff --git a/Pods/Nimble/Sources/NimbleObjectiveC/NMBExceptionCapture.h b/Pods/Nimble/Sources/NimbleObjectiveC/NMBExceptionCapture.h new file mode 100644 index 0000000..e6e0272 --- /dev/null +++ b/Pods/Nimble/Sources/NimbleObjectiveC/NMBExceptionCapture.h @@ -0,0 +1,11 @@ +#import +#import + +@interface NMBExceptionCapture : NSObject + +- (nonnull instancetype)initWithHandler:(void(^ _Nullable)(NSException * _Nonnull))handler finally:(void(^ _Nullable)(void))finally; +- (void)tryBlock:(__attribute__((noescape)) void(^ _Nonnull)(void))unsafeBlock NS_SWIFT_NAME(tryBlock(_:)); + +@end + +typedef void(^NMBSourceCallbackBlock)(BOOL successful); diff --git a/Pods/Nimble/Sources/NimbleObjectiveC/NMBStringify.h b/Pods/Nimble/Sources/NimbleObjectiveC/NMBStringify.h new file mode 100644 index 0000000..7938bca --- /dev/null +++ b/Pods/Nimble/Sources/NimbleObjectiveC/NMBStringify.h @@ -0,0 +1,18 @@ +@class NSString; + +/** + * Returns a string appropriate for displaying in test output + * from the provided value. + * + * @param anyObject A value that will show up in a test's output. + * + * @return The string that is returned can be + * customized per type by conforming a type to the `TestOutputStringConvertible` + * protocol. When stringifying a non-`TestOutputStringConvertible` type, this + * function will return the value's debug description and then its + * normal description if available and in that order. Otherwise it + * will return the result of constructing a string from the value. + * + * @see `TestOutputStringConvertible` + */ +extern NSString *_Nonnull NMBStringify(id _Nullable anyObject) __attribute__((warn_unused_result)); diff --git a/Pods/Nimble/Sources/NimbleObjectiveC/NMBStringify.m b/Pods/Nimble/Sources/NimbleObjectiveC/NMBStringify.m index 5890e22..31a80d6 100644 --- a/Pods/Nimble/Sources/NimbleObjectiveC/NMBStringify.m +++ b/Pods/Nimble/Sources/NimbleObjectiveC/NMBStringify.m @@ -1,14 +1,10 @@ #import "NMBStringify.h" -#if SWIFT_PACKAGE -@import Nimble; -#else #if __has_include("Nimble-Swift.h") #import "Nimble-Swift.h" #else #import #endif -#endif NSString *_Nonnull NMBStringify(id _Nullable anyObject) { return [NMBStringer stringify:anyObject]; diff --git a/Pods/Nimble/Sources/NimbleObjectiveC/XCTestObservationCenter+Register.m b/Pods/Nimble/Sources/NimbleObjectiveC/XCTestObservationCenter+Register.m index 4f1ce63..3c1110b 100644 --- a/Pods/Nimble/Sources/NimbleObjectiveC/XCTestObservationCenter+Register.m +++ b/Pods/Nimble/Sources/NimbleObjectiveC/XCTestObservationCenter+Register.m @@ -1,14 +1,10 @@ #import -#if SWIFT_PACKAGE -@import Nimble; -#else #if __has_include("Nimble-Swift.h") #import "Nimble-Swift.h" #else #import #endif -#endif #pragma mark - Private diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 857b93b..451c2cc 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -149,7 +149,7 @@ 0A6115706ED27012A9F43E253D3D3DD7 /* QuickSpecBase.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = QuickSpecBase.m; path = Sources/QuickObjCRuntime/QuickSpecBase.m; sourceTree = ""; }; 0B2A30FEA2214E06D065AE8997736B53 /* CwlCatchException.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CwlCatchException.swift; path = Carthage/Checkouts/CwlCatchException/Sources/CwlCatchException/CwlCatchException.swift; sourceTree = ""; }; 0BB908657F2C86943C6660C8F0130CEB /* XCTestSuite+QuickTestSuiteBuilder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "XCTestSuite+QuickTestSuiteBuilder.m"; path = "Sources/QuickObjectiveC/XCTestSuite+QuickTestSuiteBuilder.m"; sourceTree = ""; }; - 0D631E9908483F9525A6B3F36F16CC61 /* Quick */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Quick; path = Quick.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 0D631E9908483F9525A6B3F36F16CC61 /* Quick.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Quick.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 0D904E98038DAE649AA050DAE20B884A /* Pods-OSPaymentsLib-OSPaymentsLibTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-OSPaymentsLib-OSPaymentsLibTests.modulemap"; sourceTree = ""; }; 0F4A8507ACE009C2C0F45E1FDED202C7 /* NMBExpectation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NMBExpectation.swift; path = Sources/Nimble/Adapters/NMBExpectation.swift; sourceTree = ""; }; 107B1F29BE07EF1662B3B4BF2A9E0BE9 /* Pods-OSPaymentsLib-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-OSPaymentsLib-acknowledgements.plist"; sourceTree = ""; }; @@ -222,7 +222,7 @@ 81CA9AA102BC399952DACFC1F5740345 /* NMBExceptionCapture.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = NMBExceptionCapture.m; path = Sources/NimbleObjectiveC/NMBExceptionCapture.m; sourceTree = ""; }; 8270027ACBF7A64C2B453CCBFE155E90 /* Nimble.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Nimble.debug.xcconfig; sourceTree = ""; }; 844435B050856A3A90F2F2DC5D10C71E /* Equal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Equal.swift; path = Sources/Nimble/Matchers/Equal.swift; sourceTree = ""; }; - 8470BE37EE9259F9FDADDFC80764A837 /* mach_excServer.c */ = {isa = PBXFileReference; includeInIndex = 1; name = mach_excServer.c; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.c; sourceTree = ""; }; + 8470BE37EE9259F9FDADDFC80764A837 /* mach_excServer.c */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.c; name = mach_excServer.c; path = Carthage/Checkouts/CwlPreconditionTesting/Sources/CwlMachBadInstructionHandler/mach_excServer.c; sourceTree = ""; }; 84CC299AC522B25A61A3FAF124FF83FC /* ContainElementSatisfying.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ContainElementSatisfying.swift; path = Sources/Nimble/Matchers/ContainElementSatisfying.swift; sourceTree = ""; }; 85254BDDFDC46F27B70DCBF181ADE6FF /* ThrowAssertion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThrowAssertion.swift; path = Sources/Nimble/Matchers/ThrowAssertion.swift; sourceTree = ""; }; 85C9317EF9B3052FC9D544E30801F901 /* Expectation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Expectation.swift; path = Sources/Nimble/Expectation.swift; sourceTree = ""; }; @@ -234,7 +234,7 @@ 9215339C71BDBD5B494E9EFD44005158 /* NimbleEnvironment.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NimbleEnvironment.swift; path = Sources/Nimble/Adapters/NimbleEnvironment.swift; sourceTree = ""; }; 97522C7BBA1F97437715C74303E5A686 /* NMBStringify.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = NMBStringify.m; path = Sources/NimbleObjectiveC/NMBStringify.m; sourceTree = ""; }; 9AA80CEA9B4992D8F9368CEE01A42094 /* BeGreaterThan.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeGreaterThan.swift; path = Sources/Nimble/Matchers/BeGreaterThan.swift; sourceTree = ""; }; - 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; A12262F224D0D0A168C398C49F628A15 /* AllPass.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AllPass.swift; path = Sources/Nimble/Matchers/AllPass.swift; sourceTree = ""; }; A16B8BD1EFF8AB8B6940E1EC149FD38A /* DSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DSL.swift; path = Sources/Nimble/DSL.swift; sourceTree = ""; }; A1E026C7DAC445C7C813121DE7F03837 /* Async.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Async.swift; path = Sources/Nimble/Matchers/Async.swift; sourceTree = ""; }; @@ -244,7 +244,7 @@ B1D21BE1B5A742AA9C8EEE801D57559C /* Pods-OSPaymentsLib-OSPaymentsLibTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-OSPaymentsLib-OSPaymentsLibTests-umbrella.h"; sourceTree = ""; }; B22103AE676FAE45408C0FFCD20688FE /* Pods-OSPaymentsLib-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-OSPaymentsLib-Info.plist"; sourceTree = ""; }; B534FC537F198D4CB2269C659A93783F /* BeAnInstanceOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeAnInstanceOf.swift; path = Sources/Nimble/Matchers/BeAnInstanceOf.swift; sourceTree = ""; }; - BAE263041362D074978BB3B577DF0A05 /* Nimble */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Nimble; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BAE263041362D074978BB3B577DF0A05 /* Nimble.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BB5D7CE0E6246798ABFD9DAAE4915E71 /* Nimble-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Nimble-Info.plist"; sourceTree = ""; }; BBA4F4C4573FD9589D1CA0CA3DD18A0C /* BeResult.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BeResult.swift; path = Sources/Nimble/Matchers/BeResult.swift; sourceTree = ""; }; BEB97334DF3B76513D34EB7C70369D82 /* Pods-OSPaymentsLib-OSPaymentsLibTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-OSPaymentsLib-OSPaymentsLibTests.release.xcconfig"; sourceTree = ""; }; @@ -424,7 +424,6 @@ E2FF0C6AC202911FB7A52FE099B9B734 /* XCTestObservationCenter+Register.m */, 14663555BFC9D8228B23F8DA0E5EC5BD /* Support Files */, ); - name = Nimble; path = Nimble; sourceTree = ""; }; @@ -455,10 +454,10 @@ 6ED66B56EF14ED94784F9F705A021130 /* Products */ = { isa = PBXGroup; children = ( - BAE263041362D074978BB3B577DF0A05 /* Nimble */, + BAE263041362D074978BB3B577DF0A05 /* Nimble.framework */, C914B482E199C7EDA35291B58CEC2E5E /* Pods-OSPaymentsLib */, E6BD0403A56EB6AA58FE2224C68F73C4 /* Pods-OSPaymentsLib-OSPaymentsLibTests */, - 0D631E9908483F9525A6B3F36F16CC61 /* Quick */, + 0D631E9908483F9525A6B3F36F16CC61 /* Quick.framework */, ); name = Products; sourceTree = ""; @@ -510,7 +509,6 @@ 0BB908657F2C86943C6660C8F0130CEB /* XCTestSuite+QuickTestSuiteBuilder.m */, 3FBC8250D8902D858BF14BCFE2C4831B /* Support Files */, ); - name = Quick; path = Quick; sourceTree = ""; }; @@ -671,7 +669,7 @@ ); name = Nimble; productName = Nimble; - productReference = BAE263041362D074978BB3B577DF0A05 /* Nimble */; + productReference = BAE263041362D074978BB3B577DF0A05 /* Nimble.framework */; productType = "com.apple.product-type.framework"; }; C82891EAB7293DBEE916B21F57E8474D /* Quick */ = { @@ -689,7 +687,7 @@ ); name = Quick; productName = Quick; - productReference = 0D631E9908483F9525A6B3F36F16CC61 /* Quick */; + productReference = 0D631E9908483F9525A6B3F36F16CC61 /* Quick.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -698,8 +696,8 @@ BFDFE7DC352907FC980B868725387E98 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1300; - LastUpgradeCheck = 1300; + LastSwiftUpdateCheck = 1240; + LastUpgradeCheck = 1340; }; buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 13.0"; @@ -947,7 +945,7 @@ GCC_PREFIX_HEADER = "Target Support Files/Nimble/Nimble-prefix.pch"; INFOPLIST_FILE = "Target Support Files/Nimble/Nimble-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1018,7 +1016,7 @@ GCC_PREFIX_HEADER = "Target Support Files/Nimble/Nimble-prefix.pch"; INFOPLIST_FILE = "Target Support Files/Nimble/Nimble-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1051,7 +1049,7 @@ GCC_PREFIX_HEADER = "Target Support Files/Quick/Quick-prefix.pch"; INFOPLIST_FILE = "Target Support Files/Quick/Quick-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1251,7 +1249,7 @@ GCC_PREFIX_HEADER = "Target Support Files/Quick/Quick-prefix.pch"; INFOPLIST_FILE = "Target Support Files/Quick/Quick-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/Pods/Quick/README.md b/Pods/Quick/README.md index af35f20..98dbdec 100644 --- a/Pods/Quick/README.md +++ b/Pods/Quick/README.md @@ -17,7 +17,7 @@ import Quick import Nimble class TableOfContentsSpec: QuickSpec { - override class func spec() { + override func spec() { describe("the 'Documentation' directory") { it("has everything you need to get started") { let sections = Directory("Documentation").sections @@ -51,7 +51,7 @@ Certain versions of Quick and Nimble only support certain versions of Swift. Dep ## Documentation -All documentation can be found in the [Documentation folder](./Documentation), including [detailed installation instructions](./Documentation/en-us/InstallingQuick.md) for CocoaPods, Carthage, Git submodules, Swift Package Manager, and more. For example, you can install Quick and [Nimble](https://github.com/Quick/Nimble) using CocoaPods by adding the following to your `Podfile`: +All documentation can be found in the [Documentation folder](./Documentation), including [detailed installation instructions](./Documentation/en-us/InstallingQuick.md) for CocoaPods, Carthage, Git submodules, and more. For example, you can install Quick and [Nimble](https://github.com/Quick/Nimble) using CocoaPods by adding the following to your Podfile: ```rb # Podfile @@ -61,8 +61,10 @@ use_frameworks! target "MyApp" do # Normal libraries - target 'MyApp_Tests' do + abstract_target 'Tests' do inherit! :search_paths + target "MyAppTests" + target "MyAppUITests" pod 'Quick' pod 'Nimble' @@ -70,15 +72,6 @@ target "MyApp" do end ``` -You can also install Quick and Nimble using Swift Package Manager by adding the following to the dependencies section your `Package.swift`: - -```swift -dependencies: [ - .package(url: "https://github.com/Quick/Quick.git", from: "7.0.0"), - .package(url: "https://github.com/Quick/Nimble.git", from: "12.0.0"), -], -``` - ## Projects using Quick Over ten-thousand apps use either Quick and Nimble however, as they are not included in the app binary, neither appear in “Top Used Libraries” blog posts. Therefore, it would be greatly appreciated to remind contributors that their efforts are valued by compiling a list of organizations and projects that use them. @@ -91,12 +84,6 @@ Similar to projects using Quick, it would be nice to hear why people use Quick a Have something positive to say about Quick (or Nimble)? If yes, [provide a testimonial here](https://github.com/Quick/Quick/wiki/Who-uses-Quick). -## Privacy Statement - -Quick is a library that is only used for testing and should never be included in the binary submitted to App Store Connect. -Your app will be rejected if you do include Quick in the submitted binary because Quick uses private APIs to better integrate with Xcode. - -Despite not being shipped to Apple, Quick does not and will never collect any kind of analytics or tracking. ## License diff --git a/Pods/Quick/Sources/Quick/Callsite.swift b/Pods/Quick/Sources/Quick/Callsite.swift index 502a9d5..33e732c 100644 --- a/Pods/Quick/Sources/Quick/Callsite.swift +++ b/Pods/Quick/Sources/Quick/Callsite.swift @@ -14,7 +14,7 @@ public class _CallsiteBase: NSObject {} // stdlib, and because recent versions of the XCTest overlay require `StaticString` // when calling `XCTFail`. Under the Objective-C runtime (i.e. building on macOS), we // have to use `String` instead because StaticString can't be generated from Objective-C -#if !canImport(Darwin) +#if SWIFT_PACKAGE public typealias FileString = StaticString #else public typealias FileString = String diff --git a/Pods/Quick/Sources/Quick/Configuration/QCKConfiguration.swift b/Pods/Quick/Sources/Quick/Configuration/QCKConfiguration.swift index 01de905..35735a2 100644 --- a/Pods/Quick/Sources/Quick/Configuration/QCKConfiguration.swift +++ b/Pods/Quick/Sources/Quick/Configuration/QCKConfiguration.swift @@ -10,7 +10,7 @@ public typealias QuickConfigurer = (_ configuration: QCKConfiguration) -> Void A closure that, given metadata about an example, returns a boolean value indicating whether that example should be run. */ -public typealias ExampleFilter = (_ example: ExampleBase) -> Bool +public typealias ExampleFilter = (_ example: Example) -> Bool /** A configuration encapsulates various options you can use @@ -18,7 +18,6 @@ public typealias ExampleFilter = (_ example: ExampleBase) -> Bool */ final public class QCKConfiguration: NSObject { internal let exampleHooks = ExampleHooks() - internal let asyncExampleHooks = AsyncExampleHooks() internal let suiteHooks = SuiteHooks() internal var exclusionFilters: [ExampleFilter] = [ { example in // swiftlint:disable:this opening_brace @@ -76,37 +75,15 @@ final public class QCKConfiguration: NSObject { Identical to Quick.QCKConfiguration.beforeEach, except the closure is provided with metadata on the example that the closure is being run prior to. - - - Important: This automatically bridges between async and sync specs. When running on AsyncSpecs, this closure will run on the main actor. */ #if canImport(Darwin) @objc(beforeEachWithMetadata:) - public func objc_beforeEach(_ closure: @escaping BeforeExampleWithMetadataNonThrowingClosure) { - exampleHooks.appendBefore(closure) - asyncExampleHooks.appendBefore { exampleMetadata in - await MainActor.run { - closure(exampleMetadata) - } - } - } - - @nonobjc public func beforeEach(_ closure: @escaping BeforeExampleWithMetadataClosure) { exampleHooks.appendBefore(closure) - asyncExampleHooks.appendBefore { exampleMetadata in - try await MainActor.run { - try closure(exampleMetadata) - } - } } #else public func beforeEach(_ closure: @escaping BeforeExampleWithMetadataClosure) { exampleHooks.appendBefore(closure) - asyncExampleHooks.appendBefore { exampleMetadata in - try await MainActor.run { - try closure(exampleMetadata) - } - } } #endif @@ -126,51 +103,24 @@ final public class QCKConfiguration: NSObject { - parameter closure: The closure to be executed before each example in the test suite. - - - Important: This automatically bridges between async and sync specs. When running on AsyncSpecs, this closure will run on the main actor. */ public func beforeEach(_ closure: @escaping BeforeExampleClosure) { exampleHooks.appendBefore(closure) - asyncExampleHooks.appendBefore { @MainActor in - try closure() - } } /** Identical to Quick.QCKConfiguration.afterEach, except the closure is provided with metadata on the example that the closure is being run after. - - - Important: This automatically bridges between async and sync specs. When running on AsyncSpecs, this closure will run on the main actor. */ #if canImport(Darwin) @objc(afterEachWithMetadata:) - public func objc_afterEach(_ closure: @escaping AfterExampleWithMetadataNonThrowingClosure) { - exampleHooks.appendAfter(closure) - asyncExampleHooks.appendAfter { exampleMetadata in - await MainActor.run { - closure(exampleMetadata) - } - } - } - - @nonobjc public func afterEach(_ closure: @escaping AfterExampleWithMetadataClosure) { exampleHooks.appendAfter(closure) - asyncExampleHooks.appendAfter { exampleMetadata in - try await MainActor.run { - try closure(exampleMetadata) - } - } } #else public func afterEach(_ closure: @escaping AfterExampleWithMetadataClosure) { exampleHooks.appendAfter(closure) - asyncExampleHooks.appendAfter { exampleMetadata in - try await MainActor.run { - try closure(exampleMetadata) - } - } } #endif @@ -190,14 +140,9 @@ final public class QCKConfiguration: NSObject { - parameter closure: The closure to be executed before each example in the test suite. - - - Important: This automatically bridges between async and sync specs. When running on AsyncSpecs, this closure will run on the main actor. */ public func afterEach(_ closure: @escaping AfterExampleClosure) { exampleHooks.appendAfter(closure) - asyncExampleHooks.appendAfter { @MainActor in - try closure() - } } /** @@ -216,70 +161,23 @@ final public class QCKConfiguration: NSObject { - parameter closure: The closure to be executed before each example in the test suite. - - - warning: Unlike ``beforeEach`` and ``afterEach``, aroundEach does not automatically bridge between async and sync expectations. - - - SeeAlso: ``aroundEach(_:)-6ptvt`` for the async version. */ public func aroundEach(_ closure: @escaping AroundExampleClosure) { exampleHooks.appendAround(closure) } /** - Like Quick.DSL.aroundEach, this configures Quick to wrap each example - with the given closure. The closure passed to this method will wrap - all examples globally across the test suite. You may call this method - multiple times across multiple +[QuickConfigure configure:] methods in - order to define several closures to wrap all examples. - - Note that, since Quick makes no guarantee as to the order in which - +[QuickConfiguration configure:] methods are evaluated, there is no - guarantee as to the order in which aroundEach closures are evaluated. - However, aroundEach does always guarantee proper nesting of operations: - cleanup within aroundEach closures will always happen in the reverse order - of setup. - - - parameter closure: The closure to be executed before each example - in the test suite. - - - warning: Unlike ``beforeEach`` and ``afterEach``, aroundEach does not automatically bridge between async and sync expectations. - - - SeeAlso: ``aroundEach(_:)-5z8vj`` for the sync version. - */ - public func aroundEach(_ closure: @escaping AroundExampleAsyncClosure) { - asyncExampleHooks.appendAround(closure) - } - - /** - Identical to ``aroundEach(_:)-5z8vj``, except the closure receives + Identical to Quick.QCKConfiguration.aroundEach, except the closure receives metadata about the example that the closure wraps. - - - warning: Unlike ``beforeEach`` and ``afterEach``, aroundEach does not automatically bridge between async and sync expectations. - - - SeeAlso: ``aroundEach(_:)-2xmgx`` for the async version. */ public func aroundEach(_ closure: @escaping AroundExampleWithMetadataClosure) { exampleHooks.appendAround(closure) } - /** - Identical to ``aroundEach(_:)-6ptvt``, except the closure receives - metadata about the example that the closure wraps. - - - warning: Unlike ``beforeEach`` and ``afterEach``, aroundEach does not automatically bridge between async and sync expectations. - - - SeeAlso: ``aroundEach(_:)-2xmgx`` for the sync version. - */ - public func aroundEach(_ closure: @escaping AroundExampleWithMetadataAsyncClosure) { - asyncExampleHooks.appendAround(closure) - } - /** Like Quick.DSL.beforeSuite, this configures Quick to execute the given closure prior to any and all examples that are run. The two methods are functionally equivalent. - - - Important: This automatically bridges between async and sync specs. When running on AsyncSpecs, this closure will run on the main actor. */ public func beforeSuite(_ closure: @escaping BeforeSuiteClosure) { suiteHooks.appendBefore(closure) @@ -289,8 +187,6 @@ final public class QCKConfiguration: NSObject { Like Quick.DSL.afterSuite, this configures Quick to execute the given closure after all examples have been run. The two methods are functionally equivalent. - - - Important: This automatically bridges between async and sync specs. When running on AsyncSpecs, this closure will run on the main actor. */ public func afterSuite(_ closure: @escaping AfterSuiteClosure) { suiteHooks.appendAfter(closure) diff --git a/Pods/Quick/Sources/Quick/Configuration/QuickConfiguration.swift b/Pods/Quick/Sources/Quick/Configuration/QuickConfiguration.swift index a1e879e..6cc4481 100644 --- a/Pods/Quick/Sources/Quick/Configuration/QuickConfiguration.swift +++ b/Pods/Quick/Sources/Quick/Configuration/QuickConfiguration.swift @@ -3,35 +3,51 @@ import XCTest #if SWIFT_PACKAGE -/** - Subclass QuickConfiguration and override the `configure(_:)` class - method in order to configure how Quick behaves when running specs, or to define - shared examples that are used across spec files. - */ open class QuickConfiguration: NSObject { - /** - This method is executed on each subclass of this class before Quick runs - any examples. You may override this method on as many subclasses as you like, but - there is no guarantee as to the order in which these methods are executed. - - You can override this method in order to: - - 1. Configure how Quick behaves, by modifying properties on the Configuration object. - Setting the same properties in several methods has undefined behavior. - - 2. Define shared examples using `sharedExamples`. - - - Parameter configuration: A mutable object that is used to configure how Quick behaves on - a framework level. For details on all the options, see the - documentation in QCKConfiguration.swift. - */ open class func configure(_ configuration: QCKConfiguration) {} } #endif extension QuickConfiguration { + #if !canImport(Darwin) private static var configurationSubclasses: [QuickConfiguration.Type] = [] + #endif + + /// Finds all direct subclasses of QuickConfiguration and passes them to the block provided. + /// The classes are iterated over in the order that objc_getClassList returns them. + /// + /// - parameter block: A block that takes a QuickConfiguration.Type. + /// This block will be executed once for each subclass of QuickConfiguration. + private static func enumerateSubclasses(_ block: (QuickConfiguration.Type) -> Void) { + #if canImport(Darwin) + let classesCount = objc_getClassList(nil, 0) + + guard classesCount > 0 else { + return + } + + let classes = UnsafeMutablePointer.allocate(capacity: Int(classesCount)) + defer { free(classes) } + + let autoreleasingClasses = AutoreleasingUnsafeMutablePointer(classes) + objc_getClassList(autoreleasingClasses, classesCount) + + var configurationSubclasses: [QuickConfiguration.Type] = [] + for index in 0.. Void) { - World.sharedWorld.sharedExamples(name) { _ in closure() } - } - - /** - Defines a group of shared examples. These examples can be re-used in several locations - by using the `itBehavesLike` function. - - - parameter name: The name of the shared example group. This must be unique across all shared example - groups defined in a test suite. - - parameter closure: A closure containing the examples. This behaves just like an example group defined - using `describe` or `context`--the closure may contain any number of `beforeEach` - and `afterEach` closures, as well as any number of examples (defined using `it`). - - The closure takes a SharedExampleContext as an argument. This context is a function - that can be executed to retrieve parameters passed in via an `itBehavesLike` function. - */ - public static func sharedExamples(_ name: String, closure: @escaping SharedExampleClosure) { - World.sharedWorld.sharedExamples(name, closure: closure) - } - - // MARK: - Example groups - /** - Defines an example group. Example groups are logical groupings of examples. - Example groups can share setup and teardown code. - - - parameter description: An arbitrary string describing the example group. - - parameter closure: A closure that can contain other examples. - */ - public static func describe(_ description: String, closure: () -> Void) { - World.sharedWorld.describe(description, closure: closure) - } - - /** - Defines an example group. Equivalent to `describe`. - */ - public static func context(_ description: String, closure: () -> Void) { - World.sharedWorld.context(description, closure: closure) - } - - // MARK: - beforeEach - /** - Defines a closure to be run prior to each example in the current example - group. This closure is not run for pending or otherwise disabled examples. - An example group may contain an unlimited number of beforeEach. They'll be - run in the order they're defined, but you shouldn't rely on that behavior. - - - parameter closure: The closure to be run prior to each example. - */ - public static func beforeEach(_ closure: @escaping BeforeExampleClosure) { - World.sharedWorld.beforeEach(closure) - } - - /** - Identical to Quick.DSL.beforeEach, except the closure is provided with - metadata on the example that the closure is being run prior to. - */ - public static func beforeEach(_ closure: @escaping BeforeExampleWithMetadataClosure) { - World.sharedWorld.beforeEach(closure: closure) - } - - // MARK: - AfterEach - /** - Defines a closure to be run after each example in the current example - group. This closure is not run for pending or otherwise disabled examples. - An example group may contain an unlimited number of afterEach. They'll be - run in the order they're defined, but you shouldn't rely on that behavior. - - - parameter closure: The closure to be run after each example. - */ - public static func afterEach(_ closure: @escaping AfterExampleClosure) { - World.sharedWorld.afterEach(closure) - } - - /** - Identical to Quick.DSL.afterEach, except the closure is provided with - metadata on the example that the closure is being run after. - */ - public static func afterEach(_ closure: @escaping AfterExampleWithMetadataClosure) { - World.sharedWorld.afterEach(closure: closure) - } - - // MARK: - aroundEach - /** - Defines a closure to that wraps each example in the current example - group. This closure is not run for pending or otherwise disabled examples. - - The closure you pass to aroundEach receives a callback as its argument, which - it MUST call exactly one for the example to run properly: - - aroundEach { runExample in - doSomeSetup() - runExample() - doSomeCleanup() - } - - This callback is particularly useful for test decartions that can’t split - into a separate beforeEach and afterEach. For example, running each example - in its own autorelease pool (provided by Task) requires aroundEach: - - aroundEach { runExample in - autoreleasepool { - runExample() - } - checkObjectsNoLongerRetained() - } - - You can also use aroundEach to guarantee proper nesting of setup and cleanup - operations in situations where their relative order matters. - - An example group may contain an unlimited number of aroundEach callbacks. - They will nest inside each other, with the first declared in the group - nested at the outermost level. - - - parameter closure: The closure that wraps around each example. - */ - public static func aroundEach(_ closure: @escaping AroundExampleClosure) { - World.sharedWorld.aroundEach(closure) - } - - /** - Identical to Quick.DSL.aroundEach, except the closure receives metadata - about the example that the closure wraps. - */ - public static func aroundEach(_ closure: @escaping AroundExampleWithMetadataClosure) { - World.sharedWorld.aroundEach(closure) - } - - // MARK: - Examples - /** - Defines a closure to be run prior to each example but after any beforeEach blocks. - This closure is not run for pending or otherwise disabled examples. - An example group may contain an unlimited number of justBeforeEach. They'll be - run in the order they're defined, but you shouldn't rely on that behavior. - - - parameter closure: The closure to be run prior to each example and after any beforeEach blocks - */ - - public static func justBeforeEach(_ closure: @escaping BeforeExampleClosure) { - World.sharedWorld.justBeforeEach(closure) - } - - /** - Defines an example. Examples use assertions to demonstrate how code should - behave. These are like "tests" in XCTest. - - - parameter description: An arbitrary string describing what the example is meant to specify. - - parameter closure: A closure that can contain assertions. - - parameter file: The absolute path to the file containing the example. A sensible default is provided. - - parameter line: The line containing the example. A sensible default is provided. - */ - public static func it(_ description: String, file: FileString = #file, line: UInt = #line, closure: @escaping () throws -> Void) { - World.sharedWorld.it(description, file: file, line: line, closure: closure) - } - - // MARK: - Shared Examples - /** - Inserts the examples defined using a `sharedExamples` function into the current example group. - The shared examples are executed at this location, as if they were written out manually. - - - parameter name: The name of the shared examples group to be executed. This must be identical to the - name of a shared examples group defined using `sharedExamples`. If there are no shared - examples that match the name given, an exception is thrown and the test suite will crash. - - parameter file: The absolute path to the file containing the current example group. A sensible default is provided. - - parameter line: The line containing the current example group. A sensible default is provided. - */ - public static func itBehavesLike(_ name: String, file: FileString = #file, line: UInt = #line) { - itBehavesLike(name, file: file, line: line, sharedExampleContext: { return [:] }) - } - - /** - Inserts the examples defined using a `sharedExamples` function into the current example group. - The shared examples are executed at this location, as if they were written out manually. - This function also passes those shared examples a context that can be evaluated to give the shared - examples extra information on the subject of the example. - - - parameter name: The name of the shared examples group to be executed. This must be identical to the - name of a shared examples group defined using `sharedExamples`. If there are no shared - examples that match the name given, an exception is thrown and the test suite will crash. - - parameter sharedExampleContext: A closure that, when evaluated, returns key-value pairs that provide the - shared examples with extra information on the subject of the example. - - parameter file: The absolute path to the file containing the current example group. A sensible default is provided. - - parameter line: The line containing the current example group. A sensible default is provided. - */ - public static func itBehavesLike(_ name: String, file: FileString = #file, line: UInt = #line, sharedExampleContext: @escaping SharedExampleContext) { - World.sharedWorld.itBehavesLike(name, sharedExampleContext: sharedExampleContext, file: file, line: line) - } - - /** - Inserts the examples defined using a `Behavior` into the current example group. - The shared examples are executed at this location, as if they were written out manually. - This function also passes a strongly-typed context that can be evaluated to give the shared examples extra information on the subject of the example. - - - parameter behavior: The type of `Behavior` class defining the example group to be executed. - - parameter context: A closure that, when evaluated, returns an instance of `Behavior`'s context type to provide its example group with extra information on the subject of the example. - - parameter file: The absolute path to the file containing the current example group. A sensible default is provided. - - parameter line: The line containing the current example group. A sensible default is provided. - */ - public static func itBehavesLike(_ behavior: Behavior.Type, file: FileString = #file, line: UInt = #line, context: @escaping () -> C) { - World.sharedWorld.itBehavesLike(behavior, context: context, file: file, line: line) - } - - // MARK: - Pending - /** - Defines an example or example group that should not be executed. Use `pending` to temporarily disable - examples or groups that should not be run yet. - - - parameter description: An arbitrary string describing the example or example group. - - parameter closure: A closure that will not be evaluated. - */ - public static func pending(_ description: String, file: FileString = #file, line: UInt = #line, closure: @escaping () throws -> Void) { - World.sharedWorld.pending(description, file: file, line: line, closure: closure) - } - - // MARK: - Defocused - /** - Use this to quickly mark a `describe` closure as pending. - This disables all examples within the closure. - */ - public static func xdescribe(_ description: String, closure: () -> Void) { - World.sharedWorld.xdescribe(description, closure: closure) - } - - /** - Use this to quickly mark a `context` closure as pending. - This disables all examples within the closure. - */ - public static func xcontext(_ description: String, closure: () -> Void) { - xdescribe(description, closure: closure) - } - - /** - Use this to quickly mark an `it` closure as pending. - This disables the example and ensures the code within the closure is never run. - */ - public static func xit(_ description: String, file: FileString = #file, line: UInt = #line, closure: @escaping () throws -> Void) { - World.sharedWorld.xit(description, file: file, line: line, closure: closure) - } - - /** - Use this to quickly mark an `itBehavesLike` closure as pending. - This disables the example group defined by this behavior and ensures the code within is never run. - */ - public static func xitBehavesLike(_ behavior: Behavior.Type, file: FileString = #file, line: UInt = #line, context: @escaping () -> C) { - World.sharedWorld.xitBehavesLike(behavior, context: context, file: file, line: line) - } - - /** - Use this to quickly mark an `itBehavesLike` closure as pending. - This disables the example group defined by this behavior and ensures the code within is never run. - */ - public static func xitBehavesLike(_ name: String, file: FileString = #file, line: UInt = #line) { - xitBehavesLike(name, file: file, line: line, sharedExampleContext: { return [:] }) - } - - /** - Use this to quickly mark an `itBehavesLike` closure as pending. - This disables the example group defined by this behavior and ensures the code within is never run. - */ - public static func xitBehavesLike(_ name: String, file: FileString = #file, line: UInt = #line, sharedExampleContext: @escaping SharedExampleContext) { - World.sharedWorld.xitBehavesLike(name, sharedExampleContext: sharedExampleContext, file: file, line: line) - } - - // MARK: - Focused - /** - Use this to quickly focus a `describe` closure, focusing the examples in the closure. - If any examples in the test suite are focused, only those examples are executed. - This trumps any explicitly focused or unfocused examples within the closure--they are all treated as focused. - */ - public static func fdescribe(_ description: String, closure: () -> Void) { - World.sharedWorld.fdescribe(description, closure: closure) - } - - /** - Use this to quickly focus a `context` closure. Equivalent to `fdescribe`. - */ - public static func fcontext(_ description: String, closure: () -> Void) { - fdescribe(description, closure: closure) - } - - /** - Use this to quickly focus an `it` closure, focusing the example. - If any examples in the test suite are focused, only those examples are executed. - */ - public static func fit(_ description: String, file: FileString = #file, line: UInt = #line, closure: @escaping () throws -> Void) { - World.sharedWorld.fit(description, file: file, line: line, closure: closure) - } - - /** - Use this to quickly focus an `itBehavesLike` closure. - */ - public static func fitBehavesLike(_ name: String, file: FileString = #file, line: UInt = #line) { - fitBehavesLike(name, file: file, line: line, sharedExampleContext: { return [:] }) - } - - /** - Use this to quickly focus an `itBehavesLike` closure. - */ - public static func fitBehavesLike(_ name: String, file: FileString = #file, line: UInt = #line, sharedExampleContext: @escaping SharedExampleContext) { - World.sharedWorld.fitBehavesLike(name, sharedExampleContext: sharedExampleContext, file: file, line: line) - } - - /** - Use this to quickly focus on `itBehavesLike` closure. - */ - public static func fitBehavesLike(_ behavior: Behavior.Type, file: FileString = #file, line: UInt = #line, context: @escaping () -> C) { - World.sharedWorld.fitBehavesLike(behavior, context: context, file: file, line: line) - } +/** + Defines a closure to be run prior to any examples in the test suite. + You may define an unlimited number of these closures, but there is no + guarantee as to the order in which they're run. + + If the test suite crashes before the first example is run, this closure + will not be executed. + + - parameter closure: The closure to be run prior to any examples in the test suite. +*/ +public func beforeSuite(_ closure: @escaping BeforeSuiteClosure) { + World.sharedWorld.beforeSuite(closure) +} + +/** + Defines a closure to be run after all of the examples in the test suite. + You may define an unlimited number of these closures, but there is no + guarantee as to the order in which they're run. + + If the test suite crashes before all examples are run, this closure + will not be executed. + + - parameter closure: The closure to be run after all of the examples in the test suite. +*/ +public func afterSuite(_ closure: @escaping AfterSuiteClosure) { + World.sharedWorld.afterSuite(closure) +} + +/** + Defines a group of shared examples. These examples can be re-used in several locations + by using the `itBehavesLike` function. + + - parameter name: The name of the shared example group. This must be unique across all shared example + groups defined in a test suite. + - parameter closure: A closure containing the examples. This behaves just like an example group defined + using `describe` or `context`--the closure may contain any number of `beforeEach` + and `afterEach` closures, as well as any number of examples (defined using `it`). +*/ +public func sharedExamples(_ name: String, closure: @escaping () -> Void) { + World.sharedWorld.sharedExamples(name) { _ in closure() } +} + +/** + Defines a group of shared examples. These examples can be re-used in several locations + by using the `itBehavesLike` function. + + - parameter name: The name of the shared example group. This must be unique across all shared example + groups defined in a test suite. + - parameter closure: A closure containing the examples. This behaves just like an example group defined + using `describe` or `context`--the closure may contain any number of `beforeEach` + and `afterEach` closures, as well as any number of examples (defined using `it`). + + The closure takes a SharedExampleContext as an argument. This context is a function + that can be executed to retrieve parameters passed in via an `itBehavesLike` function. +*/ +public func sharedExamples(_ name: String, closure: @escaping SharedExampleClosure) { + World.sharedWorld.sharedExamples(name, closure: closure) +} + +/** + Defines an example group. Example groups are logical groupings of examples. + Example groups can share setup and teardown code. + + - parameter description: An arbitrary string describing the example group. + - parameter closure: A closure that can contain other examples. +*/ +public func describe(_ description: String, closure: () -> Void) { + World.sharedWorld.describe(description, closure: closure) +} + +/** + Defines an example group. Equivalent to `describe`. +*/ +public func context(_ description: String, closure: () -> Void) { + World.sharedWorld.context(description, closure: closure) +} + +/** + Defines a closure to be run prior to each example in the current example + group. This closure is not run for pending or otherwise disabled examples. + An example group may contain an unlimited number of beforeEach. They'll be + run in the order they're defined, but you shouldn't rely on that behavior. + + - parameter closure: The closure to be run prior to each example. +*/ +public func beforeEach(_ closure: @escaping BeforeExampleClosure) { + World.sharedWorld.beforeEach(closure) +} + +/** + Identical to Quick.DSL.beforeEach, except the closure is provided with + metadata on the example that the closure is being run prior to. +*/ +public func beforeEach(_ closure: @escaping BeforeExampleWithMetadataClosure) { + World.sharedWorld.beforeEach(closure: closure) +} + +/** + Defines a closure to be run after each example in the current example + group. This closure is not run for pending or otherwise disabled examples. + An example group may contain an unlimited number of afterEach. They'll be + run in the order they're defined, but you shouldn't rely on that behavior. + + - parameter closure: The closure to be run after each example. +*/ +public func afterEach(_ closure: @escaping AfterExampleClosure) { + World.sharedWorld.afterEach(closure) +} + +/** + Identical to Quick.DSL.afterEach, except the closure is provided with + metadata on the example that the closure is being run after. +*/ +public func afterEach(_ closure: @escaping AfterExampleWithMetadataClosure) { + World.sharedWorld.afterEach(closure: closure) +} + +/** + Defines a closure to that wraps each example in the current example + group. This closure is not run for pending or otherwise disabled examples. + + The closure you pass to aroundEach receives a callback as its argument, which + it MUST call exactly one for the example to run properly: + + aroundEach { runExample in + doSomeSetup() + runExample() + doSomeCleanup() + } + + This callback is particularly useful for test decartions that can’t split + into a separate beforeEach and afterEach. For example, running each example + in its own autorelease pool requires aroundEach: + + aroundEach { runExample in + autoreleasepool { + runExample() + } + checkObjectsNoLongerRetained() + } + + You can also use aroundEach to guarantee proper nesting of setup and cleanup + operations in situations where their relative order matters. + + An example group may contain an unlimited number of aroundEach callbacks. + They will nest inside each other, with the first declared in the group + nested at the outermost level. + + - parameter closure: The closure that wraps around each example. +*/ +public func aroundEach(_ closure: @escaping AroundExampleClosure) { + World.sharedWorld.aroundEach(closure) +} + +/** + Identical to Quick.DSL.aroundEach, except the closure receives metadata + about the example that the closure wraps. +*/ +public func aroundEach(_ closure: @escaping AroundExampleWithMetadataClosure) { + World.sharedWorld.aroundEach(closure) +} + +/** + Defines an example. Examples use assertions to demonstrate how code should + behave. These are like "tests" in XCTest. + + - parameter description: An arbitrary string describing what the example is meant to specify. + - parameter closure: A closure that can contain assertions. + - parameter file: The absolute path to the file containing the example. A sensible default is provided. + - parameter line: The line containing the example. A sensible default is provided. +*/ +public func it(_ description: String, file: FileString = #file, line: UInt = #line, closure: @escaping () throws -> Void) { + World.sharedWorld.it(description, file: file, line: line, closure: closure) +} + +/** + Inserts the examples defined using a `sharedExamples` function into the current example group. + The shared examples are executed at this location, as if they were written out manually. + + - parameter name: The name of the shared examples group to be executed. This must be identical to the + name of a shared examples group defined using `sharedExamples`. If there are no shared + examples that match the name given, an exception is thrown and the test suite will crash. + - parameter file: The absolute path to the file containing the current example group. A sensible default is provided. + - parameter line: The line containing the current example group. A sensible default is provided. +*/ +public func itBehavesLike(_ name: String, file: FileString = #file, line: UInt = #line) { + itBehavesLike(name, file: file, line: line, sharedExampleContext: { return [:] }) +} + +/** + Inserts the examples defined using a `sharedExamples` function into the current example group. + The shared examples are executed at this location, as if they were written out manually. + This function also passes those shared examples a context that can be evaluated to give the shared + examples extra information on the subject of the example. + + - parameter name: The name of the shared examples group to be executed. This must be identical to the + name of a shared examples group defined using `sharedExamples`. If there are no shared + examples that match the name given, an exception is thrown and the test suite will crash. + - parameter sharedExampleContext: A closure that, when evaluated, returns key-value pairs that provide the + shared examples with extra information on the subject of the example. + - parameter file: The absolute path to the file containing the current example group. A sensible default is provided. + - parameter line: The line containing the current example group. A sensible default is provided. +*/ +public func itBehavesLike(_ name: String, file: FileString = #file, line: UInt = #line, sharedExampleContext: @escaping SharedExampleContext) { + World.sharedWorld.itBehavesLike(name, sharedExampleContext: sharedExampleContext, file: file, line: line) +} + +/** + Inserts the examples defined using a `Behavior` into the current example group. + The shared examples are executed at this location, as if they were written out manually. + This function also passes a strongly-typed context that can be evaluated to give the shared examples extra information on the subject of the example. + + - parameter behavior: The type of `Behavior` class defining the example group to be executed. + - parameter context: A closure that, when evaluated, returns an instance of `Behavior`'s context type to provide its example group with extra information on the subject of the example. + - parameter file: The absolute path to the file containing the current example group. A sensible default is provided. + - parameter line: The line containing the current example group. A sensible default is provided. + */ +public func itBehavesLike(_ behavior: Behavior.Type, file: FileString = #file, line: UInt = #line, context: @escaping () -> C) { + World.sharedWorld.itBehavesLike(behavior, context: context, file: file, line: line) +} + +/** + Defines an example or example group that should not be executed. Use `pending` to temporarily disable + examples or groups that should not be run yet. + + - parameter description: An arbitrary string describing the example or example group. + - parameter closure: A closure that will not be evaluated. +*/ +public func pending(_ description: String, closure: () -> Void) { + World.sharedWorld.pending(description, closure: closure) +} + +/** + Use this to quickly mark a `describe` closure as pending. + This disables all examples within the closure. +*/ +public func xdescribe(_ description: String, closure: () -> Void) { + World.sharedWorld.xdescribe(description, closure: closure) +} + +/** + Use this to quickly mark a `context` closure as pending. + This disables all examples within the closure. +*/ +public func xcontext(_ description: String, closure: () -> Void) { + xdescribe(description, closure: closure) +} + +/** + Use this to quickly mark an `it` closure as pending. + This disables the example and ensures the code within the closure is never run. +*/ +public func xit(_ description: String, file: FileString = #file, line: UInt = #line, closure: @escaping () throws -> Void) { + World.sharedWorld.xit(description, file: file, line: line, closure: closure) +} + +/** + Use this to quickly mark an `itBehavesLike` closure as pending. + This disables the example group defined by this behavior and ensures the code within is never run. +*/ +public func xitBehavesLike(_ behavior: Behavior.Type, file: FileString = #file, line: UInt = #line, context: @escaping () -> C) { + World.sharedWorld.xitBehavesLike(behavior, context: context, file: file, line: line) +} +/** + Use this to quickly focus a `describe` closure, focusing the examples in the closure. + If any examples in the test suite are focused, only those examples are executed. + This trumps any explicitly focused or unfocused examples within the closure--they are all treated as focused. +*/ +public func fdescribe(_ description: String, closure: () -> Void) { + World.sharedWorld.fdescribe(description, closure: closure) +} + +/** + Use this to quickly focus a `context` closure. Equivalent to `fdescribe`. +*/ +public func fcontext(_ description: String, closure: () -> Void) { + fdescribe(description, closure: closure) +} + +/** + Use this to quickly focus an `it` closure, focusing the example. + If any examples in the test suite are focused, only those examples are executed. +*/ +public func fit(_ description: String, file: FileString = #file, line: UInt = #line, closure: @escaping () throws -> Void) { + World.sharedWorld.fit(description, file: file, line: line, closure: closure) +} + +/** + Use this to quickly focus an `itBehavesLike` closure. +*/ +public func fitBehavesLike(_ name: String, file: FileString = #file, line: UInt = #line) { + fitBehavesLike(name, file: file, line: line, sharedExampleContext: { return [:] }) +} + +/** + Use this to quickly focus an `itBehavesLike` closure. +*/ +public func fitBehavesLike(_ name: String, file: FileString = #file, line: UInt = #line, sharedExampleContext: @escaping SharedExampleContext) { + World.sharedWorld.fitBehavesLike(name, sharedExampleContext: sharedExampleContext, file: file, line: line) +} + +/** + Use this to quickly focus on `itBehavesLike` closure. + */ +public func fitBehavesLike(_ behavior: Behavior.Type, file: FileString = #file, line: UInt = #line, context: @escaping () -> C) { + World.sharedWorld.fitBehavesLike(behavior, context: context, file: file, line: line) } // swiftlint:enable line_length diff --git a/Pods/Quick/Sources/Quick/DSL/World+DSL.swift b/Pods/Quick/Sources/Quick/DSL/World+DSL.swift index d6eb719..be7e684 100644 --- a/Pods/Quick/Sources/Quick/DSL/World+DSL.swift +++ b/Pods/Quick/Sources/Quick/DSL/World+DSL.swift @@ -6,38 +6,18 @@ import Foundation writers use in their specs. */ extension World { - // MARK: - Before Suite -#if canImport(Darwin) - @objc(beforeSuite:) - internal func objc_beforeSuite(_ closure: @escaping BeforeSuiteNonThrowingClosure) { - suiteHooks.appendBefore(closure) - } -#endif - - @nonobjc internal func beforeSuite(_ closure: @escaping BeforeSuiteClosure) { suiteHooks.appendBefore(closure) } - // MARK: - After Suite -#if canImport(Darwin) - @objc(afterSuite:) - internal func objc_afterSuite(_ closure: @escaping AfterSuiteNonThrowingClosure) { - suiteHooks.appendAfter(closure) - } -#endif - - @nonobjc internal func afterSuite(_ closure: @escaping AfterSuiteClosure) { suiteHooks.appendAfter(closure) } - // MARK: - Specifying shared examples internal func sharedExamples(_ name: String, closure: @escaping SharedExampleClosure) { registerSharedExample(name, closure: closure) } - // MARK: - Example groups. internal func describe(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { guard currentExampleMetadata == nil else { raiseError("'describe' cannot be used inside '\(currentPhase)', 'describe' may only be used inside 'context' or 'describe'.") @@ -66,131 +46,60 @@ extension World { self.describe(description, flags: [Filter.pending: true], closure: closure) } - // MARK: - Just Before Each -#if canImport(Darwin) - @objc(justBeforeEach:) - internal func objc_justBeforeEach(_ closure: @escaping BeforeExampleNonThrowingClosure) { - guard currentExampleMetadata == nil else { - raiseError("'justBeforeEach' cannot be used inside '\(currentPhase)', 'justBeforeEach' may only be used inside 'context' or 'describe'.") - } - currentExampleGroup.hooks.appendJustBeforeEach(closure) - } -#endif - - @nonobjc - internal func justBeforeEach(_ closure: @escaping BeforeExampleClosure) { - guard currentExampleMetadata == nil else { - raiseError("'justBeforeEach' cannot be used inside '\(currentPhase)', 'justBeforeEach' may only be used inside 'context' or 'describe'.") - } - currentExampleGroup.hooks.appendJustBeforeEach(closure) - } - - // MARK: - Before Each -#if canImport(Darwin) - @objc(beforeEachWithMetadata:) - internal func objc_beforeEach(closure: @escaping BeforeExampleWithMetadataNonThrowingClosure) { - guard currentExampleMetadata == nil else { - raiseError("'beforeEach' cannot be used inside '\(currentPhase)', 'beforeEach' may only be used inside 'context' or 'describe'.") - } - currentExampleGroup.hooks.appendBefore(closure) - } - - @objc(beforeEach:) - internal func objc_beforeEach(closure: @escaping BeforeExampleNonThrowingClosure) { + internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("'beforeEach' cannot be used inside '\(currentPhase)', 'beforeEach' may only be used inside 'context' or 'describe'.") } currentExampleGroup.hooks.appendBefore(closure) } -#endif - @nonobjc +#if canImport(Darwin) + @objc(beforeEachWithMetadata:) internal func beforeEach(closure: @escaping BeforeExampleWithMetadataClosure) { - guard currentExampleMetadata == nil else { - raiseError("'beforeEach' cannot be used inside '\(currentPhase)', 'beforeEach' may only be used inside 'context' or 'describe'.") - } currentExampleGroup.hooks.appendBefore(closure) } - - @nonobjc - internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { - guard currentExampleMetadata == nil else { - raiseError("'beforeEach' cannot be used inside '\(currentPhase)', 'beforeEach' may only be used inside 'context' or 'describe'.") - } +#else + internal func beforeEach(closure: @escaping BeforeExampleWithMetadataClosure) { currentExampleGroup.hooks.appendBefore(closure) } +#endif - // MARK: - After Each -#if canImport(Darwin) - @objc(afterEachWithMetadata:) - internal func objc_afterEach(closure: @escaping AfterExampleWithMetadataNonThrowingClosure) { + internal func afterEach(_ closure: @escaping AfterExampleClosure) { guard currentExampleMetadata == nil else { raiseError("'afterEach' cannot be used inside '\(currentPhase)', 'afterEach' may only be used inside 'context' or 'describe'.") } currentExampleGroup.hooks.appendAfter(closure) } - @objc(afterEach:) - internal func objc_afterEach(_ closure: @escaping AfterExampleNonThrowingClosure) { - guard currentExampleMetadata == nil else { - raiseError("'afterEach' cannot be used inside '\(currentPhase)', 'afterEach' may only be used inside 'context' or 'describe'.") - } - currentExampleGroup.hooks.appendAfter(closure) - } -#endif - - @nonobjc +#if canImport(Darwin) + @objc(afterEachWithMetadata:) internal func afterEach(closure: @escaping AfterExampleWithMetadataClosure) { - guard currentExampleMetadata == nil else { - raiseError("'afterEach' cannot be used inside '\(currentPhase)', 'afterEach' may only be used inside 'context' or 'describe'.") - } currentExampleGroup.hooks.appendAfter(closure) } - - @nonobjc - internal func afterEach(_ closure: @escaping AfterExampleClosure) { - guard currentExampleMetadata == nil else { - raiseError("'afterEach' cannot be used inside '\(currentPhase)', 'afterEach' may only be used inside 'context' or 'describe'.") - } +#else + internal func afterEach(closure: @escaping AfterExampleWithMetadataClosure) { currentExampleGroup.hooks.appendAfter(closure) } +#endif - // MARK: - Around Each - #if canImport(Darwin) - @objc(aroundEach:) - internal func objc_aroundEach(_ closure: @escaping AroundExampleNonThrowingClosure) { + internal func aroundEach(_ closure: @escaping AroundExampleClosure) { guard currentExampleMetadata == nil else { raiseError("'aroundEach' cannot be used inside '\(currentPhase)', 'aroundEach' may only be used inside 'context' or 'describe'. ") } currentExampleGroup.hooks.appendAround(closure) } +#if canImport(Darwin) @objc(aroundEachWithMetadata:) - internal func objc_aroundEach(_ closure: @escaping AroundExampleWithMetadataNonThrowingClosure) { - guard currentExampleMetadata == nil else { - raiseError("'aroundEach' cannot be used inside '\(currentPhase)', 'aroundEach' may only be used inside 'context' or 'describe'. ") - } - currentExampleGroup.hooks.appendAround(closure) - } - #endif - - @nonobjc - internal func aroundEach(_ closure: @escaping AroundExampleClosure) { - guard currentExampleMetadata == nil else { - raiseError("'aroundEach' cannot be used inside '\(currentPhase)', 'aroundEach' may only be used inside 'context' or 'describe'. ") - } + internal func aroundEach(_ closure: @escaping AroundExampleWithMetadataClosure) { currentExampleGroup.hooks.appendAround(closure) } - - @nonobjc +#else internal func aroundEach(_ closure: @escaping AroundExampleWithMetadataClosure) { - guard currentExampleMetadata == nil else { - raiseError("'aroundEach' cannot be used inside '\(currentPhase)', 'aroundEach' may only be used inside 'context' or 'describe'. ") - } currentExampleGroup.hooks.appendAround(closure) } +#endif - // MARK: - Examples (Swift) @nonobjc internal func it(_ description: String, flags: FilterFlags = [:], file: FileString, line: UInt, closure: @escaping () throws -> Void) { if beforesCurrentlyExecuting { @@ -217,7 +126,6 @@ extension World { self.it(description, flags: [Filter.pending: true], file: file, line: line, closure: closure) } - // MARK: - Shared Behavior @nonobjc internal func itBehavesLike(_ name: String, sharedExampleContext: @escaping SharedExampleContext, flags: FilterFlags = [:], file: FileString, line: UInt) { guard currentExampleMetadata == nil else { @@ -274,37 +182,20 @@ extension World { self.itBehavesLike(behavior, context: context, flags: [Filter.pending: true], file: file, line: line) } - // MARK: Examples & Shared behavior (objc) #if canImport(Darwin) && !SWIFT_PACKAGE - @nonobjc - internal func syncIt(_ description: String, flags: FilterFlags = [:], file: FileString, line: UInt, closure: @escaping () throws -> Void) { - if beforesCurrentlyExecuting { - raiseError("'it' cannot be used inside 'beforeEach', 'it' may only be used inside 'context' or 'describe'.") - } - if aftersCurrentlyExecuting { - raiseError("'it' cannot be used inside 'afterEach', 'it' may only be used inside 'context' or 'describe'.") - } - guard currentExampleMetadata == nil else { - raiseError("'it' cannot be used inside 'it', 'it' may only be used inside 'context' or 'describe'.") - } - let callsite = Callsite(file: file, line: line) - let example = Example(description: description, callsite: callsite, flags: flags, closure: closure) - currentExampleGroup.appendExample(example) - } - @objc(itWithDescription:file:line:closure:) internal func objc_it(_ description: String, file: FileString, line: UInt, closure: @escaping () -> Void) { - syncIt(description, file: file, line: line, closure: closure) + it(description, file: file, line: line, closure: closure) } @objc(fitWithDescription:file:line:closure:) internal func objc_fit(_ description: String, file: FileString, line: UInt, closure: @escaping () -> Void) { - syncIt(description, flags: [Filter.focused: true], file: file, line: line, closure: closure) + fit(description, file: file, line: line, closure: closure) } @objc(xitWithDescription:file:line:closure:) internal func objc_xit(_ description: String, file: FileString, line: UInt, closure: @escaping () -> Void) { - syncIt(description, flags: [Filter.pending: true], file: file, line: line, closure: closure) + xit(description, file: file, line: line, closure: closure) } @objc(itBehavesLikeSharedExampleNamed:sharedExampleContext:file:line:) @@ -321,17 +212,10 @@ extension World { internal func objc_xitBehavesLike(_ name: String, sharedExampleContext: @escaping SharedExampleContext, file: FileString, line: UInt) { xitBehavesLike(name, sharedExampleContext: sharedExampleContext, file: file, line: line) } - - @objc(pendingWithDescription:file:line:closure:) - internal func objc_pending(_ description: String, file: FileString, line: UInt, closure: @escaping () -> Void) { - self.it(description, flags: [Filter.pending: true], file: file, line: line, closure: closure) - } #endif - // MARK: - Pending - @nonobjc - internal func pending(_ description: String, file: FileString, line: UInt, closure: @escaping () throws -> Void) { - self.it(description, flags: [Filter.pending: true], file: file, line: line, closure: closure) + internal func pending(_ description: String, closure: () -> Void) { + print("Pending: \(description)") } private var currentPhase: String { diff --git a/Pods/Quick/Sources/Quick/Example.swift b/Pods/Quick/Sources/Quick/Example.swift new file mode 100644 index 0000000..42160b1 --- /dev/null +++ b/Pods/Quick/Sources/Quick/Example.swift @@ -0,0 +1,154 @@ +import Foundation +import XCTest + +#if canImport(Darwin) +// swiftlint:disable type_name +@objcMembers +public class _ExampleBase: NSObject {} +#else +public class _ExampleBase: NSObject {} +// swiftlint:enable type_name +#endif + +/** + Examples, defined with the `it` function, use assertions to + demonstrate how code should behave. These are like "tests" in XCTest. +*/ +final public class Example: _ExampleBase { + /** + A boolean indicating whether the example is a shared example; + i.e.: whether it is an example defined with `itBehavesLike`. + */ + public var isSharedExample = false + + /** + The site at which the example is defined. + This must be set correctly in order for Xcode to highlight + the correct line in red when reporting a failure. + */ + public var callsite: Callsite + + weak internal var group: ExampleGroup? + + private let internalDescription: String + private let closure: () throws -> Void + private let flags: FilterFlags + + internal init(description: String, callsite: Callsite, flags: FilterFlags, closure: @escaping () throws -> Void) { + self.internalDescription = description + self.closure = closure + self.callsite = callsite + self.flags = flags + } + + public override var description: String { + return internalDescription + } + + /** + The example name. A name is a concatenation of the name of + the example group the example belongs to, followed by the + description of the example itself. + + The example name is used to generate a test method selector + to be displayed in Xcode's test navigator. + */ + public var name: String { + guard let groupName = group?.name else { return description } + return "\(groupName), \(description)" + } + + /** + Executes the example closure, as well as all before and after + closures defined in the its surrounding example groups. + */ + public func run() { // swiftlint:disable:this function_body_length + let world = World.sharedWorld + + if world.numberOfExamplesRun == 0 { + world.suiteHooks.executeBefores() + } + + let exampleMetadata = ExampleMetadata(example: self, exampleIndex: world.numberOfExamplesRun) + world.currentExampleMetadata = exampleMetadata + defer { + world.currentExampleMetadata = nil + } + + group!.phase = .beforesExecuting + + let runExample = { [closure, name, callsite] in + self.group!.phase = .beforesFinished + + do { + try closure() + } catch { + let description = "Test \(name) threw unexpected error: \(error.localizedDescription)" + #if SWIFT_PACKAGE + let file = callsite.file.description + #else + let file = callsite.file + #endif + + // XCTIssue is unavailable (not implemented yet) on swift-corelibs-xctest (for non-Apple platforms) + #if canImport(Darwin) + let location = XCTSourceCodeLocation(filePath: file, lineNumber: Int(callsite.line)) + let sourceCodeContext = XCTSourceCodeContext(location: location) + let issue = XCTIssue( + type: .thrownError, + compactDescription: description, + sourceCodeContext: sourceCodeContext + ) + QuickSpec.current.record(issue) + #else + QuickSpec.current.recordFailure( + withDescription: description, + inFile: file, + atLine: Int(callsite.line), + expected: false + ) + #endif + } + + self.group!.phase = .aftersExecuting + } + + let allWrappers = group!.wrappers + world.exampleHooks.wrappers + let wrappedExample = allWrappers.reduce(runExample) { closure, wrapper in + return { wrapper(exampleMetadata, closure) } + } + wrappedExample() + + group!.phase = .aftersFinished + + world.numberOfExamplesRun += 1 + + if !world.isRunningAdditionalSuites && world.numberOfExamplesRun >= world.cachedIncludedExampleCount { + world.suiteHooks.executeAfters() + } + } + + /** + Evaluates the filter flags set on this example and on the example groups + this example belongs to. Flags set on the example are trumped by flags on + the example group it belongs to. Flags on inner example groups are trumped + by flags on outer example groups. + */ + internal var filterFlags: FilterFlags { + var aggregateFlags = flags + for (key, value) in group!.filterFlags { + aggregateFlags[key] = value + } + return aggregateFlags + } +} + +extension Example { + /** + Returns a boolean indicating whether two Example objects are equal. + If two examples are defined at the exact same callsite, they must be equal. + */ + @nonobjc public static func == (lhs: Example, rhs: Example) -> Bool { + return lhs.callsite == rhs.callsite + } +} diff --git a/Pods/Quick/Sources/Quick/ExampleGroup.swift b/Pods/Quick/Sources/Quick/ExampleGroup.swift index bb6f867..d18bcf7 100644 --- a/Pods/Quick/Sources/Quick/ExampleGroup.swift +++ b/Pods/Quick/Sources/Quick/ExampleGroup.swift @@ -1,20 +1,11 @@ import Foundation -internal protocol Filterable { - var filterFlags: FilterFlags { get } -} - -private enum ExampleUnit { - case example(Example) - case group(ExampleGroup) -} - /** Example groups are logical groupings of examples, defined with the `describe` and `context` functions. Example groups can share setup and teardown code. */ -final public class ExampleGroup: NSObject, Filterable { +final public class ExampleGroup: NSObject { weak internal var parent: ExampleGroup? internal let hooks = ExampleHooks() @@ -23,7 +14,8 @@ final public class ExampleGroup: NSObject, Filterable { private let internalDescription: String private let flags: FilterFlags private let isInternalRootExampleGroup: Bool - private var childUnits = [ExampleUnit]() + private var childGroups = [ExampleGroup]() + private var childExamples = [Example]() internal init(description: String, flags: FilterFlags, isInternalRootExampleGroup: Bool = false) { self.internalDescription = description @@ -42,25 +34,14 @@ final public class ExampleGroup: NSObject, Filterable { #if canImport(Darwin) @objc public var examples: [Example] { - _examples + return childExamples + childGroups.flatMap { $0.examples } } #else public var examples: [Example] { - _examples + return childExamples + childGroups.flatMap { $0.examples } } #endif - private var _examples: [Example] { - childUnits.flatMap { unit in - switch unit { - case .example(let example): - return [example] - case .group(let exampleGroup): - return exampleGroup.examples - } - } - } - internal var name: String? { guard let parent = parent else { return isInternalRootExampleGroup ? nil : description @@ -80,14 +61,6 @@ final public class ExampleGroup: NSObject, Filterable { return aggregateFlags } - internal var justBeforeEachStatements: [AroundExampleWithMetadataClosure] { - var closures = Array(hooks.justBeforeEachStatements.reversed()) - walkUp { group in - closures.append(contentsOf: group.hooks.justBeforeEachStatements.reversed()) - } - return closures - } - internal var wrappers: [AroundExampleWithMetadataClosure] { var closures = Array(hooks.wrappers.reversed()) walkUp { group in @@ -97,24 +70,22 @@ final public class ExampleGroup: NSObject, Filterable { } internal func walkDownExamples(_ callback: (_ example: Example) -> Void) { - for unit in childUnits { - switch unit { - case .example(let example): - callback(example) - case .group(let exampleGroup): - exampleGroup.walkDownExamples(callback) - } + for example in childExamples { + callback(example) + } + for group in childGroups { + group.walkDownExamples(callback) } } internal func appendExampleGroup(_ group: ExampleGroup) { group.parent = self - childUnits.append(.group(group)) + childGroups.append(group) } internal func appendExample(_ example: Example) { example.group = self - childUnits.append(.example(example)) + childExamples.append(example) } private func walkUp(_ callback: (_ group: ExampleGroup) -> Void) { diff --git a/Pods/Quick/Sources/Quick/ExampleMetadata.swift b/Pods/Quick/Sources/Quick/ExampleMetadata.swift new file mode 100644 index 0000000..a8f0d77 --- /dev/null +++ b/Pods/Quick/Sources/Quick/ExampleMetadata.swift @@ -0,0 +1,33 @@ +import Foundation + +#if canImport(Darwin) +// swiftlint:disable type_name +@objcMembers +public class _ExampleMetadataBase: NSObject {} +#else +public class _ExampleMetadataBase: NSObject {} +// swiftlint:enable type_name +#endif + +/** + A class that encapsulates information about an example, + including the index at which the example was executed, as + well as the example itself. +*/ +final public class ExampleMetadata: _ExampleMetadataBase { + /** + The example for which this metadata was collected. + */ + public let example: Example + + /** + The index at which this example was executed in the + test suite. + */ + public let exampleIndex: Int + + internal init(example: Example, exampleIndex: Int) { + self.example = example + self.exampleIndex = exampleIndex + } +} diff --git a/Pods/Quick/Sources/Quick/Filter.swift b/Pods/Quick/Sources/Quick/Filter.swift index 1a14f74..a250631 100644 --- a/Pods/Quick/Sources/Quick/Filter.swift +++ b/Pods/Quick/Sources/Quick/Filter.swift @@ -1,5 +1,14 @@ import Foundation +#if canImport(Darwin) +// swiftlint:disable type_name +@objcMembers +internal class _FilterBase: NSObject {} +#else +internal class _FilterBase: NSObject {} +// swiftlint:enable type_name +#endif + /** A mapping of string keys to booleans that can be used to filter examples or example groups. For example, a "focused" @@ -11,13 +20,12 @@ internal typealias FilterFlags = [String: Bool] A namespace for filter flag keys, defined primarily to make the keys available in Objective-C. */ -final internal class Filter: NSObject { +final internal class Filter: _FilterBase { /** Example and example groups with [Focused: true] are included in test runs, excluding all other examples without this flag. Use this to only run one or two tests that you're currently focusing on. */ - @nonobjc internal class var focused: String { return "focused" } @@ -26,7 +34,6 @@ final internal class Filter: NSObject { Example and example groups with [Pending: true] are excluded from test runs. Use this to temporarily suspend examples that you know do not pass yet. */ - @nonobjc internal class var pending: String { return "pending" } diff --git a/Pods/Quick/Sources/Quick/Hooks/Closures.swift b/Pods/Quick/Sources/Quick/Hooks/Closures.swift index 3f79a35..e70194d 100644 --- a/Pods/Quick/Sources/Quick/Hooks/Closures.swift +++ b/Pods/Quick/Sources/Quick/Hooks/Closures.swift @@ -1,141 +1,48 @@ // MARK: Example Hooks -/** - An async throwing closure executed before an example is run. -*/ -public typealias BeforeExampleAsyncClosure = () async throws -> Void - -/** - A throwing closure executed before an example is run. - */ -public typealias BeforeExampleClosure = () throws -> Void - /** A closure executed before an example is run. - This is only used by ObjC. - */ -public typealias BeforeExampleNonThrowingClosure = () -> Void - -/** - An async throwing closure executed before an example is run. The closure is given example metadata, - which contains information about the example that is about to be run. */ -public typealias BeforeExampleWithMetadataAsyncClosure = (_ exampleMetadata: ExampleMetadata) async throws -> Void - -/** - A throwing closure executed before an example is run. The closure is given example metadata, - which contains information about the example that is about to be run. - */ -public typealias BeforeExampleWithMetadataClosure = (_ exampleMetadata: ExampleMetadata) throws -> Void +public typealias BeforeExampleClosure = () -> Void /** A closure executed before an example is run. The closure is given example metadata, which contains information about the example that is about to be run. - This is only used by ObjC - */ -public typealias BeforeExampleWithMetadataNonThrowingClosure = (_ exampleMetadata: ExampleMetadata) -> Void - -/** - An async throwing closure executed after an example is run. */ -public typealias AfterExampleAsyncClosure = BeforeExampleAsyncClosure - -/** - A throwing closure executed after an example is run. -*/ -public typealias AfterExampleClosure = BeforeExampleClosure +public typealias BeforeExampleWithMetadataClosure = (_ exampleMetadata: ExampleMetadata) -> Void /** A closure executed after an example is run. - This is only used by ObjC -*/ -public typealias AfterExampleNonThrowingClosure = BeforeExampleNonThrowingClosure - -/** - An async throwing closure executed after an example is run. The closure is given example metadata, - which contains information about the example that has just finished running. -*/ -public typealias AfterExampleWithMetadataAsyncClosure = BeforeExampleWithMetadataAsyncClosure - -/** - A throwing closure executed after an example is run. The closure is given example metadata, - which contains information about the example that has just finished running. */ -public typealias AfterExampleWithMetadataClosure = BeforeExampleWithMetadataClosure +public typealias AfterExampleClosure = BeforeExampleClosure /** A closure executed after an example is run. The closure is given example metadata, which contains information about the example that has just finished running. */ -public typealias AfterExampleWithMetadataNonThrowingClosure = BeforeExampleWithMetadataNonThrowingClosure - -/** - A throwing closure which wraps an example. The closure must call runExample() exactly once. -*/ -public typealias AroundExampleClosure = (_ runExample: @escaping () -> Void) throws -> Void +public typealias AfterExampleWithMetadataClosure = BeforeExampleWithMetadataClosure /** A closure which wraps an example. The closure must call runExample() exactly once. */ -public typealias AroundExampleNonThrowingClosure = (_ runExample: @escaping () -> Void) -> Void +public typealias AroundExampleClosure = (_ runExample: @escaping () -> Void) -> Void /** - A throwing closure which wraps an example. The closure is given example metadata, + A closure which wraps an example. The closure is given example metadata, which contains information about the example that the wrapper will run. The closure must call runExample() exactly once. */ public typealias AroundExampleWithMetadataClosure = - (_ exampleMetadata: ExampleMetadata, _ runExample: @escaping () -> Void) throws -> Void - -/** - A throwing closure which wraps an example. The closure is given example metadata, - which contains information about the example that the wrapper will run. - The closure must call runExample() exactly once. -*/ -public typealias AroundExampleWithMetadataNonThrowingClosure = (_ exampleMetadata: ExampleMetadata, _ runExample: @escaping () -> Void) -> Void -/** - An async throwing closure which wraps an example. The closure must call runExample() exactly once. -*/ -public typealias AroundExampleAsyncClosure = (_ runExample: @escaping () async -> Void) async throws -> Void - -/** - An async throwing closure which wraps an example. The closure is given example metadata, - which contains information about the example that the wrapper will run. - The closure must call runExample() exactly once. -*/ -public typealias AroundExampleWithMetadataAsyncClosure = - (_ exampleMetadata: ExampleMetadata, _ runExample: @escaping () async -> Void) async throws -> Void - // MARK: Suite Hooks -/** - An async throwing closure executed before any examples are run. -*/ -public typealias BeforeSuiteAsyncClosure = () async throws -> Void - -/** - A throwing closure executed before any examples are run. -*/ -public typealias BeforeSuiteClosure = () throws -> Void - /** A closure executed before any examples are run. */ -public typealias BeforeSuiteNonThrowingClosure = () -> Void - -/** - An async throwing closure executed after all examples have finished running. -*/ -public typealias AfterSuiteAsyncClosure = BeforeSuiteAsyncClosure - -/** - A throwing closure executed after all examples have finished running. -*/ -public typealias AfterSuiteClosure = BeforeSuiteClosure +public typealias BeforeSuiteClosure = () -> Void /** A closure executed after all examples have finished running. */ -public typealias AfterSuiteNonThrowingClosure = BeforeSuiteNonThrowingClosure +public typealias AfterSuiteClosure = BeforeSuiteClosure diff --git a/Pods/Quick/Sources/Quick/Hooks/ExampleHooks.swift b/Pods/Quick/Sources/Quick/Hooks/ExampleHooks.swift index 0fc0384..51f004b 100644 --- a/Pods/Quick/Sources/Quick/Hooks/ExampleHooks.swift +++ b/Pods/Quick/Sources/Quick/Hooks/ExampleHooks.swift @@ -1,30 +1,20 @@ -import Foundation - /** A container for closures to be executed before and after each example. */ final internal class ExampleHooks { - internal var justBeforeEachStatements: [AroundExampleWithMetadataClosure] = [] internal var wrappers: [AroundExampleWithMetadataClosure] = [] internal var phase: HooksPhase = .nothingExecuted - internal func appendJustBeforeEach(_ closure: @escaping BeforeExampleClosure) { - justBeforeEachStatements.append { _, runExample in - try closure() - runExample() - } - } - internal func appendBefore(_ closure: @escaping BeforeExampleWithMetadataClosure) { wrappers.append { exampleMetadata, runExample in - try closure(exampleMetadata) + closure(exampleMetadata) runExample() } } internal func appendBefore(_ closure: @escaping BeforeExampleClosure) { wrappers.append { _, runExample in - try closure() + closure() runExample() } } @@ -32,14 +22,14 @@ final internal class ExampleHooks { internal func appendAfter(_ closure: @escaping AfterExampleWithMetadataClosure) { wrappers.prepend { exampleMetadata, runExample in runExample() - try closure(exampleMetadata) + closure(exampleMetadata) } } internal func appendAfter(_ closure: @escaping AfterExampleClosure) { wrappers.prepend { _, runExample in runExample() - try closure() + closure() } } @@ -48,7 +38,7 @@ final internal class ExampleHooks { } internal func appendAround(_ closure: @escaping AroundExampleClosure) { - wrappers.append { _, runExample in try closure(runExample) } + wrappers.append { _, runExample in closure(runExample) } } } diff --git a/Pods/Quick/Sources/Quick/Hooks/SuiteHooks.swift b/Pods/Quick/Sources/Quick/Hooks/SuiteHooks.swift index 337ff1f..b39292b 100644 --- a/Pods/Quick/Sources/Quick/Hooks/SuiteHooks.swift +++ b/Pods/Quick/Sources/Quick/Hooks/SuiteHooks.swift @@ -17,11 +17,7 @@ final internal class SuiteHooks { internal func executeBefores() { phase = .beforesExecuting for before in befores { - do { - try before() - } catch { - break - } + before() } phase = .beforesFinished } @@ -29,11 +25,7 @@ final internal class SuiteHooks { internal func executeAfters() { phase = .aftersExecuting for after in afters { - do { - try after() - } catch { - break - } + after() } phase = .aftersFinished } diff --git a/Pods/Quick/Sources/Quick/QuickTestObservation.swift b/Pods/Quick/Sources/Quick/QuickTestObservation.swift index 1c2c033..8bfc95b 100644 --- a/Pods/Quick/Sources/Quick/QuickTestObservation.swift +++ b/Pods/Quick/Sources/Quick/QuickTestObservation.swift @@ -5,7 +5,7 @@ import XCTest /// A dummy protocol for calling the internal `+[QuickSpec buildExamplesIfNeeded]` method /// which is defined in Objective-C from Swift. -@objc internal protocol _QuickSpecInternal { // swiftlint:disable:this type_name +@objc internal protocol _QuickSpecInternal { static func buildExamplesIfNeeded() } @@ -27,11 +27,52 @@ import XCTest guard !didBuildAllExamples else { return } didBuildAllExamples = true - allSubclasses(ofType: QuickSpec.self) - .forEach { (specClass: QuickSpec.Type) in - // This relies on `_QuickSpecInternal`. - (specClass as AnyClass).buildExamplesIfNeeded() + QuickSpec.enumerateSubclasses { specClass in + // This relies on `_QuickSpecInternal`. + (specClass as AnyClass).buildExamplesIfNeeded() + } + } +} + +// swiftlint:disable:next todo +// TODO: Unify this with QuickConfiguration's equivalent +extension QuickSpec { + internal static func enumerateSubclasses( + subclasses: [QuickSpec.Type]? = nil, + _ block: (QuickSpec.Type) -> Void + ) { + let subjects: [QuickSpec.Type] + if let subclasses = subclasses { + subjects = subclasses + } else { + let classesCount = objc_getClassList(nil, 0) + + guard classesCount > 0 else { + return } + + let classes = UnsafeMutablePointer.allocate(capacity: Int(classesCount)) + defer { free(classes) } + + let autoreleasingClasses = AutoreleasingUnsafeMutablePointer(classes) + objc_getClassList(autoreleasingClasses, classesCount) + + var specSubclasses: [QuickSpec.Type] = [] + for index in 0.. [ExampleWrapper] { + internal func examples(forSpecClass specClass: QuickSpec.Type) -> [Example] { // 1. Grab all included examples. - let included = includedExamples() + let included = includedExamples // 2. Grab the intersection of (a) examples for this spec, and (b) included examples. - let spec = rootExampleGroup(forSpecClass: specClass).examples.map { example in - return ExampleWrapper( - example: example, - runFullTest: included.first(where: { $0.example == example})?.runFullTest ?? false - ) - } + let spec = rootExampleGroup(forSpecClass: specClass).examples.filter { included.contains($0) } // 3. Remove all excluded examples. - return spec.map { test -> ExampleWrapper in - ExampleWrapper(example: test.example, runFullTest: test.runFullTest && !self.configuration.exclusionFilters.contains { $0(test.example) }) + return spec.filter { example in + !self.configuration.exclusionFilters.contains { $0(example) } } } @@ -200,7 +192,7 @@ final internal class World: _WorldBase { } internal var includedExampleCount: Int { - return includedExamples().count + return includedExamples.count } internal lazy var cachedIncludedExampleCount: Int = self.includedExampleCount @@ -209,7 +201,7 @@ final internal class World: _WorldBase { let suiteBeforesExecuting = suiteHooks.phase == .beforesExecuting let exampleBeforesExecuting = exampleHooks.phase == .beforesExecuting var groupBeforesExecuting = false - if let runningExampleGroup = currentExampleMetadata?.group { + if let runningExampleGroup = currentExampleMetadata?.example.group { groupBeforesExecuting = runningExampleGroup.phase == .beforesExecuting } @@ -220,7 +212,7 @@ final internal class World: _WorldBase { let suiteAftersExecuting = suiteHooks.phase == .aftersExecuting let exampleAftersExecuting = exampleHooks.phase == .aftersExecuting var groupAftersExecuting = false - if let runningExampleGroup = currentExampleMetadata?.group { + if let runningExampleGroup = currentExampleMetadata?.example.group { groupAftersExecuting = runningExampleGroup.phase == .aftersExecuting } @@ -236,7 +228,7 @@ final internal class World: _WorldBase { currentExampleGroup = previousExampleGroup } - private func allExamples() -> [Example] { + private var allExamples: [Example] { var all: [Example] = [] for (_, group) in specs { group.walkDownExamples { all.append($0) } @@ -244,32 +236,20 @@ final internal class World: _WorldBase { return all } - internal func hasFocusedExamples() -> Bool { - return allExamples().contains { example in + private var includedExamples: [Example] { + let all = allExamples + let included = all.filter { example in return self.configuration.inclusionFilters.contains { $0(example) } } - } - private func includedExamples() -> [ExampleWrapper] { - let all = allExamples() - let hasFocusedExamples = self.hasFocusedExamples() || AsyncWorld.sharedWorld.hasFocusedExamples() - - if !hasFocusedExamples && configuration.runAllWhenEverythingFiltered { - return all.map { example in - return ExampleWrapper( - example: example, - runFullTest: !self.configuration.exclusionFilters.contains { $0(example) } - ) + if included.isEmpty && configuration.runAllWhenEverythingFiltered { + let exceptExcluded = all.filter { example in + return !self.configuration.exclusionFilters.contains { $0(example) } } + + return exceptExcluded } else { - return all.map { example in - return ExampleWrapper( - example: example, - runFullTest: self.configuration.inclusionFilters.contains { - $0(example) - } - ) - } + return included } } @@ -285,23 +265,3 @@ final internal class World: _WorldBase { } } } - -#if canImport(Darwin) -// swiftlint:disable type_name -@objcMembers -internal class _ExampleWrapperBase: NSObject {} -#else -internal class _ExampleWrapperBase: NSObject {} -// swiftlint:enable type_name -#endif - -final internal class ExampleWrapper: _ExampleWrapperBase { - private(set) var example: Example - private(set) var runFullTest: Bool - - init(example: Example, runFullTest: Bool) { - self.example = example - self.runFullTest = runFullTest - super.init() - } -} diff --git a/Pods/Quick/Sources/QuickObjectiveC/DSL/QCKDSL.h b/Pods/Quick/Sources/QuickObjectiveC/DSL/QCKDSL.h index f2d52e7..d3e3f64 100644 --- a/Pods/Quick/Sources/QuickObjectiveC/DSL/QCKDSL.h +++ b/Pods/Quick/Sources/QuickObjectiveC/DSL/QCKDSL.h @@ -35,7 +35,7 @@ #define QuickSpecBegin(name) \ @interface name : QuickSpec; @end \ @implementation name \ - + (void)spec { \ + - (void)spec { \ /** @@ -65,7 +65,6 @@ QUICK_EXPORT void qck_afterEach(QCKDSLEmptyBlock closure); QUICK_EXPORT void qck_afterEachWithMetadata(QCKDSLExampleMetadataBlock closure); QUICK_EXPORT void qck_aroundEach(QCKDSLAroundExampleBlock closure); QUICK_EXPORT void qck_aroundEachWithMetadata(QCKDSLAroundExampleMetadataBlock closure); -QUICK_EXPORT void qck_justBeforeEach(QCKDSLEmptyBlock closure); QUICK_EXPORT void qck_pending(NSString *description, QCKDSLEmptyBlock closure); QUICK_EXPORT void qck_xdescribe(NSString *description, QCKDSLEmptyBlock closure); QUICK_EXPORT void qck_xcontext(NSString *description, QCKDSLEmptyBlock closure); @@ -74,178 +73,193 @@ QUICK_EXPORT void qck_fcontext(NSString *description, QCKDSLEmptyBlock closure); #ifndef QUICK_DISABLE_SHORT_SYNTAX /** - Defines a closure to be run prior to any examples in the test suite. - You may define an unlimited number of these closures, but there is no - guarantee as to the order in which they're run. + Defines a closure to be run prior to any examples in the test suite. + You may define an unlimited number of these closures, but there is no + guarantee as to the order in which they're run. - If the test suite crashes before the first example is run, this closure - will not be executed. + If the test suite crashes before the first example is run, this closure + will not be executed. - @param closure The closure to be run prior to any examples in the test suite. + @param closure The closure to be run prior to any examples in the test suite. */ static inline void beforeSuite(QCKDSLEmptyBlock closure) { qck_beforeSuite(closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Defines a closure to be run after all of the examples in the test suite. - You may define an unlimited number of these closures, but there is no - guarantee as to the order in which they're run. + Defines a closure to be run after all of the examples in the test suite. + You may define an unlimited number of these closures, but there is no + guarantee as to the order in which they're run. - If the test suite crashes before all examples are run, this closure - will not be executed. + If the test suite crashes before all examples are run, this closure + will not be executed. - @param closure The closure to be run after all of the examples in the test suite. + @param closure The closure to be run after all of the examples in the test suite. */ static inline void afterSuite(QCKDSLEmptyBlock closure) { qck_afterSuite(closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Defines a group of shared examples. These examples can be re-used in several locations - by using the ``itBehavesLike`` function. - - @param name The name of the shared example group. This must be unique across all shared example - groups defined in a test suite. - @param closure A closure containing the examples. This behaves just like an example group defined - using `describe` or `context`--the closure may contain any number of `beforeEach` - and `afterEach` closures, as well as any number of examples (defined using `it`). + Defines a group of shared examples. These examples can be re-used in several locations + by using the `itBehavesLike` function. + + @param name The name of the shared example group. This must be unique across all shared example + groups defined in a test suite. + @param closure A closure containing the examples. This behaves just like an example group defined + using `describe` or `context`--the closure may contain any number of `beforeEach` + and `afterEach` closures, as well as any number of examples (defined using `it`). */ static inline void sharedExamples(NSString *name, QCKDSLSharedExampleBlock closure) { qck_sharedExamples(name, closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Defines an example group. Example groups are logical groupings of examples. - Example groups can share setup and teardown code. + Defines an example group. Example groups are logical groupings of examples. + Example groups can share setup and teardown code. - @param description An arbitrary string describing the example group. - @param closure A closure that can contain other examples. + @param description An arbitrary string describing the example group. + @param closure A closure that can contain other examples. */ static inline void describe(NSString *description, QCKDSLEmptyBlock closure) { qck_describe(description, closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Defines an example group. Equivalent to ``describe(description, closure)``. + Defines an example group. Equivalent to `describe`. */ static inline void context(NSString *description, QCKDSLEmptyBlock closure) { qck_context(description, closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Defines a closure to be run prior to each example in the current example - group. This closure is not run for pending or otherwise disabled examples. - An example group may contain an unlimited number of beforeEach. They'll be - run in the order they're defined, but you shouldn't rely on that behavior. + Defines a closure to be run prior to each example in the current example + group. This closure is not run for pending or otherwise disabled examples. + An example group may contain an unlimited number of beforeEach. They'll be + run in the order they're defined, but you shouldn't rely on that behavior. - @param closure The closure to be run prior to each example. + @param closure The closure to be run prior to each example. */ static inline void beforeEach(QCKDSLEmptyBlock closure) { qck_beforeEach(closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Identical to ``beforeEach(closure)``, except the closure is provided with - metadata on the example that the closure is being run prior to. + Identical to QCKDSL.beforeEach, except the closure is provided with + metadata on the example that the closure is being run prior to. */ static inline void beforeEachWithMetadata(QCKDSLExampleMetadataBlock closure) { qck_beforeEachWithMetadata(closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Defines a closure to be run after each example in the current example - group. This closure is not run for pending or otherwise disabled examples. - An example group may contain an unlimited number of afterEach. They'll be - run in the order they're defined, but you shouldn't rely on that behavior. - - @param closure The closure to be run after each example. + Defines a closure to be run after each example in the current example + group. This closure is not run for pending or otherwise disabled examples. + An example group may contain an unlimited number of afterEach. They'll be + run in the order they're defined, but you shouldn't rely on that behavior. + + @param closure The closure to be run after each example. */ static inline void afterEach(QCKDSLEmptyBlock closure) { qck_afterEach(closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Identical to ``afterEach(closure)``, except the closure is provided with - metadata on the example that the closure is being run after. + Identical to QCKDSL.afterEach, except the closure is provided with + metadata on the example that the closure is being run after. */ static inline void afterEachWithMetadata(QCKDSLExampleMetadataBlock closure) { qck_afterEachWithMetadata(closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Defines a closure to be run around each example in the currente example group. - You must call the passed-in `runClosure` argument at least once in order to - run the example. This closure is not run for pending or otherwise disabled example. - An example group may contain an unlimited number of `aroundEach`. They'll be - run in the order they're defined, but you shouldn't rely on that behavior. - - @param closure The closure to run around each example. This closure itself takes - in a closure: the before-mentioned `runClosure` argument. The `runClosure` argument - must be called at once and only once. - */ + Defines a closure to that wraps each example in the current example + group. This closure is not run for pending or otherwise disabled examples. + + The closure you pass to aroundEach receives a callback as its argument, which + it MUST call exactly one for the example to run properly: + + aroundEach(^(QCKDSLEmptyBlock runExample) { + [self doSomeSetup]; + runExample(); + [self doSomeCleanup]; + }); + + This callback is particularly useful for test decartions that can’t split + into a separate beforeEach and afterEach. For example, running each example + in its own autorelease pool requires aroundEach: + + aroundEach(^(QCKDSLEmptyBlock runExample) { + @autoreleasepool { + runExample(); + } + [self checkObjectsNoLongerRetained]; + }); + + You can also use aroundEach to guarantee proper nesting of setup and cleanup + operations in situations where their relative order matters. + + An example group may contain an unlimited number of aroundEach callbacks. + They will nest inside each other, with the first declared in the group + nested at the outermost level. + + - parameter closure: The closure that wraps around each example. +*/ static inline void aroundEach(QCKDSLAroundExampleBlock closure) { qck_aroundEach(closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Identical to ``aroundEach(closure)``, except the closure is provided with - metadata on the example that the closure is being run around. - - @param closure The closure to run around each example. This closure itself takes - in an ``ExampleMetadata-swift.class`` object and a closure. - The ``ExampleMetadata-swift.class`` provides information about the example being run around. - The closure is the example to run, and must be called at once and only once. + Identical to Quick.DSL.aroundEach, except the closure receives metadata + about the example that the closure wraps. */ static inline void aroundEachWithMetadata(QCKDSLAroundExampleMetadataBlock closure) { qck_aroundEachWithMetadata(closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Defines a closure to be run prior to each example but after any beforeEach blocks. - This closure is not run for pending or otherwise disabled examples. - An example group may contain an unlimited number of justBeforeEach. They'll be - run in the order they're defined, but you shouldn't rely on that behavior. - - @param closure The closure to be run prior to each example but before any beforeEach blocks in the test suite. + Defines an example or example group that should not be executed. Use `pending` to temporarily disable + examples or groups that should not be run yet. + + @param description An arbitrary string describing the example or example group. + @param closure A closure that will not be evaluated. */ -static inline void justBeforeEach(QCKDSLEmptyBlock closure) { - qck_justBeforeEach(closure); -} NS_SWIFT_UNAVAILABLE("") +static inline void pending(NSString *description, QCKDSLEmptyBlock closure) { + qck_pending(description, closure); +} /** - Use this to quickly mark a ``describe(description, closure)`` block as pending. - This disables all examples within the block. + Use this to quickly mark a `describe` block as pending. + This disables all examples within the block. */ static inline void xdescribe(NSString *description, QCKDSLEmptyBlock closure) { qck_xdescribe(description, closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Use this to quickly mark a ``context(description, closure)`` block as pending. - This disables all examples within the block. + Use this to quickly mark a `context` block as pending. + This disables all examples within the block. */ static inline void xcontext(NSString *description, QCKDSLEmptyBlock closure) { qck_xcontext(description, closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Use this to quickly focus a ``describe(description, closure)`` block, focusing the examples in the block. - If any examples in the test suite are focused, only those examples are executed. - This trumps any explicitly focused or unfocused examples within the block--they are all treated as focused. + Use this to quickly focus a `describe` block, focusing the examples in the block. + If any examples in the test suite are focused, only those examples are executed. + This trumps any explicitly focused or unfocused examples within the block--they are all treated as focused. */ static inline void fdescribe(NSString *description, QCKDSLEmptyBlock closure) { qck_fdescribe(description, closure); -} NS_SWIFT_UNAVAILABLE("") +} /** - Use this to quickly focus a ``context(description, closure)`` block. - Equivalent to ``fdescribe(description, closure)``. + Use this to quickly focus a `context` block. Equivalent to `fdescribe`. */ static inline void fcontext(NSString *description, QCKDSLEmptyBlock closure) { qck_fcontext(description, closure); -} NS_SWIFT_UNAVAILABLE("") +} #define it qck_it #define xit qck_xit @@ -253,7 +267,6 @@ static inline void fcontext(NSString *description, QCKDSLEmptyBlock closure) { #define itBehavesLike qck_itBehavesLike #define xitBehavesLike qck_xitBehavesLike #define fitBehavesLike qck_fitBehavesLike -#define pending qck_pending #endif #define qck_it qck_it_builder(@(__FILE__), __LINE__) @@ -262,15 +275,13 @@ static inline void fcontext(NSString *description, QCKDSLEmptyBlock closure) { #define qck_itBehavesLike qck_itBehavesLike_builder(@(__FILE__), __LINE__) #define qck_xitBehavesLike qck_xitBehavesLike_builder(@(__FILE__), __LINE__) #define qck_fitBehavesLike qck_fitBehavesLike_builder(@(__FILE__), __LINE__) -#define qck_pending qck_pending_builder(@(__FILE__), __LINE__) typedef void (^QCKItBlock)(NSString *description, QCKDSLEmptyBlock closure); typedef void (^QCKItBehavesLikeBlock)(NSString *description, QCKDSLSharedExampleContext context); -QUICK_EXPORT QCKItBlock qck_it_builder(NSString *file, NSUInteger line) NS_SWIFT_UNAVAILABLE(""); -QUICK_EXPORT QCKItBlock qck_xit_builder(NSString *file, NSUInteger line) NS_SWIFT_UNAVAILABLE(""); -QUICK_EXPORT QCKItBlock qck_fit_builder(NSString *file, NSUInteger line) NS_SWIFT_UNAVAILABLE(""); -QUICK_EXPORT QCKItBehavesLikeBlock qck_itBehavesLike_builder(NSString *file, NSUInteger line) NS_SWIFT_UNAVAILABLE(""); -QUICK_EXPORT QCKItBehavesLikeBlock qck_xitBehavesLike_builder(NSString *file, NSUInteger line) NS_SWIFT_UNAVAILABLE(""); -QUICK_EXPORT QCKItBehavesLikeBlock qck_fitBehavesLike_builder(NSString *file, NSUInteger line) NS_SWIFT_UNAVAILABLE(""); -QUICK_EXPORT QCKItBlock qck_pending_builder(NSString *file, NSUInteger line) NS_SWIFT_UNAVAILABLE(""); +QUICK_EXPORT QCKItBlock qck_it_builder(NSString *file, NSUInteger line); +QUICK_EXPORT QCKItBlock qck_xit_builder(NSString *file, NSUInteger line); +QUICK_EXPORT QCKItBlock qck_fit_builder(NSString *file, NSUInteger line); +QUICK_EXPORT QCKItBehavesLikeBlock qck_itBehavesLike_builder(NSString *file, NSUInteger line); +QUICK_EXPORT QCKItBehavesLikeBlock qck_xitBehavesLike_builder(NSString *file, NSUInteger line); +QUICK_EXPORT QCKItBehavesLikeBlock qck_fitBehavesLike_builder(NSString *file, NSUInteger line); diff --git a/Pods/Quick/Sources/QuickObjectiveC/DSL/QCKDSL.m b/Pods/Quick/Sources/QuickObjectiveC/DSL/QCKDSL.m index ba30410..9285265 100644 --- a/Pods/Quick/Sources/QuickObjectiveC/DSL/QCKDSL.m +++ b/Pods/Quick/Sources/QuickObjectiveC/DSL/QCKDSL.m @@ -42,10 +42,6 @@ void qck_afterEachWithMetadata(QCKDSLExampleMetadataBlock closure) { [[World sharedWorld] afterEachWithMetadata:closure]; } -void qck_justBeforeEach(QCKDSLEmptyBlock closure) { - [[World sharedWorld] justBeforeEach:closure]; -} - void qck_aroundEach(QCKDSLAroundExampleBlock closure) { [[World sharedWorld] aroundEach:closure]; } @@ -108,10 +104,16 @@ QCKItBehavesLikeBlock qck_fitBehavesLike_builder(NSString *file, NSUInteger line }; } -QCKItBlock qck_pending_builder(NSString *file, NSUInteger line) { - return ^(NSString *description, QCKDSLEmptyBlock closure) { - [[World sharedWorld] pendingWithDescription:description file:file line:line closure:closure]; - }; +void qck_pending(NSString *description, QCKDSLEmptyBlock closure) { + [[World sharedWorld] pending:description closure:closure]; +} + +void qck_xdescribe(NSString *description, QCKDSLEmptyBlock closure) { + [[World sharedWorld] xdescribe:description closure:closure]; +} + +void qck_xcontext(NSString *description, QCKDSLEmptyBlock closure) { + qck_xdescribe(description, closure); } void qck_fdescribe(NSString *description, QCKDSLEmptyBlock closure) { diff --git a/Pods/Quick/Sources/QuickObjectiveC/QuickSpec.h b/Pods/Quick/Sources/QuickObjectiveC/QuickSpec.h index e4d3e5e..ccf006e 100644 --- a/Pods/Quick/Sources/QuickObjectiveC/QuickSpec.h +++ b/Pods/Quick/Sources/QuickObjectiveC/QuickSpec.h @@ -34,7 +34,7 @@ and examples. @code - override class func spec() { + override func spec() { describe("winter") { it("is coming") { // ... @@ -45,13 +45,11 @@ See DSL.swift for more information on what syntax is available. */ -+ (void)spec; +- (void)spec; /** Returns the currently executing spec. Use in specs that require XCTestCase methods, e.g. expectationWithDescription. - - If you're using `beforeSuite`/`afterSuite`, you should consider the ``currentSpec()`` helper. */ @property (class, nonatomic, readonly) QuickSpec *current; diff --git a/Pods/Quick/Sources/QuickObjectiveC/QuickSpec.m b/Pods/Quick/Sources/QuickObjectiveC/QuickSpec.m index a7d83a1..2d6b1fc 100644 --- a/Pods/Quick/Sources/QuickObjectiveC/QuickSpec.m +++ b/Pods/Quick/Sources/QuickObjectiveC/QuickSpec.m @@ -28,13 +28,13 @@ + (NSArray *)testInvocations { // In case of fix in later versions next line can be removed [[QuickTestObservation sharedInstance] buildAllExamplesIfNeeded]; - NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; + NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[examples count]]; NSMutableSet *selectorNames = [NSMutableSet set]; - for (ExampleWrapper *exampleWrapper in examples) { - SEL selector = [self addInstanceMethodForExample:exampleWrapper.example runFullTest:exampleWrapper.runFullTest classSelectorNames:selectorNames]; + for (Example *example in examples) { + SEL selector = [self addInstanceMethodForExample:example classSelectorNames:selectorNames]; NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; @@ -46,27 +46,9 @@ + (NSArray *)testInvocations { return invocations; } -/** - This method is used as a hook for injecting test methods into the - Objective-C runtime on individual test runs. - - When `xctest` runs a test on a single method, it does not call - `defaultTestSuite` on the test class but rather calls - `instancesRespondToSelector:` to build its own suite. - - In normal conditions, Quick uses the implicit call to `defaultTestSuite` - to both generate examples and inject them as methods by way of - `testInvocations`. Under single test conditions, there's no implicit - call to `defaultTestSuite` so we make it explicitly here. - */ -+ (BOOL)instancesRespondToSelector:(SEL)aSelector { - [self defaultTestSuite]; - return [super instancesRespondToSelector:aSelector]; -} - #pragma mark - Public Interface -+ (void)spec { } +- (void)spec { } + (QuickSpec*) current { return currentSpec; @@ -91,8 +73,10 @@ + (void)buildExamplesIfNeeded { ExampleGroup *rootExampleGroup = [world rootExampleGroupForSpecClass:[self class]]; [world performWithCurrentExampleGroup:rootExampleGroup closure:^{ + QuickSpec *spec = [self new]; + @try { - [self spec]; + [spec spec]; } @catch (NSException *exception) { [NSException raise:NSInternalInconsistencyException @@ -124,24 +108,25 @@ + (void)buildExamplesIfNeeded { @return The selector of the newly defined instance method. */ -+ (SEL)addInstanceMethodForExample:(Example *)example runFullTest:(BOOL)runFullTest classSelectorNames:(NSMutableSet *)selectorNames { ++ (SEL)addInstanceMethodForExample:(Example *)example classSelectorNames:(NSMutableSet *)selectorNames { IMP implementation = imp_implementationWithBlock(^(QuickSpec *self){ self.example = example; currentSpec = self; - if (runFullTest) { - [example run]; - } else { - [example runSkippedTest]; - } - currentSpec = nil; + [example run]; }); const char *types = [[NSString stringWithFormat:@"%s%s%s", @encode(void), @encode(id), @encode(SEL)] UTF8String]; - NSString *selectorName = [TestSelectorNameProvider testSelectorNameFor:example classSelectorNames:selectorNames]; - + NSString *originalName = [QCKObjCStringUtils c99ExtendedIdentifierFrom:example.name]; + NSString *selectorName = originalName; + NSUInteger i = 2; + + while ([selectorNames containsObject:selectorName]) { + selectorName = [NSString stringWithFormat:@"%@_%tu", originalName, i++]; + } + [selectorNames addObject:selectorName]; - + SEL selector = NSSelectorFromString(selectorName); class_addMethod(self, selector, implementation, types); diff --git a/Pods/Target Support Files/Nimble/Nimble-Info.plist b/Pods/Target Support Files/Nimble/Nimble-Info.plist index dced619..a451985 100644 --- a/Pods/Target Support Files/Nimble/Nimble-Info.plist +++ b/Pods/Target Support Files/Nimble/Nimble-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - ${PODS_DEVELOPMENT_LANGUAGE} + en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 13.2.1 + 10.0.0 CFBundleSignature ???? CFBundleVersion diff --git a/Pods/Target Support Files/Nimble/Nimble-umbrella.h b/Pods/Target Support Files/Nimble/Nimble-umbrella.h index 35609a7..15ed932 100644 --- a/Pods/Target Support Files/Nimble/Nimble-umbrella.h +++ b/Pods/Target Support Files/Nimble/Nimble-umbrella.h @@ -14,6 +14,9 @@ #import "DSL.h" #import "NMBExceptionCapture.h" #import "NMBStringify.h" +#import "CwlCatchException.h" +#import "CwlMachBadInstructionHandler.h" +#import "mach_excServer.h" FOUNDATION_EXPORT double NimbleVersionNumber; FOUNDATION_EXPORT const unsigned char NimbleVersionString[]; diff --git a/Pods/Target Support Files/Nimble/Nimble.debug.xcconfig b/Pods/Target Support Files/Nimble/Nimble.debug.xcconfig index c3b0599..32f7768 100644 --- a/Pods/Target Support Files/Nimble/Nimble.debug.xcconfig +++ b/Pods/Target Support Files/Nimble/Nimble.debug.xcconfig @@ -4,17 +4,18 @@ CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Nimble DEFINES_MODULE = YES ENABLE_BITCODE = NO ENABLE_TESTING_SEARCH_PATHS = YES -FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/CwlCatchException" "${PODS_CONFIGURATION_BUILD_DIR}/CwlCatchExceptionSupport" "${PODS_CONFIGURATION_BUILD_DIR}/CwlMachBadInstructionHandler" "${PODS_CONFIGURATION_BUILD_DIR}/CwlPosixPreconditionTesting" "${PODS_CONFIGURATION_BUILD_DIR}/CwlPreconditionTesting" +FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift -OTHER_LDFLAGS = $(inherited) -Xlinker -no_application_extension -weak-lXCTestSwiftSupport -framework "CwlPreconditionTesting" -weak_framework "XCTest" +LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -Xlinker -no_application_extension -weak-lXCTestSwiftSupport -weak_framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS $(inherited) -suppress-warnings PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Nimble PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES +SWIFT_INCLUDE_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" +SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Nimble/Nimble.release.xcconfig b/Pods/Target Support Files/Nimble/Nimble.release.xcconfig index c3b0599..32f7768 100644 --- a/Pods/Target Support Files/Nimble/Nimble.release.xcconfig +++ b/Pods/Target Support Files/Nimble/Nimble.release.xcconfig @@ -4,17 +4,18 @@ CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Nimble DEFINES_MODULE = YES ENABLE_BITCODE = NO ENABLE_TESTING_SEARCH_PATHS = YES -FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/CwlCatchException" "${PODS_CONFIGURATION_BUILD_DIR}/CwlCatchExceptionSupport" "${PODS_CONFIGURATION_BUILD_DIR}/CwlMachBadInstructionHandler" "${PODS_CONFIGURATION_BUILD_DIR}/CwlPosixPreconditionTesting" "${PODS_CONFIGURATION_BUILD_DIR}/CwlPreconditionTesting" +FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift -OTHER_LDFLAGS = $(inherited) -Xlinker -no_application_extension -weak-lXCTestSwiftSupport -framework "CwlPreconditionTesting" -weak_framework "XCTest" +LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -Xlinker -no_application_extension -weak-lXCTestSwiftSupport -weak_framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS $(inherited) -suppress-warnings PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Nimble PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES +SWIFT_INCLUDE_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" +SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-Info.plist b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-Info.plist index 19cf209..2243fe6 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-Info.plist +++ b/Pods/Target Support Files/Pods-OSPaymentsLib-OSPaymentsLibTests/Pods-OSPaymentsLib-OSPaymentsLibTests-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - ${PODS_DEVELOPMENT_LANGUAGE} + en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-Info.plist b/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-Info.plist index 19cf209..2243fe6 100644 --- a/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-Info.plist +++ b/Pods/Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - ${PODS_DEVELOPMENT_LANGUAGE} + en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/Pods/Target Support Files/Quick/Quick-Info.plist b/Pods/Target Support Files/Quick/Quick-Info.plist index 8cc444f..8d87a1a 100644 --- a/Pods/Target Support Files/Quick/Quick-Info.plist +++ b/Pods/Target Support Files/Quick/Quick-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - ${PODS_DEVELOPMENT_LANGUAGE} + en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 7.5.0 + 5.0.1 CFBundleSignature ???? CFBundleVersion diff --git a/Pods/Target Support Files/Quick/Quick.debug.xcconfig b/Pods/Target Support Files/Quick/Quick.debug.xcconfig index d949e13..ddea45d 100644 --- a/Pods/Target Support Files/Quick/Quick.debug.xcconfig +++ b/Pods/Target Support Files/Quick/Quick.debug.xcconfig @@ -6,15 +6,16 @@ ENABLE_BITCODE = NO ENABLE_TESTING_SEARCH_PATHS = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -Xlinker -no_application_extension -framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Quick PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES +SWIFT_INCLUDE_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" +SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Quick/Quick.release.xcconfig b/Pods/Target Support Files/Quick/Quick.release.xcconfig index d949e13..ddea45d 100644 --- a/Pods/Target Support Files/Quick/Quick.release.xcconfig +++ b/Pods/Target Support Files/Quick/Quick.release.xcconfig @@ -6,15 +6,16 @@ ENABLE_BITCODE = NO ENABLE_TESTING_SEARCH_PATHS = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -Xlinker -no_application_extension -framework "XCTest" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/Quick PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES +SWIFT_INCLUDE_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib" +SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 382f551..873a933 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,35 +4,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 1.1.1 - -### 2023-02-08 -- Make library available as `xcframework` (https://outsystemsrd.atlassian.net/browse/RMET-2280). - -## 1.1.0 - -### 2023-01-05 -- Feat: Add access token to Full Payment Process (https://outsystemsrd.atlassian.net/browse/RMET-2147). - -### 2022-12-12 -- Feat: Add Payment Service Provider property to `OSPMTDetailsModel` struct (https://outsystemsrd.atlassian.net/browse/RMET-2095). - -### 2022-12-02 -- Feat: Add Stripe as Payment Service Provider (https://outsystemsrd.atlassian.net/browse/RMET-2078). - -### 2022-11-14 -- Add `podspec` file. - -## 1.0.0 - ### 2022-08-03 + - Feat: Set Payment Details (https://outsystemsrd.atlassian.net/browse/RMET-1723). ### 2022-08-02 + - Feat: Check Wallet Availability for Payment (https://outsystemsrd.atlassian.net/browse/RMET-1695). ### 2022-08-01 + - Feat: Setup Apple Pay Configurations (https://outsystemsrd.atlassian.net/browse/RMET-1722). ### 2022-04-12 + - Create repository.