diff --git a/NodeKit.xcodeproj/project.pbxproj b/NodeKit.xcodeproj/project.pbxproj index af425f33..5c70d00a 100644 --- a/NodeKit.xcodeproj/project.pbxproj +++ b/NodeKit.xcodeproj/project.pbxproj @@ -15,17 +15,10 @@ 390E697B2A13660C007F2304 /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390E69782A13660C007F2304 /* MultipartFormData.swift */; }; 390E697C2A13660C007F2304 /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390E69792A13660C007F2304 /* AFError.swift */; }; 390E697D2A13660C007F2304 /* HTTPHeaders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390E697A2A13660C007F2304 /* HTTPHeaders.swift */; }; - 5005EB1A2BB88E1100B670CD /* NodeAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB192BB88E1100B670CD /* NodeAdapter.swift */; }; - 5005EB1C2BB88EC500B670CD /* CombineNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB1B2BB88EC500B670CD /* CombineNode.swift */; }; - 5005EB1E2BB8A6B100B670CD /* CombineConvertibleNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB1D2BB8A6B100B670CD /* CombineConvertibleNode.swift */; }; + 5005EB1C2BB88EC500B670CD /* CombineStreamNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB1B2BB88EC500B670CD /* CombineStreamNode.swift */; }; 5005EB212BB8A6D000B670CD /* AsyncNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB202BB8A6D000B670CD /* AsyncNode.swift */; }; 5005EB232BB8A6D900B670CD /* AsyncStreamNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB222BB8A6D900B670CD /* AsyncStreamNode.swift */; }; - 5005EB262BB8A78B00B670CD /* CombineCompatibleNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB252BB8A78B00B670CD /* CombineCompatibleNodeTests.swift */; }; - 5005EB282BB8A79800B670CD /* AsyncNodeAdapterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB272BB8A79800B670CD /* AsyncNodeAdapterTests.swift */; }; - 5005EB2A2BB8A7A300B670CD /* AsyncStreamNodeAdapterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB292BB8A7A300B670CD /* AsyncStreamNodeAdapterTests.swift */; }; - 5005EB312BB9918700B670CD /* NodeAdapterOutputMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB302BB9918700B670CD /* NodeAdapterOutputMock.swift */; }; 5005EB332BB9935400B670CD /* AsyncStreamNodeMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB322BB9935400B670CD /* AsyncStreamNodeMock.swift */; }; - 5005EB382BB99BE600B670CD /* NodeAdapterMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB372BB99BE600B670CD /* NodeAdapterMock.swift */; }; 5005EB3C2BB9B1C800B670CD /* AsyncNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB3B2BB9B1C800B670CD /* AsyncNodeTests.swift */; }; 5005EB3E2BB9B4A300B670CD /* AsyncStreamNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB3D2BB9B4A300B670CD /* AsyncStreamNodeTests.swift */; }; 5005EB422BB9BC2500B670CD /* MockError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB412BB9BC2500B670CD /* MockError.swift */; }; @@ -41,6 +34,14 @@ 50528E332BAE295D00E86CB6 /* TokenRefresherActorMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50528E322BAE295D00E86CB6 /* TokenRefresherActorMock.swift */; }; 50528E372BAE34A400E86CB6 /* TokenRefresherActorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50528E362BAE34A400E86CB6 /* TokenRefresherActorTests.swift */; }; 50528E392BAE39AE00E86CB6 /* AborterMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50528E382BAE39AE00E86CB6 /* AborterMock.swift */; }; + 50C8EB282BBD7A2200C5CB93 /* AsyncStreamCombineNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB272BBD7A2200C5CB93 /* AsyncStreamCombineNode.swift */; }; + 50C8EB2A2BBD7DEA00C5CB93 /* CombineNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB292BBD7DEA00C5CB93 /* CombineNode.swift */; }; + 50C8EB2C2BBD8EBE00C5CB93 /* CombineNodeMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB2B2BBD8EBE00C5CB93 /* CombineNodeMock.swift */; }; + 50C8EB2E2BBD8FC000C5CB93 /* CombineStreamNodeMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB2D2BBD8FC000C5CB93 /* CombineStreamNodeMock.swift */; }; + 50C8EB302BBD90DE00C5CB93 /* CombineNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB2F2BBD90DE00C5CB93 /* CombineNodeTests.swift */; }; + 50C8EB322BBD932D00C5CB93 /* CombineStreamNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB312BBD932D00C5CB93 /* CombineStreamNodeTests.swift */; }; + 50C8EB342BBD951500C5CB93 /* AsyncStreamCombineNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB332BBD951500C5CB93 /* AsyncStreamCombineNodeTests.swift */; }; + 50C8EB362BBD9CBF00C5CB93 /* NodeResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB352BBD9CBF00C5CB93 /* NodeResultTests.swift */; }; 90B608D4283E1110006F4309 /* NodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90B608CB283E1110006F4309 /* NodeKit.framework */; }; 90B608DA283E1110006F4309 /* NodeKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 90B608CE283E1110006F4309 /* NodeKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 90B6090E283E1268006F4309 /* UrlCacheReaderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608E4283E1268006F4309 /* UrlCacheReaderNode.swift */; }; @@ -185,17 +186,10 @@ 390E69782A13660C007F2304 /* MultipartFormData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipartFormData.swift; sourceTree = ""; }; 390E69792A13660C007F2304 /* AFError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AFError.swift; sourceTree = ""; }; 390E697A2A13660C007F2304 /* HTTPHeaders.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPHeaders.swift; sourceTree = ""; }; - 5005EB192BB88E1100B670CD /* NodeAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeAdapter.swift; sourceTree = ""; }; - 5005EB1B2BB88EC500B670CD /* CombineNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineNode.swift; sourceTree = ""; }; - 5005EB1D2BB8A6B100B670CD /* CombineConvertibleNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineConvertibleNode.swift; sourceTree = ""; }; + 5005EB1B2BB88EC500B670CD /* CombineStreamNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineStreamNode.swift; sourceTree = ""; }; 5005EB202BB8A6D000B670CD /* AsyncNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncNode.swift; sourceTree = ""; }; 5005EB222BB8A6D900B670CD /* AsyncStreamNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncStreamNode.swift; sourceTree = ""; }; - 5005EB252BB8A78B00B670CD /* CombineCompatibleNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineCompatibleNodeTests.swift; sourceTree = ""; }; - 5005EB272BB8A79800B670CD /* AsyncNodeAdapterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncNodeAdapterTests.swift; sourceTree = ""; }; - 5005EB292BB8A7A300B670CD /* AsyncStreamNodeAdapterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncStreamNodeAdapterTests.swift; sourceTree = ""; }; - 5005EB302BB9918700B670CD /* NodeAdapterOutputMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeAdapterOutputMock.swift; sourceTree = ""; }; 5005EB322BB9935400B670CD /* AsyncStreamNodeMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncStreamNodeMock.swift; sourceTree = ""; }; - 5005EB372BB99BE600B670CD /* NodeAdapterMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeAdapterMock.swift; sourceTree = ""; }; 5005EB3B2BB9B1C800B670CD /* AsyncNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncNodeTests.swift; sourceTree = ""; }; 5005EB3D2BB9B4A300B670CD /* AsyncStreamNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncStreamNodeTests.swift; sourceTree = ""; }; 5005EB412BB9BC2500B670CD /* MockError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockError.swift; sourceTree = ""; }; @@ -211,6 +205,14 @@ 50528E322BAE295D00E86CB6 /* TokenRefresherActorMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenRefresherActorMock.swift; sourceTree = ""; }; 50528E362BAE34A400E86CB6 /* TokenRefresherActorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenRefresherActorTests.swift; sourceTree = ""; }; 50528E382BAE39AE00E86CB6 /* AborterMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AborterMock.swift; sourceTree = ""; }; + 50C8EB272BBD7A2200C5CB93 /* AsyncStreamCombineNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncStreamCombineNode.swift; sourceTree = ""; }; + 50C8EB292BBD7DEA00C5CB93 /* CombineNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineNode.swift; sourceTree = ""; }; + 50C8EB2B2BBD8EBE00C5CB93 /* CombineNodeMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineNodeMock.swift; sourceTree = ""; }; + 50C8EB2D2BBD8FC000C5CB93 /* CombineStreamNodeMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineStreamNodeMock.swift; sourceTree = ""; }; + 50C8EB2F2BBD90DE00C5CB93 /* CombineNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineNodeTests.swift; sourceTree = ""; }; + 50C8EB312BBD932D00C5CB93 /* CombineStreamNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineStreamNodeTests.swift; sourceTree = ""; }; + 50C8EB332BBD951500C5CB93 /* AsyncStreamCombineNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncStreamCombineNodeTests.swift; sourceTree = ""; }; + 50C8EB352BBD9CBF00C5CB93 /* NodeResultTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeResultTests.swift; sourceTree = ""; }; 90B608CB283E1110006F4309 /* NodeKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NodeKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 90B608CE283E1110006F4309 /* NodeKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NodeKit.h; sourceTree = ""; }; 90B608D3283E1110006F4309 /* NodeKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NodeKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -398,9 +400,9 @@ 5005EB182BB88DD500B670CD /* Combine */ = { isa = PBXGroup; children = ( - 5005EB192BB88E1100B670CD /* NodeAdapter.swift */, - 5005EB1B2BB88EC500B670CD /* CombineNode.swift */, - 5005EB1D2BB8A6B100B670CD /* CombineConvertibleNode.swift */, + 5005EB1B2BB88EC500B670CD /* CombineStreamNode.swift */, + 50C8EB272BBD7A2200C5CB93 /* AsyncStreamCombineNode.swift */, + 50C8EB292BBD7DEA00C5CB93 /* CombineNode.swift */, ); path = Combine; sourceTree = ""; @@ -414,24 +416,14 @@ path = Async; sourceTree = ""; }; - 5005EB242BB8A77300B670CD /* Combine */ = { - isa = PBXGroup; - children = ( - 5005EB252BB8A78B00B670CD /* CombineCompatibleNodeTests.swift */, - 5005EB272BB8A79800B670CD /* AsyncNodeAdapterTests.swift */, - 5005EB292BB8A7A300B670CD /* AsyncStreamNodeAdapterTests.swift */, - ); - path = Combine; - sourceTree = ""; - }; 5005EB2F2BB9917E00B670CD /* Mocks */ = { isa = PBXGroup; children = ( - 5005EB372BB99BE600B670CD /* NodeAdapterMock.swift */, 50528E2B2BAE18F400E86CB6 /* AsyncNodeMock.swift */, - 5005EB302BB9918700B670CD /* NodeAdapterOutputMock.swift */, 5005EB322BB9935400B670CD /* AsyncStreamNodeMock.swift */, 5005EB412BB9BC2500B670CD /* MockError.swift */, + 50C8EB2B2BBD8EBE00C5CB93 /* CombineNodeMock.swift */, + 50C8EB2D2BBD8FC000C5CB93 /* CombineStreamNodeMock.swift */, ); path = Mocks; sourceTree = ""; @@ -474,14 +466,25 @@ 50528E2A2BAE18DD00E86CB6 /* Node */ = { isa = PBXGroup; children = ( + 506150AE2BBC24AE00EBBE96 /* Combine */, 5005EB3F2BB9BBFD00B670CD /* CastHelper */, 5005EB3A2BB9B1BE00B670CD /* Async */, 5005EB2F2BB9917E00B670CD /* Mocks */, - 5005EB242BB8A77300B670CD /* Combine */, + 50C8EB352BBD9CBF00C5CB93 /* NodeResultTests.swift */, ); path = Node; sourceTree = ""; }; + 506150AE2BBC24AE00EBBE96 /* Combine */ = { + isa = PBXGroup; + children = ( + 50C8EB2F2BBD90DE00C5CB93 /* CombineNodeTests.swift */, + 50C8EB312BBD932D00C5CB93 /* CombineStreamNodeTests.swift */, + 50C8EB332BBD951500C5CB93 /* AsyncStreamCombineNodeTests.swift */, + ); + path = Combine; + sourceTree = ""; + }; 90B608C1283E1110006F4309 = { isa = PBXGroup; children = ( @@ -1248,13 +1251,13 @@ 90B60989283E1287006F4309 /* URLQueryBoolEncodingStartegy.swift in Sources */, 390E696C2A13654A007F2304 /* RequestSenderNode.swift in Sources */, 90B609BE283E1287006F4309 /* LoggerNode.swift in Sources */, - 5005EB1A2BB88E1100B670CD /* NodeAdapter.swift in Sources */, 90B609B4283E1287006F4309 /* ServerRequestsManager.swift in Sources */, 90B6092C283E1268006F4309 /* ObservableProtocol.swift in Sources */, 90B60927283E1268006F4309 /* Observer+Shugar.swift in Sources */, 90B60990283E1287006F4309 /* RequstEncoderNode.swift in Sources */, 90B609A4283E1287006F4309 /* ResponseDataPreprocessorNode.swift in Sources */, 90B609A6283E1287006F4309 /* DTOMapperNode.swift in Sources */, + 50C8EB282BBD7A2200C5CB93 /* AsyncStreamCombineNode.swift in Sources */, 90B609AE283E1287006F4309 /* LayerTypes.swift in Sources */, 90B60996283E1287006F4309 /* VoidIONode.swift in Sources */, 90B60912283E1268006F4309 /* IfServerFailsFromCacheNode.swift in Sources */, @@ -1264,6 +1267,7 @@ 90B609A0283E1287006F4309 /* ResponseHttpErrorProcessorNode.swift in Sources */, 90B6099F283E1287006F4309 /* HeaderInjectorNode.swift in Sources */, 5005EB212BB8A6D000B670CD /* AsyncNode.swift in Sources */, + 50C8EB2A2BBD7DEA00C5CB93 /* CombineNode.swift in Sources */, 90B609A5283E1287006F4309 /* ResponseProcessorNode.swift in Sources */, 90B60995283E1287006F4309 /* DTOEncoderNode.swift in Sources */, 390E69722A136586007F2304 /* UrlJsonRequestEncodingNode.swift in Sources */, @@ -1275,7 +1279,7 @@ 390E697C2A13660C007F2304 /* AFError.swift in Sources */, 90B609B8283E1287006F4309 /* AnyAsyncIterator.swift in Sources */, 90B60986283E1287006F4309 /* RequestRouterNode.swift in Sources */, - 5005EB1C2BB88EC500B670CD /* CombineNode.swift in Sources */, + 5005EB1C2BB88EC500B670CD /* CombineStreamNode.swift in Sources */, 90B6091A283E1268006F4309 /* RawMappable+Dictionary.swift in Sources */, 90B609A7283E1287006F4309 /* RawEncoderNode.swift in Sources */, 90B609B9283E1287006F4309 /* OffsetAsyncPager.swift in Sources */, @@ -1304,7 +1308,6 @@ 90B60915283E1268006F4309 /* UrlETagReaderNode.swift in Sources */, 90B60985283E1287006F4309 /* UrlRequestTrasformatorNode.swift in Sources */, 390E69702A136586007F2304 /* NodeParameterEncoding.swift in Sources */, - 5005EB1E2BB8A6B100B670CD /* CombineConvertibleNode.swift in Sources */, 502F9DA92BAB0CF000151A8D /* TokenRefresherActor.swift in Sources */, 90B60928283E1268006F4309 /* CancelableContext.swift in Sources */, 90B609C1283E1287006F4309 /* Log.swift in Sources */, @@ -1320,30 +1323,32 @@ files = ( 90B60A07283E16DC006F4309 /* User.swift in Sources */, 90B609F5283E16DC006F4309 /* URLQueryBoolEncodingDefaultStartegyTests.swift in Sources */, + 50C8EB322BBD932D00C5CB93 /* CombineStreamNodeTests.swift in Sources */, 90B609FE283E16DC006F4309 /* UrlWithOrderedQuery.swift in Sources */, + 50C8EB362BBD9CBF00C5CB93 /* NodeResultTests.swift in Sources */, 90B60A10283E16E4006F4309 /* DeferCallingTests.swift in Sources */, 90B609F9283E16DC006F4309 /* CacheReaderNodeTests.swift in Sources */, 90B60A05283E16DC006F4309 /* UserEntry.swift in Sources */, - 5005EB262BB8A78B00B670CD /* CombineCompatibleNodeTests.swift in Sources */, + 50C8EB342BBD951500C5CB93 /* AsyncStreamCombineNodeTests.swift in Sources */, 90B60A06283E16DC006F4309 /* AuthModel.swift in Sources */, - 5005EB2A2BB8A7A300B670CD /* AsyncStreamNodeAdapterTests.swift in Sources */, 90B60A04283E16DC006F4309 /* AuthModelEntry.swift in Sources */, 90B60A01283E16DC006F4309 /* LoggingTests.swift in Sources */, 50528E312BAE1F9800E86CB6 /* LoggingContextMock.swift in Sources */, 90B609FC283E16DC006F4309 /* UrlETagSaverNodeTests.swift in Sources */, + 50C8EB302BBD90DE00C5CB93 /* CombineNodeTests.swift in Sources */, 90B609FF283E16DC006F4309 /* UrlETagUrlCacheTriggerNodeTests.swift in Sources */, 5005EB332BB9935400B670CD /* AsyncStreamNodeMock.swift in Sources */, 90B60A02283E16DC006F4309 /* Infrastructure.swift in Sources */, + 50C8EB2C2BBD8EBE00C5CB93 /* CombineNodeMock.swift in Sources */, 50528E332BAE295D00E86CB6 /* TokenRefresherActorMock.swift in Sources */, - 5005EB282BB8A79800B670CD /* AsyncNodeAdapterTests.swift in Sources */, 90B609F3283E16DC006F4309 /* URLQueryDictionaryKeyEncodingDefaultStrategyTests.swift in Sources */, 90B609F8283E16DC006F4309 /* EncodingTests.swift in Sources */, + 50C8EB2E2BBD8FC000C5CB93 /* CombineStreamNodeMock.swift in Sources */, 5005EB3E2BB9B4A300B670CD /* AsyncStreamNodeTests.swift in Sources */, 5005EB442BB9BC5B00B670CD /* Result+Extension.swift in Sources */, 90B609F1283E16DC006F4309 /* ChainConfiguratorNodeTests.swift in Sources */, 5005EB422BB9BC2500B670CD /* MockError.swift in Sources */, 90B609F6283E16DC006F4309 /* URLQueryInjectorNodeTests.swift in Sources */, - 5005EB382BB99BE600B670CD /* NodeAdapterMock.swift in Sources */, 50528E2C2BAE18F400E86CB6 /* AsyncNodeMock.swift in Sources */, 502F9D9A2BAA389500151A8D /* LoggingContextTests.swift in Sources */, 90B609FD283E16DC006F4309 /* UrlETagReaderNodeTests.swift in Sources */, @@ -1359,7 +1364,6 @@ 50528E372BAE34A400E86CB6 /* TokenRefresherActorTests.swift in Sources */, 5005EB3C2BB9B1C800B670CD /* AsyncNodeTests.swift in Sources */, 90B60A03283E16DC006F4309 /* CredentialsEntry.swift in Sources */, - 5005EB312BB9918700B670CD /* NodeAdapterOutputMock.swift in Sources */, 90B609F2283E16DC006F4309 /* MockerProxyConfigNodeTests.swift in Sources */, 90B609FA283E16DC006F4309 /* FirstCachePolicyTests.swift in Sources */, 50528E392BAE39AE00E86CB6 /* AborterMock.swift in Sources */, diff --git a/NodeKit/CacheNode/ETag/UrlETagReaderNode.swift b/NodeKit/CacheNode/ETag/UrlETagReaderNode.swift index 1459ca36..339afda2 100644 --- a/NodeKit/CacheNode/ETag/UrlETagReaderNode.swift +++ b/NodeKit/CacheNode/ETag/UrlETagReaderNode.swift @@ -31,9 +31,9 @@ open class UrlETagReaderNode: AsyncNode { /// Пытается прочесть eTag-токен из хранилища и добавить его к запросу. /// В случае, если прочесть токен не удалось, то управление просто передается дальше. - open func process(_ data: TransportUrlRequest) -> Observer { + open func processLegacy(_ data: TransportUrlRequest) -> Observer { guard let tag = UserDefaults.etagStorage?.value(forKey: data.url.absoluteString) as? String else { - return next.process(data) + return next.processLegacy(data) } var headers = data.headers @@ -45,7 +45,7 @@ open class UrlETagReaderNode: AsyncNode { let newData = TransportUrlRequest(with: params, raw: data.raw) - return next.process(newData) + return next.processLegacy(newData) } /// Пытается прочесть eTag-токен из хранилища и добавить его к запросу. diff --git a/NodeKit/CacheNode/ETag/UrlETagSaverNode.swift b/NodeKit/CacheNode/ETag/UrlETagSaverNode.swift index 951b2db5..596038e5 100644 --- a/NodeKit/CacheNode/ETag/UrlETagSaverNode.swift +++ b/NodeKit/CacheNode/ETag/UrlETagSaverNode.swift @@ -41,7 +41,7 @@ open class UrlETagSaverNode: AsyncNode { /// Пытается получить eTag-токен по ключу `UrlETagSaverNode.eTagHeaderKey`. /// В любом случае передает управление дальше. - open func process(_ data: UrlProcessedResponse) -> Observer { + open func processLegacy(_ data: UrlProcessedResponse) -> Observer { guard let tag = data.response.allHeaderFields[self.eTagHeaderKey] as? String, let url = data.request.url, let urlAsKey = url.withOrderedQuery() @@ -51,7 +51,7 @@ open class UrlETagSaverNode: AsyncNode { UserDefaults.etagStorage?.set(tag, forKey: urlAsKey) - return next?.process(data) ?? .emit(data: ()) + return next?.processLegacy(data) ?? .emit(data: ()) } /// Пытается получить eTag-токен по ключу `UrlETagSaverNode.eTagHeaderKey`. diff --git a/NodeKit/CacheNode/FirstCachePolicyNode.swift b/NodeKit/CacheNode/FirstCachePolicyNode.swift index 7ca8acf4..e5697e80 100644 --- a/NodeKit/CacheNode/FirstCachePolicyNode.swift +++ b/NodeKit/CacheNode/FirstCachePolicyNode.swift @@ -55,16 +55,16 @@ open class FirstCachePolicyNode: AsyncStreamNode { /// а затем, передает управление следующему узлу. /// В случае, если получить `URLRequest` не удалось, /// то управление просто передается следующему узлу - open func process(_ data: RawUrlRequest) -> Observer { + open func processLegacy(_ data: RawUrlRequest) -> Observer { let result = Context() if let request = data.toUrlRequest() { - cacheReaderNode.process(request) + cacheReaderNode.processLegacy(request) .onCompleted { result.emit(data: $0) } .onError { result.emit(error: $0)} } - next.process(data) + next.processLegacy(data) .onCompleted { result.emit(data: $0)} .onError { result.emit(error: $0) } diff --git a/NodeKit/CacheNode/IfServerFailsFromCacheNode.swift b/NodeKit/CacheNode/IfServerFailsFromCacheNode.swift index c45b2878..4e50ac42 100644 --- a/NodeKit/CacheNode/IfServerFailsFromCacheNode.swift +++ b/NodeKit/CacheNode/IfServerFailsFromCacheNode.swift @@ -30,15 +30,15 @@ open class IfConnectionFailedFromCacheNode: AsyncNode { /// Проверяет, произошла ли ошибка связи в ответ на запрос. /// Если ошибка произошла, то возвращает успешный ответ из кэша. /// В противном случае передает управление следующему узлу. - open func process(_ data: URLRequest) -> Observer { + open func processLegacy(_ data: URLRequest) -> Observer { - return self.next.process(data).mapError { error -> Observer in + return self.next.processLegacy(data).mapError { error -> Observer in var logMessage = self.logViewObjectName logMessage += "Catching \(error)" + .lineTabDeilimeter let request = UrlNetworkRequest(urlRequest: data) if error is BaseTechnicalError { logMessage += "Start read cache" + .lineTabDeilimeter - return self.cacheReaderNode.process(request) + return self.cacheReaderNode.processLegacy(request) } logMessage += "Error is \(type(of: error))" logMessage += "and request = \(String(describing: request))" + .lineTabDeilimeter diff --git a/NodeKit/CacheNode/UrlCacheReaderNode.swift b/NodeKit/CacheNode/UrlCacheReaderNode.swift index 16be7aee..bd721ff2 100644 --- a/NodeKit/CacheNode/UrlCacheReaderNode.swift +++ b/NodeKit/CacheNode/UrlCacheReaderNode.swift @@ -30,7 +30,7 @@ open class UrlCacheReaderNode: AsyncNode { } /// Посылает запрос в кэш и пытается сериализовать данные в JSON. - open func process(_ data: UrlNetworkRequest) -> Observer { + open func processLegacy(_ data: UrlNetworkRequest) -> Observer { guard let cachedResponse = self.extractCachedUrlResponse(data.urlRequest) else { return self.needsToThrowError ? .emit(error: BaseUrlCacheReaderError.cantLoadDataFromCache) : Context() diff --git a/NodeKit/CacheNode/UrlCacheWriterNode.swift b/NodeKit/CacheNode/UrlCacheWriterNode.swift index efc4a42a..baadea02 100644 --- a/NodeKit/CacheNode/UrlCacheWriterNode.swift +++ b/NodeKit/CacheNode/UrlCacheWriterNode.swift @@ -16,7 +16,7 @@ open class UrlCacheWriterNode: AsyncNode { /// Формирует `CachedURLResponse` с политикой `.allowed`, сохраняет его в кэш, /// а затем возвращает сообщение об успешной операции. - open func process(_ data: UrlProcessedResponse) -> Observer { + open func processLegacy(_ data: UrlProcessedResponse) -> Observer { let cahced = CachedURLResponse(response: data.response, data: data.data, storagePolicy: .allowed) URLCache.shared.storeCachedResponse(cahced, for: data.request) return Context().emit(data: ()) diff --git a/NodeKit/CacheNode/UrlNotModifiedTriggerNode.swift b/NodeKit/CacheNode/UrlNotModifiedTriggerNode.swift index fc23cc33..61545897 100644 --- a/NodeKit/CacheNode/UrlNotModifiedTriggerNode.swift +++ b/NodeKit/CacheNode/UrlNotModifiedTriggerNode.swift @@ -37,12 +37,12 @@ open class UrlNotModifiedTriggerNode: AsyncNode { /// Проверяет http status-code. Если код соовуетствует NotModified, то возвращает запрос из кэша. /// В протвином случае передает управление дальше. - open func process(_ data: UrlDataResponse) -> Observer { + open func processLegacy(_ data: UrlDataResponse) -> Observer { guard data.response.statusCode == 304 else { let log = makeErrorLog(code: data.response.statusCode) - return next.process(data).log(log) + return next.processLegacy(data).log(log) } - return cacheReader.process(UrlNetworkRequest(urlRequest: data.request)) + return cacheReader.processLegacy(UrlNetworkRequest(urlRequest: data.request)) } /// Проверяет http status-code. Если код соовуетствует NotModified, то возвращает запрос из кэша. diff --git a/NodeKit/Core/Node/Async/AsyncNode.swift b/NodeKit/Core/Node/Async/AsyncNode.swift index 50c6469b..8942b09c 100644 --- a/NodeKit/Core/Node/Async/AsyncNode.swift +++ b/NodeKit/Core/Node/Async/AsyncNode.swift @@ -6,12 +6,13 @@ // Copyright © 2024 Surf. All rights reserved. // +import Combine import Foundation /// Протокол наследованный от Node, добавляющий подход преобразования входных данных в результат с помощью SwiftConcurrency /// Применим для узлов, которые возвращают один результат -public protocol AsyncNode: CombineConvertibleNode { - +public protocol AsyncNode: CombineNode { + /// Ассинхронный метод, который содержит логику для обработки данных /// /// - Parameter data: Входные данные @@ -20,23 +21,47 @@ public protocol AsyncNode: CombineConvertibleNode { func process(_ data: Input, logContext: LoggingContextProtocol) async -> NodeResult } +/// Стандартная реализация CombineCompatibleNode. +public extension AsyncNode { + + /// Метод запускающий процесс обработки данных. + /// + /// - Parameters: + /// - data: Входные данные ноды. + /// - queue: Очередь на которой будут выдаваться результаты. + /// - logContext: Контекст логов. + /// - Returns: Publisher для подписки на результат. + @discardableResult + func nodeResultPublisher( + for data: Input, + on scheduler: some Scheduler, + logContext: LoggingContextProtocol + ) -> AnyPublisher, Never> { + return Future, Never> { promise in + Task { + let result = await process(data, logContext: logContext) + promise(.success(result)) + } + } + .receive(on: scheduler) + .eraseToAnyPublisher() + } +} + public extension AsyncNode { /// Метод process с созданием нового лог контекста. + @discardableResult func process(_ data: Input) async -> NodeResult { return await process(data, logContext: LoggingContext()) } - - /// Базовая реализация конвертации узла в ``CombineNode``. - func combineNode() -> any CombineNode { - return CombineCompatibleNode(adapter: AsyncNodeAdapter(node: self)) - } } /// Содержит иснтаксический сахар для работы с узлами, у которых входящий тип = `Void` public extension AsyncNode where Input == Void { /// Вызывает `process(_:)` + @discardableResult func process() async -> NodeResult { return await process(Void()) } diff --git a/NodeKit/Core/Node/Async/AsyncStreamNode.swift b/NodeKit/Core/Node/Async/AsyncStreamNode.swift index b781d3f8..2c75a870 100644 --- a/NodeKit/Core/Node/Async/AsyncStreamNode.swift +++ b/NodeKit/Core/Node/Async/AsyncStreamNode.swift @@ -6,29 +6,38 @@ // Copyright © 2024 Surf. All rights reserved. // +import Combine import Foundation /// Протокол наследованный от Node, добавляющий подход преобразования входных данных в поток результатов с помощью SwiftConcurrency /// Применим для узлов, которые могут вернуть несколько результатов -public protocol AsyncStreamNode: CombineConvertibleNode { - +public protocol AsyncStreamNode: Node { + /// Ассинхронный метод, который содержит логику для обработки данных /// /// - Parameter data: Входные данные /// - Returns: Поток результатов обработки данных. + @discardableResult func process(_ data: Input, logContext: LoggingContextProtocol) -> AsyncStream> + + /// Метод возвращающий объект для обработки результатов с помощью Combine. + /// + /// - Returns: Узел, поддерживающий обработку результатов с помощью Combine. + func combineNode() -> any CombineStreamNode } public extension AsyncStreamNode { /// Метод process с созданием нового лог контекста. + @discardableResult func process(_ data: Input) -> AsyncStream> { return process(data, logContext: LoggingContext()) } - - /// Базовая реализация конвертации узла в ``CombineNode``. - func combineNode() -> any CombineNode { - return CombineCompatibleNode(adapter: AsyncStreamNodeAdapter(node: self)) + /// Стандартная реализация конвертации узла в ``CombineNode``. + /// + /// - Returns: Узел, поддерживающий обработку результатов с помощью Combine. + func combineNode() -> any CombineStreamNode { + return AsyncStreamCombineNode(node: self) } } @@ -36,6 +45,7 @@ public extension AsyncStreamNode { public extension AsyncStreamNode where Input == Void { /// Вызывает `process(_:)` + @discardableResult func process() -> AsyncStream> { return process(Void()) } diff --git a/NodeKit/Core/Node/Combine/AsyncStreamCombineNode.swift b/NodeKit/Core/Node/Combine/AsyncStreamCombineNode.swift new file mode 100644 index 00000000..04c4e4c0 --- /dev/null +++ b/NodeKit/Core/Node/Combine/AsyncStreamCombineNode.swift @@ -0,0 +1,53 @@ +// +// AsyncStreamCombineNode.swift +// NodeKit +// +// Created by Andrei Frolov on 03.04.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Foundation +import Combine + +/// Реализация ``PublisherContainerNode`` для ``AsyncStreamNode``. +public struct AsyncStreamCombineNode: CombineStreamNode { + + // MARK: - Private Properties + + private let subject = PassthroughSubject, Never>() + private let node: any AsyncStreamNode + + // MARK: - Initialization + + init(node: some AsyncStreamNode) { + self.node = node + } + + // MARK: - CombineNode + + /// Publisher результата обработки данных. + /// - Parameter queue: Очередь на которой будут выдаваться результаты. + public func nodeResultPublisher(on scheduler: some Scheduler) -> AnyPublisher, Never> { + return subject + .receive(on: scheduler) + .eraseToAnyPublisher() + } + + /// Метод обработки данных протокола ``Node``. Будет удален в ближайшее время. + public func processLegacy(_ data: Input) -> Observer { + return node.processLegacy(data) + } + + /// Метод запускающий процесс обработки данных. + /// + /// - Parameters: + /// - data: Входные данные ноды. + /// - logContext: Контекст логов. + public func process(_ data: Input, logContext: LoggingContextProtocol) { + Task { + for await result in node.process(data, logContext: logContext) { + subject.send(result) + } + } + } +} diff --git a/NodeKit/Core/Node/Combine/CombineConvertibleNode.swift b/NodeKit/Core/Node/Combine/CombineConvertibleNode.swift deleted file mode 100644 index f5353da7..00000000 --- a/NodeKit/Core/Node/Combine/CombineConvertibleNode.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// CombineConvertibleNode.swift -// NodeKit -// -// Created by Andrei Frolov on 29.03.24. -// Copyright © 2024 Surf. All rights reserved. -// - -import Foundation - -/// Протокол наследованный от Node, добавляющий возможность конвертации ноды в ``CombineNode``. -public protocol CombineConvertibleNode: Node { - - /// Преобразование ноды в ``CombineNode`` для поддержки работы с Combine. - /// - /// - Returns: Нода с поддержкой работы Combine. - func combineNode() -> any CombineNode -} diff --git a/NodeKit/Core/Node/Combine/CombineNode.swift b/NodeKit/Core/Node/Combine/CombineNode.swift index 556e5714..0059f559 100644 --- a/NodeKit/Core/Node/Combine/CombineNode.swift +++ b/NodeKit/Core/Node/Combine/CombineNode.swift @@ -6,110 +6,73 @@ // Copyright © 2024 Surf. All rights reserved. // -import Combine import Foundation +import Combine -/// Протокол ноды, поддерживающего обработку результата с помощью Combine. -public protocol CombineNode: AnyObject { - associatedtype Input - associatedtype Output - - /// Метод запускающий процесс обработки данных. +/// Протокол ноды, совместимой с обработкой результатов с помощью метода rnodeResultPublisher. +public protocol CombineNode: Node { + + /// Метод запускающий процесс обработки данных + /// и возвращающий publisher для подписки на результат. /// /// - Parameters: /// - data: Входные данные ноды. + /// - queue: Очередь на которой будут выдаваться результаты. /// - logContext: Контекст логов. - /// - Returns: Self ноды. + /// - Returns: Publisher для подписки на результат. @discardableResult - func process(_ data: Input, logContext: LoggingContextProtocol) -> Self - - /// Метод получения Publisher, для подписки на результат обработки данных в главном потоке. - /// - /// - Returns: Publisher результа обработки данных ноды. - func eraseToAnyPublisher() -> AnyPublisher, Never> - - /// Метод получения Publisher, для подписки на результат обработки данных. - /// - /// - Parameter queue: Очередь, на которой будут получены данные. - /// - Returns: Publisher результа обработки данных ноды. - func eraseToAnyPublisher(queue: DispatchQueue) -> AnyPublisher, Never> + func nodeResultPublisher( + for data: Input, + on scheduler: some Scheduler, + logContext: LoggingContextProtocol + ) -> AnyPublisher, Never> } public extension CombineNode { - /// Метод запускающий процесс обработки данных и создающий новый контекст логов. - /// - /// - Parameter data: Входные данные ноды. - /// - Returns: Self ноды. + /// Метод запускающий процесс обработки данных и возвращаюший результат на главной очереди. + /// + /// - Parameters: + /// - data: Входные данные ноды. + /// - logContext: Контекст логов. + /// - Returns: Publisher для подписки на результат. @discardableResult - func process(_ data: Input) -> Self { - return process(data, logContext: LoggingContext()) - } -} - -/// Содержит иснтаксический сахар для работы с узлами, у которых входящий тип = `Void` -public extension CombineNode where Input == Void { - - /// Вызывает `process(_:)` - func process() -> Self { - return process(Void()) + func nodeResultPublisher( + for data: Input, + logContext: LoggingContextProtocol + ) -> AnyPublisher, Never> { + return nodeResultPublisher(for: data, on: DispatchQueue.main, logContext: logContext) } -} - -/// Реализация ``CombineNode`` -public class CombineCompatibleNode: CombineNode, NodeAdapterOutput { - - // MARK: - Private Properties - - private let subject = CurrentValueSubject?, Never>(nil) - private let adapter: any NodeAdapter - // MARK: - Initialization - - public init(adapter: some NodeAdapter) { - self.adapter = adapter - } - - // MARK: - CombineNode - - /// Создает новую задачу, в которой вызывает метод process у адаптера. + /// Метод запускающий процесс обработки данных, создающий новый контекст логов + /// и возвращаюший результат на кастомной очереди. /// /// - Parameters: /// - data: Входные данные ноды. /// - logContext: Контекст логов. - /// - Returns: Self ноды. + /// - Returns: Publisher для подписки на результат. @discardableResult - public func process(_ data: Input, logContext: LoggingContextProtocol) -> Self { - Task { - await adapter.process(data: data, logContext: logContext, output: self) - } - return self - } - - /// Метод получения Publisher, для подписки на результат обработки данных в главном потоке. - /// - /// - Returns: Publisher результа обработки данных ноды. - public func eraseToAnyPublisher() -> AnyPublisher, Never> { - return subject - .compactMap { $0 } - .receive(on: DispatchQueue.main) - .eraseToAnyPublisher() + func nodeResultPublisher(for data: Input, on scheduler: some Scheduler) -> AnyPublisher, Never> { + return nodeResultPublisher(for: data, on: scheduler, logContext: LoggingContext()) } - /// Метод получения Publisher, для подписки на результат обработки данных. + /// Метод запускающий процесс обработки данных, создающий новый контекст логов + /// и возвращаюший результат на главной очереди. /// - /// - Parameter queue: Очередь, на которой будут получены данные. - /// - Returns: Publisher результа обработки данных ноды. - public func eraseToAnyPublisher(queue: DispatchQueue) -> AnyPublisher, Never> { - return subject - .compactMap { $0 } - .receive(on: queue) - .eraseToAnyPublisher() + /// - Parameter data: Входные данные ноды. + /// - Returns: Self ноды. + @discardableResult + func nodeResultPublisher(for data: Input) -> AnyPublisher, Never> { + return nodeResultPublisher(for: data, on: DispatchQueue.main) } +} + +/// Содержит иснтаксический сахар для работы с узлами, у которых входящий тип = `Void` +public extension CombineNode where Input == Void { - // MARK: - NodeAdapterOutput - - public func send(_ value: NodeResult) { - subject.send(value) + /// Вызывает `process(_:)` + @discardableResult + func nodeResultPublisher() -> AnyPublisher, Never> { + return nodeResultPublisher(for: Void()) } } diff --git a/NodeKit/Core/Node/Combine/CombineStreamNode.swift b/NodeKit/Core/Node/Combine/CombineStreamNode.swift new file mode 100644 index 00000000..ea99b3d2 --- /dev/null +++ b/NodeKit/Core/Node/Combine/CombineStreamNode.swift @@ -0,0 +1,52 @@ +// +// PublisherContainerNode.swift +// NodeKit +// +// Created by Andrei Frolov on 29.03.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Combine +import Foundation + +/// Протокол ноды, хранящее в себе publisher результатов обработки данных. +/// Используется для потока данных, когда необходимо выполнить подписку до начала обработки. +public protocol CombineStreamNode: Node { + + /// Publisher результата обработки данных. + /// - Parameter queue: Очередь на которой будут выдаваться результаты. + func nodeResultPublisher(on scheduler: some Scheduler) -> AnyPublisher, Never> + + /// Метод запускающий процесс обработки данных. + /// + /// - Parameters: + /// - data: Входные данные ноды. + /// - logContext: Контекст логов. + func process(_ data: Input, logContext: LoggingContextProtocol) +} + +public extension CombineStreamNode { + + /// Метод запускающий процесс обработки данных, создающий новый контекст логов + /// и возвращаюший результат на кастомной очереди. + /// + /// - Parameters: + /// - data: Входные данные ноды. + /// - logContext: Контекст логов. + func process(_ data: Input) { + process(data, logContext: LoggingContext()) + } + + var nodeResultPublisher: AnyPublisher, Never> { + return nodeResultPublisher(on: DispatchQueue.main) + } +} + +/// Содержит иснтаксический сахар для работы с узлами, у которых входящий тип = `Void` +public extension CombineStreamNode where Input == Void { + + /// Вызывает `process(_:)` + func process() { + return process(Void()) + } +} diff --git a/NodeKit/Core/Node/Combine/NodeAdapter.swift b/NodeKit/Core/Node/Combine/NodeAdapter.swift deleted file mode 100644 index 24a3e47c..00000000 --- a/NodeKit/Core/Node/Combine/NodeAdapter.swift +++ /dev/null @@ -1,100 +0,0 @@ -// -// NodeAdapter.swift -// NodeKit -// -// Created by Andrei Frolov on 29.03.24. -// Copyright © 2024 Surf. All rights reserved. -// - -import Combine - -/// Протокол для выходных данных адаптера. -public protocol NodeAdapterOutput { - associatedtype Output - - /// Метод отправки результата ноды. - /// - /// - Parameter value: результат ноды. - func send(_ value: NodeResult) -} - -/// Адаптер для мапинга интерфейса ноды на ``NodeAdapterOutput``. -public protocol NodeAdapter { - associatedtype Input - associatedtype Output - - /// Метод содержащий логику мапинга обработки данных ноды на ``NodeAdapterOutput``, - /// - /// - Parameters: - /// - data: Входные данные ноды. - /// - logContext: Контекст логов. - /// - output: Output, в который будут переданы данные, полученные с ноды. - func process( - data: Input, - logContext: LoggingContextProtocol, - output: some NodeAdapterOutput - ) async -} - -/// Адаптер для мапинга интерфейса ``AsyncNode`` на ``NodeAdapterOutput``. -public struct AsyncNodeAdapter: NodeAdapter { - - // MARK: - Private Properties - - private let node: any AsyncNode - - // MARK: - Initialization - - public init(node: some AsyncNode) { - self.node = node - } - - // MARK: - CombineAdapter - - /// Вызывает метод process у асинхронной ноды и передает результат в output. - /// - /// - Parameters: - /// - data: Входные данные ноды. - /// - logContext: Контекст логов. - /// - output: Output, в который будут переданы данные, полученные с ноды. - public func process( - data: Input, - logContext: LoggingContextProtocol, - output: some NodeAdapterOutput - ) async { - let result = await node.process(data, logContext: logContext) - output.send(result) - } -} - -/// Адаптер для мапинга интерфейса ``AsyncStreamNode`` на ``NodeAdapterOutput``. -public struct AsyncStreamNodeAdapter: NodeAdapter { - - // MARK: - Private Properties - - private let node: any AsyncStreamNode - - // MARK: - Initialization - - public init(node: some AsyncStreamNode) { - self.node = node - } - - // MARK: - CombineAdapter - - /// Вызывает метод process у асинхронной ноды и передает результаты в output. - /// - /// - Parameters: - /// - data: Входные данные ноды. - /// - logContext: Контекст логов. - /// - output: Output, в который будут переданы данные, полученные с ноды. - public func process( - data: Input, - logContext: LoggingContextProtocol, - output: some NodeAdapterOutput - ) async { - for await result in node.process(data, logContext: logContext) { - output.send(result) - } - } -} diff --git a/NodeKit/Core/Node/Node.swift b/NodeKit/Core/Node/Node.swift index 3e92cc52..cb27b878 100644 --- a/NodeKit/Core/Node/Node.swift +++ b/NodeKit/Core/Node/Node.swift @@ -33,5 +33,6 @@ public protocol Node { /// /// - Parameter data: Входные данные /// - Returns: Подписка на процесс обработки данных. - func process(_ data: Input) -> Observer + @available(*, deprecated, message: "Будет удалено в ближайшее время") + func processLegacy(_ data: Input) -> Observer } diff --git a/NodeKit/Core/Node/NodeResult.swift b/NodeKit/Core/Node/NodeResult.swift index 52d95f41..ea09db52 100644 --- a/NodeKit/Core/Node/NodeResult.swift +++ b/NodeKit/Core/Node/NodeResult.swift @@ -72,4 +72,24 @@ public extension NodeResult { return .failure(customError ?? error) } } + + /// Возвращает занчение успещного результата или nil если Failure. + var value: Success? { + switch self { + case .success(let value): + return value + case .failure: + return nil + } + } + + /// Возвращает Error, если Failure или nil если Success. + var error: Error? { + switch self { + case .success: + return nil + case .failure(let error): + return error + } + } } diff --git a/NodeKit/Encodings/UrlJsonRequestEncodingNode.swift b/NodeKit/Encodings/UrlJsonRequestEncodingNode.swift index bfa78413..59085694 100644 --- a/NodeKit/Encodings/UrlJsonRequestEncodingNode.swift +++ b/NodeKit/Encodings/UrlJsonRequestEncodingNode.swift @@ -21,7 +21,7 @@ open class UrlJsonRequestEncodingNode: AsyncNode { self.next = next } - open func process(_ data: RequestEncodingModel) -> Observer { + open func processLegacy(_ data: RequestEncodingModel) -> Observer { var log = getLogMessage(data) let request: TransportUrlRequest? let paramEncoding = { () -> ParameterEncoding? in @@ -47,7 +47,7 @@ open class UrlJsonRequestEncodingNode: AsyncNode { return Context().log(log).emit(error: RequestEncodingError.unsupportedDataType) } - return next.process(unwrappedRequest).log(log) + return next.processLegacy(unwrappedRequest).log(log) } open func process( diff --git a/NodeKit/Layers/ConfigurationLayer/ChainConfiguratorNode.swift b/NodeKit/Layers/ConfigurationLayer/ChainConfiguratorNode.swift index e71b468c..73e27e85 100644 --- a/NodeKit/Layers/ConfigurationLayer/ChainConfiguratorNode.swift +++ b/NodeKit/Layers/ConfigurationLayer/ChainConfiguratorNode.swift @@ -40,10 +40,10 @@ open class ChainConfiguratorNode: AsyncNode { /// затем выполняет всю цепочку операций и диспатчит ответ на `endQueue` /// /// - Parameter data: Данные для обработки - open func process(_ data: I) -> Observer { + open func processLegacy(_ data: I) -> Observer { return Context.emit(data: ()) .dispatchOn(self.beginQueue) - .map { return self.next.process(data) } + .map { return self.next.processLegacy(data) } .dispatchOn(self.endQueue) } diff --git a/NodeKit/Layers/DTOProcessingLayer/DTOMapperNode.swift b/NodeKit/Layers/DTOProcessingLayer/DTOMapperNode.swift index 4cba7cea..d6780d24 100644 --- a/NodeKit/Layers/DTOProcessingLayer/DTOMapperNode.swift +++ b/NodeKit/Layers/DTOProcessingLayer/DTOMapperNode.swift @@ -24,7 +24,7 @@ open class DTOMapperNode: AsyncNode where Input: RawEncodable, Ou /// Маппит данные в RawMappable, передает управление следующей цепочке, а затем маппит ответ в DTOConvertible /// /// - Parameter data: Данные для обработки. - open func process(_ data: Input) -> Observer { + open func processLegacy(_ data: Input) -> Observer { let context = Context() var log = Log(self.logViewObjectName, id: self.objectName, order: LogOrder.dtoMapperNode) @@ -32,7 +32,7 @@ open class DTOMapperNode: AsyncNode where Input: RawEncodable, Ou do { let data = try data.toRaw() - let nextProcessResult = next.process(data) + let nextProcessResult = next.processLegacy(data) return nextProcessResult.map { [weak nextProcessResult] result in do { diff --git a/NodeKit/Layers/DTOProcessingLayer/RawEncoderNode.swift b/NodeKit/Layers/DTOProcessingLayer/RawEncoderNode.swift index b9a3b06a..0cf1d596 100644 --- a/NodeKit/Layers/DTOProcessingLayer/RawEncoderNode.swift +++ b/NodeKit/Layers/DTOProcessingLayer/RawEncoderNode.swift @@ -25,9 +25,9 @@ open class RawEncoderNode: AsyncNode where Input: RawEncodable { /// Если при конвертировании произошла ошибка - прерывает выполнение цепочки. /// /// - Parameter data: Входящая модель. - open func process(_ data: Input) -> Observer { + open func processLegacy(_ data: Input) -> Observer { do { - return next.process(try data.toRaw()) + return next.processLegacy(try data.toRaw()) } catch { return .emit(error: error) } diff --git a/NodeKit/Layers/InputProcessingLayer/DTOEncoderNode.swift b/NodeKit/Layers/InputProcessingLayer/DTOEncoderNode.swift index 8f6e1cc4..8c0943c1 100644 --- a/NodeKit/Layers/InputProcessingLayer/DTOEncoderNode.swift +++ b/NodeKit/Layers/InputProcessingLayer/DTOEncoderNode.swift @@ -25,9 +25,9 @@ open class DTOEncoderNode: AsyncNode where Input: DTOEncodable { /// Если при конвертировании произошла ошибка - прерывает выполнение цепочки. /// /// - Parameter data: Входящая модель. - open func process(_ data: Input) -> Observer { + open func processLegacy(_ data: Input) -> Observer { do { - return rawEncodable.process(try data.toDTO()) + return rawEncodable.processLegacy(try data.toDTO()) } catch { return .emit(error: error) } diff --git a/NodeKit/Layers/InputProcessingLayer/EntryinputDtoOutputNode.swift b/NodeKit/Layers/InputProcessingLayer/EntryinputDtoOutputNode.swift index c3817c01..281850b9 100644 --- a/NodeKit/Layers/InputProcessingLayer/EntryinputDtoOutputNode.swift +++ b/NodeKit/Layers/InputProcessingLayer/EntryinputDtoOutputNode.swift @@ -17,10 +17,10 @@ open class EntryinputDtoOutputNode: AsyncNode self.next = next } - open func process(_ data: Input) -> Observer { + open func processLegacy(_ data: Input) -> Observer { do { let raw = try data.toRaw() - return self.next.process(raw).map { try Output.from(dto: Output.DTO.from(raw: $0) ) } + return self.next.processLegacy(raw).map { try Output.from(dto: Output.DTO.from(raw: $0) ) } } catch { return .emit(error: error) } diff --git a/NodeKit/Layers/InputProcessingLayer/ModelInputNode.swift b/NodeKit/Layers/InputProcessingLayer/ModelInputNode.swift index 5640e2b1..3b865b59 100644 --- a/NodeKit/Layers/InputProcessingLayer/ModelInputNode.swift +++ b/NodeKit/Layers/InputProcessingLayer/ModelInputNode.swift @@ -27,13 +27,13 @@ public class ModelInputNode: AsyncNode where Input: DTOEncodable, /// Если при маппинге произошла ошибка, то она будет проброшена выше. /// /// - Parameter data: Данные для запроса. - open func process(_ data: Input) -> Observer { + open func processLegacy(_ data: Input) -> Observer { let context = Context() do { let data = try data.toDTO() - return next.process(data) + return next.processLegacy(data) .map { try Output.from(dto: $0) } } catch { return context.emit(error: error) diff --git a/NodeKit/Layers/InputProcessingLayer/VoidIONode.swift b/NodeKit/Layers/InputProcessingLayer/VoidIONode.swift index 6b939058..7e982860 100644 --- a/NodeKit/Layers/InputProcessingLayer/VoidIONode.swift +++ b/NodeKit/Layers/InputProcessingLayer/VoidIONode.swift @@ -16,8 +16,8 @@ open class VoidIONode: AsyncNode { self.next = next } - open func process(_ data: Void) -> Observer { - return self.next.process(Json()).map { json in + open func processLegacy(_ data: Void) -> Observer { + return self.next.processLegacy(Json()).map { json in let result = Context() var log = Log(self.logViewObjectName, id: self.objectName, order: LogOrder.voidIONode) if !json.isEmpty { @@ -34,7 +34,6 @@ open class VoidIONode: AsyncNode { logContext: LoggingContextProtocol ) async -> NodeResult { return await next.process(Json(), logContext: logContext).asyncFlatMap { json in - let result = Context() if !json.isEmpty { var log = Log(logViewObjectName, id: objectName, order: LogOrder.voidIONode) log += "VoidIOtNode used but request have not empty response" diff --git a/NodeKit/Layers/InputProcessingLayer/VoidInputNode.swift b/NodeKit/Layers/InputProcessingLayer/VoidInputNode.swift index 748e557d..dd6d1e29 100644 --- a/NodeKit/Layers/InputProcessingLayer/VoidInputNode.swift +++ b/NodeKit/Layers/InputProcessingLayer/VoidInputNode.swift @@ -22,8 +22,8 @@ open class VoidInputNode: AsyncNode { } /// Передает управление следующему узлу,в качестве параметра передает пустой `Json` - open func process(_ data: Void) -> Observer { - return next.process(Json()) + open func processLegacy(_ data: Void) -> Observer { + return next.processLegacy(Json()) } /// Передает управление следующему узлу,в качестве параметра передает пустой `Json` @@ -40,7 +40,7 @@ open class VoidInputNode: AsyncNode { /// Содержит иснтаксический сахар для работы с узлами, у которых входящий тип = `Void` extension Node where Input == Void { /// Вызывает `process(_:)` - func process() -> Observer { - return self.process(Void()) + func processLegacy() -> Observer { + return self.processLegacy(Void()) } } diff --git a/NodeKit/Layers/InputProcessingLayer/VoidOutputNode.swift b/NodeKit/Layers/InputProcessingLayer/VoidOutputNode.swift index 9cc8e655..2441d873 100644 --- a/NodeKit/Layers/InputProcessingLayer/VoidOutputNode.swift +++ b/NodeKit/Layers/InputProcessingLayer/VoidOutputNode.swift @@ -16,7 +16,7 @@ open class VoidOutputNode: AsyncNode where Input: DTOEncodable, Input.DTO self.next = next } - open func process(_ data: Input) -> Observer { + open func processLegacy(_ data: Input) -> Observer { var newData: Json @@ -26,7 +26,7 @@ open class VoidOutputNode: AsyncNode where Input: DTOEncodable, Input.DTO return .emit(error: error) } - return self.next.process(newData).map { json in + return self.next.processLegacy(newData).map { json in let result = Context() var log = Log(self.logViewObjectName, id: self.objectName, order: LogOrder.voidOutputNode) if !json.isEmpty { diff --git a/NodeKit/Layers/RequestBuildingLayer/MetadataConnectorNode.swift b/NodeKit/Layers/RequestBuildingLayer/MetadataConnectorNode.swift index d8823ba3..367b8fc0 100644 --- a/NodeKit/Layers/RequestBuildingLayer/MetadataConnectorNode.swift +++ b/NodeKit/Layers/RequestBuildingLayer/MetadataConnectorNode.swift @@ -27,8 +27,8 @@ open class MetadataConnectorNode: AsyncNode { /// формирует модель `RequestModel` и передает ее на дальнейшую обработку. /// /// - Parameter data: данные в Raw формате. (после маппинга из Entry) - open func process(_ data: Raw) -> Observer { - return next.process(RequestModel(metadata: self.metadata, raw: data)) + open func processLegacy(_ data: Raw) -> Observer { + return next.processLegacy(RequestModel(metadata: self.metadata, raw: data)) } /// формирует модель `RequestModel` и передает ее на дальнейшую обработку. diff --git a/NodeKit/Layers/RequestBuildingLayer/MultipartUrlRequestTrasformatorNode.swift b/NodeKit/Layers/RequestBuildingLayer/MultipartUrlRequestTrasformatorNode.swift index afc0da9a..58214e4f 100644 --- a/NodeKit/Layers/RequestBuildingLayer/MultipartUrlRequestTrasformatorNode.swift +++ b/NodeKit/Layers/RequestBuildingLayer/MultipartUrlRequestTrasformatorNode.swift @@ -23,7 +23,7 @@ open class MultipartUrlRequestTrasformatorNode: AsyncNode { /// Конструирует модель для для работы на транспортном уровне цепочки. /// /// - Parameter data: Данные для дальнейшей обработки. - open func process( + open func processLegacy( _ data: RoutableRequestModel> ) -> Observer { @@ -41,7 +41,7 @@ open class MultipartUrlRequestTrasformatorNode: AsyncNode { headers: data.metadata, data: data.raw) - return next.process(request) + return next.processLegacy(request) } /// Конструирует модель для для работы на транспортном уровне цепочки. diff --git a/NodeKit/Layers/RequestBuildingLayer/RequestRouterNode.swift b/NodeKit/Layers/RequestBuildingLayer/RequestRouterNode.swift index e6fc2fc2..7642df42 100644 --- a/NodeKit/Layers/RequestBuildingLayer/RequestRouterNode.swift +++ b/NodeKit/Layers/RequestBuildingLayer/RequestRouterNode.swift @@ -37,8 +37,8 @@ open class RequestRouterNode: AsyncNode { } /// Преобразует `RequestModel` в `RoutableRequestModel` и передает управление следующему узлу - open func process(_ data: RequestModel) -> Observer { - return self.next.process(RoutableRequestModel(metadata: data.metadata, raw: data.raw, route: self.route)) + open func processLegacy(_ data: RequestModel) -> Observer { + return self.next.processLegacy(RoutableRequestModel(metadata: data.metadata, raw: data.raw, route: self.route)) } /// Преобразует `RequestModel` в `RoutableRequestModel` и передает управление следующему узлу diff --git a/NodeKit/Layers/RequestBuildingLayer/RequstEncoderNode.swift b/NodeKit/Layers/RequestBuildingLayer/RequstEncoderNode.swift index bf633b06..b6d3e4ff 100644 --- a/NodeKit/Layers/RequestBuildingLayer/RequstEncoderNode.swift +++ b/NodeKit/Layers/RequestBuildingLayer/RequstEncoderNode.swift @@ -40,9 +40,9 @@ open class RequstEncoderNode: AsyncNode { /// Преобразует `RoutableRequestModel` в `EncodableRequestModel` /// и передает управление следующему узлу. - open func process(_ data: RoutableRequestModel) -> Observer { + open func processLegacy(_ data: RoutableRequestModel) -> Observer { let model = EncodableRequestModel(metadata: data.metadata, raw: data.raw, route: data.route, encoding: self.encoding) - return self.next.process(model) + return self.next.processLegacy(model) } /// Преобразует `RoutableRequestModel` в `EncodableRequestModel` diff --git a/NodeKit/Layers/RequestBuildingLayer/URLQueryInjectorNode.swift b/NodeKit/Layers/RequestBuildingLayer/URLQueryInjectorNode.swift index d3ebd762..fd8760a7 100644 --- a/NodeKit/Layers/RequestBuildingLayer/URLQueryInjectorNode.swift +++ b/NodeKit/Layers/RequestBuildingLayer/URLQueryInjectorNode.swift @@ -47,10 +47,10 @@ open class URLQueryInjectorNode: AsyncNode { /// Добавляет URL-query если может и передает управление следующему узлу. /// В случае, если не удалось обработать URL, то возвращает ошибку `cantCreateUrlComponentsFromUrlString` /// - SeeAlso: ``URLQueryInjectorNodeError`` - open func process(_ data: RoutableRequestModel) -> Observer { + open func processLegacy(_ data: RoutableRequestModel) -> Observer { guard !self.config.query.isEmpty else { - return self.next.process(data) + return self.next.processLegacy(data) } var url: URL @@ -78,7 +78,7 @@ open class URLQueryInjectorNode: AsyncNode { raw: data.raw, route: newUrl) - return self.next.process(newModel) + return self.next.processLegacy(newModel) } /// Добавляет URL-query если может и передает управление следующему узлу. diff --git a/NodeKit/Layers/RequestBuildingLayer/UrlRequestTrasformatorNode.swift b/NodeKit/Layers/RequestBuildingLayer/UrlRequestTrasformatorNode.swift index 79972954..724f305c 100644 --- a/NodeKit/Layers/RequestBuildingLayer/UrlRequestTrasformatorNode.swift +++ b/NodeKit/Layers/RequestBuildingLayer/UrlRequestTrasformatorNode.swift @@ -27,7 +27,7 @@ open class UrlRequestTrasformatorNode: AsyncNode { /// Конструирует модель для для работы на транспортном уровне цепочки. /// /// - Parameter data: Данные для дальнейшей обработки. - open func process( + open func processLegacy( _ data: EncodableRequestModel ) -> Observer { @@ -46,7 +46,7 @@ open class UrlRequestTrasformatorNode: AsyncNode { let encodingModel = RequestEncodingModel(urlParameters: params, raw: data.raw, encoding: data.encoding ?? nil) - return next.process(encodingModel) + return next.processLegacy(encodingModel) } /// Конструирует модель для для работы на транспортном уровне цепочки. diff --git a/NodeKit/Layers/RequestProcessingLayer/MultipartRequestCreatorNode.swift b/NodeKit/Layers/RequestProcessingLayer/MultipartRequestCreatorNode.swift index 0e83f85f..f4903643 100644 --- a/NodeKit/Layers/RequestProcessingLayer/MultipartRequestCreatorNode.swift +++ b/NodeKit/Layers/RequestProcessingLayer/MultipartRequestCreatorNode.swift @@ -38,7 +38,7 @@ open class MultipartRequestCreatorNode: AsyncNode { /// Конфигурирует низкоуровневый запрос. /// /// - Parameter data: Данные для конфигурирования и последующей отправки запроса. - open func process(_ data: MultipartUrlRequest) -> Observer { + open func processLegacy(_ data: MultipartUrlRequest) -> Observer { do { var request = URLRequest(url: data.url) request.httpMethod = data.method.rawValue @@ -53,7 +53,7 @@ open class MultipartRequestCreatorNode: AsyncNode { let encodedFormData = try formData.encode() request.httpBody = encodedFormData - return self.next.process(request).log(self.getLogMessage(data)) + return self.next.processLegacy(request).log(self.getLogMessage(data)) } catch { return .emit(error: error) } diff --git a/NodeKit/Layers/RequestProcessingLayer/RequestCreatorNode.swift b/NodeKit/Layers/RequestProcessingLayer/RequestCreatorNode.swift index 5d13915b..a1e1c309 100644 --- a/NodeKit/Layers/RequestProcessingLayer/RequestCreatorNode.swift +++ b/NodeKit/Layers/RequestProcessingLayer/RequestCreatorNode.swift @@ -20,7 +20,7 @@ open class RequestCreatorNode: AsyncNode { /// Конфигурирует низкоуровненвый запрос. /// /// - Parameter data: Данные для конфигурирования и последующей отправки запроса. - open func process(_ data: TransportUrlRequest) -> Observer { + open func processLegacy(_ data: TransportUrlRequest) -> Observer { var mergedHeaders = data.headers self.providers.map { $0.metadata() }.forEach { dict in @@ -32,7 +32,7 @@ open class RequestCreatorNode: AsyncNode { request.httpBody = data.raw mergedHeaders.forEach { request.addValue($0.value, forHTTPHeaderField: $0.key) } - return self.next.process(request).log(self.getLogMessage(data)) + return self.next.processLegacy(request).log(self.getLogMessage(data)) } /// Конфигурирует низкоуровненвый запрос. diff --git a/NodeKit/Layers/RequestProcessingLayer/RequestSenderNode.swift b/NodeKit/Layers/RequestProcessingLayer/RequestSenderNode.swift index 50380d07..72af2655 100644 --- a/NodeKit/Layers/RequestProcessingLayer/RequestSenderNode.swift +++ b/NodeKit/Layers/RequestProcessingLayer/RequestSenderNode.swift @@ -50,7 +50,7 @@ open class RequestSenderNode: AsyncNode, Aborter { /// Выполняет запрос,ожидает ответ и передает его следующему узлу. /// /// - Parameter request: Данные для исполнения запроса. - open func process(_ request: URLRequest) -> Observer { + open func processLegacy(_ request: URLRequest) -> Observer { let context = Context() self.context = context @@ -75,7 +75,7 @@ open class RequestSenderNode: AsyncNode, Aborter { } log += "Request sended!" task?.resume() - return context.map { self.rawResponseProcessor.process($0) } + return context.map { self.rawResponseProcessor.processLegacy($0) } } /// Выполняет запрос,ожидает ответ и передает его следующему узлу. diff --git a/NodeKit/Layers/ResponseProcessingLayer/DataLoading/DataLoadingResponseProcessor.swift b/NodeKit/Layers/ResponseProcessingLayer/DataLoading/DataLoadingResponseProcessor.swift index 78c2e00b..c7d33fd0 100644 --- a/NodeKit/Layers/ResponseProcessingLayer/DataLoading/DataLoadingResponseProcessor.swift +++ b/NodeKit/Layers/ResponseProcessingLayer/DataLoading/DataLoadingResponseProcessor.swift @@ -25,12 +25,12 @@ open class DataLoadingResponseProcessor: AsyncNode { } /// В случае, если узел для постобработки существует, то вызывает его, если нет - возвращает данные. - open func process(_ data: UrlDataResponse) -> Observer { + open func processLegacy(_ data: UrlDataResponse) -> Observer { guard let next = self.next else { return .emit(data: data.data) } - return next.process(data).map { data.data } + return next.processLegacy(data).map { data.data } } /// В случае, если узел для постобработки существует, то вызывает его, если нет - возвращает данные. diff --git a/NodeKit/Layers/ResponseProcessingLayer/ResponseDataParserNode.swift b/NodeKit/Layers/ResponseProcessingLayer/ResponseDataParserNode.swift index 630e0051..7c89fe2a 100644 --- a/NodeKit/Layers/ResponseProcessingLayer/ResponseDataParserNode.swift +++ b/NodeKit/Layers/ResponseProcessingLayer/ResponseDataParserNode.swift @@ -34,7 +34,7 @@ open class ResponseDataParserNode: AsyncNode { /// Парсит ответ и в случае успеха передает управление следующему узлу. /// /// - Parameter data: Модель ответа сервера. - open func process(_ data: UrlDataResponse) -> Observer { + open func processLegacy(_ data: UrlDataResponse) -> Observer { let context = Context() var json = Json() @@ -66,7 +66,7 @@ open class ResponseDataParserNode: AsyncNode { let networkResponse = UrlProcessedResponse(dataResponse: data, json: json) - return nextNode.process(networkResponse).log(Log(log, id: self.objectName, order: LogOrder.responseDataParserNode)).map { json } + return nextNode.processLegacy(networkResponse).log(Log(log, id: self.objectName, order: LogOrder.responseDataParserNode)).map { json } } /// Парсит ответ и в случае успеха передает управление следующему узлу. diff --git a/NodeKit/Layers/ResponseProcessingLayer/ResponseDataPreprocessorNode.swift b/NodeKit/Layers/ResponseProcessingLayer/ResponseDataPreprocessorNode.swift index ac534f01..7fa1f8fa 100644 --- a/NodeKit/Layers/ResponseProcessingLayer/ResponseDataPreprocessorNode.swift +++ b/NodeKit/Layers/ResponseProcessingLayer/ResponseDataPreprocessorNode.swift @@ -25,7 +25,7 @@ open class ResponseDataPreprocessorNode: AsyncNode { /// Сериализует "сырые" данные в `Json` /// /// - Parameter data: Представление ответа. - open func process(_ data: UrlDataResponse) -> Observer { + open func processLegacy(_ data: UrlDataResponse) -> Observer { var log = Log(self.logViewObjectName, id: self.objectName, order: LogOrder.responseDataPreprocessorNode) guard data.response.statusCode != 204 else { @@ -38,7 +38,7 @@ open class ResponseDataPreprocessorNode: AsyncNode { return Context().emit(data: Json()).log(log) } - return self.next.process(data) + return self.next.processLegacy(data) } /// Сериализует "сырые" данные в `Json` diff --git a/NodeKit/Layers/ResponseProcessingLayer/ResponseHttpErrorProcessorNode.swift b/NodeKit/Layers/ResponseProcessingLayer/ResponseHttpErrorProcessorNode.swift index 50e1be15..0331492b 100644 --- a/NodeKit/Layers/ResponseProcessingLayer/ResponseHttpErrorProcessorNode.swift +++ b/NodeKit/Layers/ResponseProcessingLayer/ResponseHttpErrorProcessorNode.swift @@ -44,7 +44,7 @@ open class ResponseHttpErrorProcessorNode: AsyncNode { /// В противном случае возвращает `HttpError` /// /// - Parameter data: Модель ответа сервера. - open func process(_ data: UrlDataResponse) -> Observer { + open func processLegacy(_ data: UrlDataResponse) -> Observer { let context = Context() @@ -63,7 +63,7 @@ open class ResponseHttpErrorProcessorNode: AsyncNode { break } let log = self.logViewObjectName + "Cant match status code -> call next" - return self.next.process(data).log(Log(log, id: self.objectName, order: LogOrder.responseHttpErrorProcessorNode)) + return self.next.processLegacy(data).log(Log(log, id: self.objectName, order: LogOrder.responseHttpErrorProcessorNode)) } /// Сопоставляет HTTP-коды с заданными и в случае их несовпадения передает управление дальше. diff --git a/NodeKit/Layers/ResponseProcessingLayer/ResponseProcessorNode.swift b/NodeKit/Layers/ResponseProcessingLayer/ResponseProcessorNode.swift index d5a57d55..0f9a9e37 100644 --- a/NodeKit/Layers/ResponseProcessingLayer/ResponseProcessorNode.swift +++ b/NodeKit/Layers/ResponseProcessingLayer/ResponseProcessorNode.swift @@ -31,7 +31,7 @@ open class ResponseProcessorNode: AsyncNode { /// Проверяет, возникла-ли какая-то ошибка во время работы. /// /// - Parameter data: Низкоуровневый ответ сервера. - open func process(_ data: NodeDataResponse) -> Observer { + open func processLegacy(_ data: NodeDataResponse) -> Observer { var log = Log(self.logViewObjectName, id: self.objectName, order: LogOrder.responseProcessorNode) switch data.result { @@ -53,7 +53,7 @@ open class ResponseProcessorNode: AsyncNode { log += " ~~> \(urlResponse.statusCode)" + .lineTabDeilimeter log += "EMPTY" - return next.process(response).log(log) + return next.processLegacy(response).log(log) case .success(let value): log += "Request success!" + .lineTabDeilimeter guard @@ -75,7 +75,7 @@ open class ResponseProcessorNode: AsyncNode { log += " --> \(urlResponse.statusCode)" + .lineTabDeilimeter log += String(data: value, encoding: .utf8) ?? "CURRUPTED" - return self.next.process(dataResponse).log(log) + return self.next.processLegacy(dataResponse).log(log) } } diff --git a/NodeKit/Layers/TrasportLayer/TechnicaErrorMapperNode.swift b/NodeKit/Layers/TrasportLayer/TechnicaErrorMapperNode.swift index 6e40adae..56454312 100644 --- a/NodeKit/Layers/TrasportLayer/TechnicaErrorMapperNode.swift +++ b/NodeKit/Layers/TrasportLayer/TechnicaErrorMapperNode.swift @@ -39,8 +39,8 @@ open class TechnicaErrorMapperNode: AsyncNode { /// Передает управление следующему узлу, и в случае ошибки маппит ее. /// /// - Parameter data: Данные для обработки. - open func process(_ data: URLRequest) -> Observer { - return self.next.process(data) + open func processLegacy(_ data: URLRequest) -> Observer { + return self.next.processLegacy(data) .mapError { error -> Error in switch (error as NSError).code { case -1020: diff --git a/NodeKit/Layers/Utils/AccessSafe/AccessSafeNode.swift b/NodeKit/Layers/Utils/AccessSafe/AccessSafeNode.swift index f6f3a968..c7a87a1b 100644 --- a/NodeKit/Layers/Utils/AccessSafe/AccessSafeNode.swift +++ b/NodeKit/Layers/Utils/AccessSafe/AccessSafeNode.swift @@ -69,12 +69,12 @@ open class AccessSafeNode: AsyncNode { /// Просто передает управление следующему узлу. /// В случае если вернулась доступа, то обноляет токен и повторяет запрос. - open func process(_ data: TransportUrlRequest) -> Observer { - return self.next.process(data).mapError { error -> Observer in + open func processLegacy(_ data: TransportUrlRequest) -> Observer { + return self.next.processLegacy(data).mapError { error -> Observer in switch error { case ResponseHttpErrorProcessorNodeError.forbidden, ResponseHttpErrorProcessorNodeError.unauthorized: - return self.updateTokenChain.process(()).map { _ in - return self.next.process(data) + return self.updateTokenChain.processLegacy(()).map { _ in + return self.next.processLegacy(data) } default: return .emit(error: error) diff --git a/NodeKit/Layers/Utils/AccessSafe/TokenRefresherNode.swift b/NodeKit/Layers/Utils/AccessSafe/TokenRefresherNode.swift index 6d365592..06e82a62 100644 --- a/NodeKit/Layers/Utils/AccessSafe/TokenRefresherNode.swift +++ b/NodeKit/Layers/Utils/AccessSafe/TokenRefresherNode.swift @@ -50,7 +50,7 @@ open class TokenRefresherNode: AsyncNode { /// Если запрос был отправлен, то создает `Observer`, сохраняет его у себя и возвращает предыдущему узлу. /// Если нет - отправляет запрос и сохраняет `Observer` /// После того как запрос на обновление токена был выполнен успешно - эмитит данные во все сохраненные Observer'ы и удаляет их из памяти - open func process(_ data: Void) -> Observer { + open func processLegacy(_ data: Void) -> Observer { let shouldSaveContext: Bool = self.flagQueue.sync { if self.isRequestSended { @@ -71,7 +71,7 @@ open class TokenRefresherNode: AsyncNode { } } - return self.tokenRefreshChain.process(()).map { [weak self] model -> Void in + return self.tokenRefreshChain.processLegacy(()).map { [weak self] model -> Void in guard let `self` = self else { return () } diff --git a/NodeKit/Layers/Utils/HeaderInjectorNode.swift b/NodeKit/Layers/Utils/HeaderInjectorNode.swift index 582792cf..338c157f 100644 --- a/NodeKit/Layers/Utils/HeaderInjectorNode.swift +++ b/NodeKit/Layers/Utils/HeaderInjectorNode.swift @@ -30,7 +30,7 @@ open class HeaderInjectorNode: AsyncNode { } /// Добавляет хедеры к запросу и отправляет его слудующему в цепочке узлу. - open func process(_ data: TransportUrlRequest) -> Observer { + open func processLegacy(_ data: TransportUrlRequest) -> Observer { var resultHeaders = self.headers var log = self.logViewObjectName log += "Add headers \(self.headers)" + .lineTabDeilimeter @@ -41,7 +41,7 @@ open class HeaderInjectorNode: AsyncNode { headers: resultHeaders, raw: data.raw) log += "Result headers: \(resultHeaders)" - return next.process(newData) + return next.processLegacy(newData) } /// Добавляет хедеры к запросу и отправляет его слудующему в цепочке узлу. diff --git a/NodeKit/Layers/Utils/LoadIndicatorNode.swift b/NodeKit/Layers/Utils/LoadIndicatorNode.swift index 8aaa97e6..e11866a6 100644 --- a/NodeKit/Layers/Utils/LoadIndicatorNode.swift +++ b/NodeKit/Layers/Utils/LoadIndicatorNode.swift @@ -38,7 +38,7 @@ open class LoadIndicatableNode: AsyncNode { /// Показывает индикатор и передает управление дальше. /// По окнчании работы цепочки скрывает индикатор. - open func process(_ data: Input) -> Observer { + open func processLegacy(_ data: Input) -> Observer { DispatchQueue.global().async(flags: .barrier) { LoadIndicatableNodeStatic.requestConter += 1 } @@ -49,7 +49,7 @@ open class LoadIndicatableNode: AsyncNode { } } - return self.next.process(data) + return self.next.processLegacy(data) .map { (item: Output) -> Output in decrementRequestCounter() return item diff --git a/NodeKit/Layers/Utils/RequestAborterNode.swift b/NodeKit/Layers/Utils/RequestAborterNode.swift index 393f621c..1cdcb4f2 100644 --- a/NodeKit/Layers/Utils/RequestAborterNode.swift +++ b/NodeKit/Layers/Utils/RequestAborterNode.swift @@ -44,8 +44,8 @@ open class AborterNode: AsyncNode { /// Просто передает поток следующему узлу /// и если пришло сообщение об отмене запроса, то посылает Aborter'у `cancel()` - open func process(_ data: Input) -> Observer { - return self.next.process(data) + open func processLegacy(_ data: Input) -> Observer { + return self.next.processLegacy(data) .multicast() .onCanceled { [weak self] in self?.aborter.cancel() diff --git a/NodeKit/MockerIntegration/MockerProxyConfigNode.swift b/NodeKit/MockerIntegration/MockerProxyConfigNode.swift index 139f08cd..9269e58b 100644 --- a/NodeKit/MockerIntegration/MockerProxyConfigNode.swift +++ b/NodeKit/MockerIntegration/MockerProxyConfigNode.swift @@ -54,10 +54,10 @@ final class MockerProxyConfigNode: AsyncNode { // MARK: - Node /// Добавляет хедеры в `data` - public func process(_ data: RequestModel) -> Observer { + public func processLegacy(_ data: RequestModel) -> Observer { guard self.isProxyingOn else { - return self.next.process(data) + return self.next.processLegacy(data) } var copy = data @@ -66,7 +66,7 @@ final class MockerProxyConfigNode: AsyncNode { copy.metadata[Keys.proxyingHost] = self.proxyingHost copy.metadata[Keys.proxyingScheme] = self.proxyingScheme - return self.next.process(copy) + return self.next.processLegacy(copy) } // MARK: - Node diff --git a/NodeKit/Utils/Logging/LoggerNode.swift b/NodeKit/Utils/Logging/LoggerNode.swift index 74b85d60..b8d178d7 100644 --- a/NodeKit/Utils/Logging/LoggerNode.swift +++ b/NodeKit/Utils/Logging/LoggerNode.swift @@ -21,10 +21,10 @@ open class LoggerNode: AsyncNode { /// Сразу же передает управление следующему узлу и подписывается на выполнение операций. /// /// - Parameter data: Данные для обработки. Этот узел их не использует. - open func process(_ data: Input) -> Observer { + open func processLegacy(_ data: Input) -> Observer { let result = Context() - let context = self.next.process(data) + let context = self.next.processLegacy(data) let filter = self.filters diff --git a/NodeKit/Utils/Logging/LoggerStreamNode.swift b/NodeKit/Utils/Logging/LoggerStreamNode.swift index 0c6b9225..23a0412a 100644 --- a/NodeKit/Utils/Logging/LoggerStreamNode.swift +++ b/NodeKit/Utils/Logging/LoggerStreamNode.swift @@ -28,10 +28,10 @@ open class LoggerStreamNode: AsyncStreamNode { /// Сразу же передает управление следующему узлу и подписывается на выполнение операций. /// /// - Parameter data: Данные для обработки. Этот узел их не импользует. - open func process(_ data: Input) -> Observer { + open func processLegacy(_ data: Input) -> Observer { let result = Context() - let context = self.next.process(data) + let context = self.next.processLegacy(data) let filter = self.filters diff --git a/NodeKitTests/UnitTests/AborterNode/AbortingTests.swift b/NodeKitTests/UnitTests/AborterNode/AbortingTests.swift index 83c6b7d1..75a9cb50 100644 --- a/NodeKitTests/UnitTests/AborterNode/AbortingTests.swift +++ b/NodeKitTests/UnitTests/AborterNode/AbortingTests.swift @@ -48,7 +48,7 @@ final class AbortingTests: XCTestCase { // given let nextContext = Context() - nextNodeMock.stubbedProccessResult = nextContext + nextNodeMock.stubbedProccessLegacyResult = nextContext // when @@ -61,7 +61,7 @@ final class AbortingTests: XCTestCase { var deferCalls = 0 let context = sut - .process(()) + .processLegacy(()) .onCompleted { val in completedCalls += 1 }.onError { val in @@ -106,7 +106,7 @@ final class AbortingTests: XCTestCase { // then - XCTAssertFalse(nextNodeMock.invokedProcess) + XCTAssertFalse(nextNodeMock.invokedProcessLegacy) switch result { case .success: XCTFail("Неожиданный результат") diff --git a/NodeKitTests/UnitTests/CacheNode/CacheReaderNodeTests.swift b/NodeKitTests/UnitTests/CacheNode/CacheReaderNodeTests.swift index 59ff9805..91321fd1 100644 --- a/NodeKitTests/UnitTests/CacheNode/CacheReaderNodeTests.swift +++ b/NodeKitTests/UnitTests/CacheNode/CacheReaderNodeTests.swift @@ -40,7 +40,7 @@ public class CacheReaderNodeTests: XCTestCase { var json: Json? - testNode.process(model).onCompleted { data in + testNode.processLegacy(model).onCompleted { data in json = data }.onError { error in XCTFail("\(error)") @@ -84,7 +84,7 @@ public class CacheReaderNodeTests: XCTestCase { var expected: Error? - testNode.process(model).onCompleted { data in + testNode.processLegacy(model).onCompleted { data in XCTFail("\(data)") }.onError { error in expected = error @@ -123,7 +123,7 @@ public class CacheReaderNodeTests: XCTestCase { var expected: Error? - testNode.process(model).onCompleted { data in + testNode.processLegacy(model).onCompleted { data in XCTFail("\(data)") }.onError { error in expected = error @@ -162,7 +162,7 @@ public class CacheReaderNodeTests: XCTestCase { var expected: Error? - testNode.process(model).onCompleted { data in + testNode.processLegacy(model).onCompleted { data in XCTFail("\(data)") }.onError { error in expected = error diff --git a/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagReaderNodeTests.swift b/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagReaderNodeTests.swift index 16e4b071..51e1c41c 100644 --- a/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagReaderNodeTests.swift +++ b/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagReaderNodeTests.swift @@ -51,7 +51,7 @@ final class UrlETagReaderNodeTests: XCTestCase { let params = TransportUrlParameters(method: .get, url: url) let request = TransportUrlRequest(with:params , raw: Data()) - nextNodeMock.stubbedProccessResult = .emit(data: Json()) + nextNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) var expectedHeader = request.headers expectedHeader[ETagConstants.eTagRequestHeaderKey] = tag @@ -68,7 +68,7 @@ final class UrlETagReaderNodeTests: XCTestCase { var callCount = 0 - sut.process(request).onCompleted { _ in + sut.processLegacy(request).onCompleted { _ in callCount += 1 expectation.fulfill() }.onError { _ in @@ -80,9 +80,9 @@ final class UrlETagReaderNodeTests: XCTestCase { // then - let nextNodeParameter = try XCTUnwrap(nextNodeMock.invokedProcessParameter) + let nextNodeParameter = try XCTUnwrap(nextNodeMock.invokedProcessLegacyParameter) - XCTAssertEqual(nextNodeMock.invokedProcessCount, 1) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyCount, 1) XCTAssertEqual(callCount, 1) XCTAssertEqual(nextNodeParameter.method, request.method) XCTAssertEqual(nextNodeParameter.url, request.url) @@ -99,7 +99,7 @@ final class UrlETagReaderNodeTests: XCTestCase { let params = TransportUrlParameters(method: .get, url: url) let request = TransportUrlRequest(with:params , raw: Data()) - nextNodeMock.stubbedProccessResult = .emit(data: Json()) + nextNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) let expectation = self.expectation(description: "\(#function)") @@ -109,7 +109,7 @@ final class UrlETagReaderNodeTests: XCTestCase { var callCount = 0 - sut.process(request).onCompleted { _ in + sut.processLegacy(request).onCompleted { _ in callCount += 1 expectation.fulfill() }.onError { _ in @@ -121,10 +121,10 @@ final class UrlETagReaderNodeTests: XCTestCase { // then - let nextProcessInvokedParameter = try XCTUnwrap(nextNodeMock.invokedProcessParameter) + let nextProcessInvokedParameter = try XCTUnwrap(nextNodeMock.invokedProcessLegacyParameter) XCTAssertEqual(callCount, 1) - XCTAssertEqual(nextNodeMock.invokedProcessCount, 1) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyCount, 1) XCTAssertEqual(request.headers, nextProcessInvokedParameter.headers) XCTAssertEqual(request.url, nextProcessInvokedParameter.url) XCTAssertEqual(request.method, nextProcessInvokedParameter.method) @@ -143,7 +143,7 @@ final class UrlETagReaderNodeTests: XCTestCase { let params = TransportUrlParameters(method: .get, url: url) let request = TransportUrlRequest(with:params , raw: Data()) - nextNodeMock.stubbedProccessResult = .emit(data: Json()) + nextNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) var expectedHeader = request.headers expectedHeader[key] = tag @@ -160,7 +160,7 @@ final class UrlETagReaderNodeTests: XCTestCase { var callCount = 0 - sut.process(request).onCompleted { _ in + sut.processLegacy(request).onCompleted { _ in callCount += 1 expectation.fulfill() }.onError { _ in @@ -172,9 +172,9 @@ final class UrlETagReaderNodeTests: XCTestCase { // then - let nextNodeParameter = try XCTUnwrap(nextNodeMock.invokedProcessParameter) + let nextNodeParameter = try XCTUnwrap(nextNodeMock.invokedProcessLegacyParameter) - XCTAssertEqual(nextNodeMock.invokedProcessCount, 1) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyCount, 1) XCTAssertEqual(callCount, 1) XCTAssertEqual(nextNodeParameter.method, request.method) XCTAssertEqual(nextNodeParameter.url, request.url) @@ -210,7 +210,7 @@ final class UrlETagReaderNodeTests: XCTestCase { // then - let nextNodeParameter = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameter) + let nextNodeParameter = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameter?.0) XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) XCTAssertEqual(nextNodeParameter.method, request.method) @@ -237,7 +237,7 @@ final class UrlETagReaderNodeTests: XCTestCase { // then let nextProcessInvokedParameter = try XCTUnwrap( - nextNodeMock.invokedAsyncProcessParameter + nextNodeMock.invokedAsyncProcessParameter?.0 ) XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) @@ -277,7 +277,7 @@ final class UrlETagReaderNodeTests: XCTestCase { // then let nextNodeParameter = try XCTUnwrap( - nextNodeMock.invokedAsyncProcessParameter + nextNodeMock.invokedAsyncProcessParameter?.0 ) XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) diff --git a/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagSaverNodeTests.swift b/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagSaverNodeTests.swift index 485ba2dc..4bb8668d 100644 --- a/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagSaverNodeTests.swift +++ b/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagSaverNodeTests.swift @@ -34,7 +34,7 @@ public class UrlETagSaverNodeTests: XCTestCase { // Act - node.process(data).onCompleted { model in + node.processLegacy(data).onCompleted { model in callCount += 1 expectation.fulfill() }.onError { error in @@ -74,7 +74,7 @@ public class UrlETagSaverNodeTests: XCTestCase { // Act - node.process(data).onCompleted { model in + node.processLegacy(data).onCompleted { model in callCount += 1 expectation.fulfill() }.onError { error in @@ -115,7 +115,7 @@ public class UrlETagSaverNodeTests: XCTestCase { // Act - node.process(data).onCompleted { model in + node.processLegacy(data).onCompleted { model in callCount += 1 expectation.fulfill() }.onError { error in @@ -165,11 +165,11 @@ public class UrlETagSaverNodeTests: XCTestCase { // Act - node.process(data1) + node.processLegacy(data1) .onCompleted { _ in expectation1.fulfill() } .onError { _ in expectation1.fulfill() } - node.process(data2) + node.processLegacy(data2) .onCompleted { _ in expectation2.fulfill() } .onError { _ in expectation2.fulfill() } diff --git a/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagUrlCacheTriggerNodeTests.swift b/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagUrlCacheTriggerNodeTests.swift index e07a2738..637955b3 100644 --- a/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagUrlCacheTriggerNodeTests.swift +++ b/NodeKitTests/UnitTests/CacheNode/ETag/UrlETagUrlCacheTriggerNodeTests.swift @@ -50,13 +50,13 @@ final class UrlETagUrlCacheTriggerNodeTests: XCTestCase { let expectation = self.expectation(description: "\(#function)") - transportNodeMock.stubbedProccessResult = .emit(data: Json()) + transportNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) // when var numberOfCalls = 0 - sut.process(response).onCompleted { _ in + sut.processLegacy(response).onCompleted { _ in numberOfCalls += 1 expectation.fulfill() }.onError { _ in @@ -69,8 +69,8 @@ final class UrlETagUrlCacheTriggerNodeTests: XCTestCase { // then XCTAssertEqual(numberOfCalls, 1) - XCTAssertEqual(transportNodeMock.invokedProcessCount, 1) - XCTAssertFalse(cacheSaverMock.invokedProcess) + XCTAssertEqual(transportNodeMock.invokedProcessLegacyCount, 1) + XCTAssertFalse(cacheSaverMock.invokedProcessLegacy) } func testProcess_whenStatus304_thenCacheNodeCalled() { @@ -81,13 +81,13 @@ final class UrlETagUrlCacheTriggerNodeTests: XCTestCase { let expectation = self.expectation(description: "\(#function)") - cacheSaverMock.stubbedProccessResult = .emit(data: Json()) + cacheSaverMock.stubbedProccessLegacyResult = .emit(data: Json()) // when var numberOfCalls = 0 - sut.process(response).onCompleted { _ in + sut.processLegacy(response).onCompleted { _ in numberOfCalls += 1 expectation.fulfill() }.onError { _ in @@ -100,8 +100,8 @@ final class UrlETagUrlCacheTriggerNodeTests: XCTestCase { // then XCTAssertEqual(numberOfCalls, 1) - XCTAssertFalse(transportNodeMock.invokedAsyncProcess) - XCTAssertEqual(cacheSaverMock.invokedProcessCount, 1) + XCTAssertFalse(transportNodeMock.invokedProcessLegacy) + XCTAssertEqual(cacheSaverMock.invokedProcessLegacyCount, 1) } func testAsyncProcess_whenDataIsNotModified_thenNextCalled() async throws { @@ -122,8 +122,8 @@ final class UrlETagUrlCacheTriggerNodeTests: XCTestCase { let unwrappedResult = try XCTUnwrap(try result.get() as? [String: String]) XCTAssertEqual(transportNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(transportNodeMock.invokedAsyncProcessParameter, response) - XCTAssertFalse(cacheSaverMock.invokedProcess) + XCTAssertEqual(transportNodeMock.invokedAsyncProcessParameter?.0, response) + XCTAssertFalse(cacheSaverMock.invokedAsyncProcess) XCTAssertEqual(unwrappedResult, expectedNextResult) } @@ -147,7 +147,7 @@ final class UrlETagUrlCacheTriggerNodeTests: XCTestCase { XCTAssertFalse(transportNodeMock.invokedAsyncProcess) XCTAssertEqual(cacheSaverMock.invokedAsyncProcessCount, 1) XCTAssertEqual( - cacheSaverMock.invokedAsyncProcessParameter?.urlRequest, + cacheSaverMock.invokedAsyncProcessParameter?.0.urlRequest, response.request ) XCTAssertEqual(unwrappedResult, expectedCacheResult) diff --git a/NodeKitTests/UnitTests/CacheNode/FirstCachePolicyTests.swift b/NodeKitTests/UnitTests/CacheNode/FirstCachePolicyTests.swift index 850bd74d..e3db99fa 100644 --- a/NodeKitTests/UnitTests/CacheNode/FirstCachePolicyTests.swift +++ b/NodeKitTests/UnitTests/CacheNode/FirstCachePolicyTests.swift @@ -52,11 +52,11 @@ final class FirstCachePolicyTests: XCTestCase { var completedCalls = 0 - nextNodeMock.stubbedProccessResult = .emit(data: Json()) + nextNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) // when - sut.process(request).onCompleted { data in + sut.processLegacy(request).onCompleted { data in completedCalls += 1 expectation.fulfill() } @@ -72,8 +72,8 @@ final class FirstCachePolicyTests: XCTestCase { // then XCTAssertEqual(completedCalls, 1) - XCTAssertEqual(nextNodeMock.invokedProcessCount, 1) - XCTAssertFalse(readerNodeMock.invokedProcess) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyCount, 1) + XCTAssertFalse(readerNodeMock.invokedProcessLegacy) } func testProcess_whenGoodInput_thenReaderCalled() { @@ -87,12 +87,12 @@ final class FirstCachePolicyTests: XCTestCase { let nextNodeContext = Context() let readerNodeContext = Context() - nextNodeMock.stubbedProccessResult = nextNodeContext - readerNodeMock.stubbedProccessResult = readerNodeContext + nextNodeMock.stubbedProccessLegacyResult = nextNodeContext + readerNodeMock.stubbedProccessLegacyResult = readerNodeContext // when - sut.process(request).onCompleted { data in + sut.processLegacy(request).onCompleted { data in completedCalls += 1 if completedCalls == 2 { expectation.fulfill() @@ -111,8 +111,8 @@ final class FirstCachePolicyTests: XCTestCase { // then XCTAssertEqual(completedCalls, 2) - XCTAssertEqual(nextNodeMock.invokedProcessCount, 1) - XCTAssertEqual(readerNodeMock.invokedProcessCount, 1) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyCount, 1) + XCTAssertEqual(readerNodeMock.invokedProcessLegacyCount, 1) } func testAsyncProcess_whenBadInput_thenNextCalled() async throws { diff --git a/NodeKitTests/UnitTests/CacheNode/IfConnectionFailedFromCacheNodeTests.swift b/NodeKitTests/UnitTests/CacheNode/IfConnectionFailedFromCacheNodeTests.swift index a307151b..95c69d00 100644 --- a/NodeKitTests/UnitTests/CacheNode/IfConnectionFailedFromCacheNodeTests.swift +++ b/NodeKitTests/UnitTests/CacheNode/IfConnectionFailedFromCacheNodeTests.swift @@ -52,17 +52,17 @@ public class IfConnectionFailedFromCacheNodeTests: XCTestCase { let request = URLRequest(url: URL(string: "test.ex.temp")!) - mapperNextNodeMock.stubbedProccessResult = .emit(error: NSError(domain: "app.network", code: -1009, userInfo: nil)) - cacheReaderNodeMock.stubbedProccessResult = .emit(data: Json()) + mapperNextNodeMock.stubbedProccessLegacyResult = .emit(error: NSError(domain: "app.network", code: -1009, userInfo: nil)) + cacheReaderNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) // when - _ = sut.process(request) + _ = sut.processLegacy(request) // then - XCTAssertEqual(mapperNextNodeMock.invokedProcessCount, 1) - XCTAssertEqual(cacheReaderNodeMock.invokedProcessCount, 1) + XCTAssertEqual(mapperNextNodeMock.invokedProcessLegacyCount, 1) + XCTAssertEqual(cacheReaderNodeMock.invokedProcessLegacyCount, 1) } public func testProcess_withoutError_thenNodeWorkInCaseOfGoodInternet() { @@ -70,17 +70,17 @@ public class IfConnectionFailedFromCacheNodeTests: XCTestCase { let request = URLRequest(url: URL(string: "test.ex.temp")!) - mapperNextNodeMock.stubbedProccessResult = .emit(data: Json()) - cacheReaderNodeMock.stubbedProccessResult = .emit(data: Json()) + mapperNextNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) + cacheReaderNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) // when - _ = sut.process(request) + _ = sut.processLegacy(request) // then - XCTAssertEqual(mapperNextNodeMock.invokedProcessCount, 1) - XCTAssertEqual(cacheReaderNodeMock.invokedProcessCount, 0) + XCTAssertEqual(mapperNextNodeMock.invokedProcessLegacyCount, 1) + XCTAssertEqual(cacheReaderNodeMock.invokedProcessLegacyCount, 0) } public func testAsyncProcess_whenErrorReceived_thenNodeWorkInCaseOfBadInternet() async throws { @@ -100,9 +100,9 @@ public class IfConnectionFailedFromCacheNodeTests: XCTestCase { let unwrappedResult = try XCTUnwrap(result.get() as? [String: String]) XCTAssertEqual(mapperNextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(mapperNextNodeMock.invokedAsyncProcessParameter, request) + XCTAssertEqual(mapperNextNodeMock.invokedAsyncProcessParameter?.0, request) XCTAssertEqual(cacheReaderNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(cacheReaderNodeMock.invokedAsyncProcessParameter?.urlRequest, request) + XCTAssertEqual(cacheReaderNodeMock.invokedAsyncProcessParameter?.0.urlRequest, request) XCTAssertEqual(unwrappedResult, expectedResult) } @@ -123,7 +123,7 @@ public class IfConnectionFailedFromCacheNodeTests: XCTestCase { let unwrappedResult = try XCTUnwrap(result.get() as? [String: String]) XCTAssertEqual(mapperNextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(mapperNextNodeMock.invokedAsyncProcessParameter, request) + XCTAssertEqual(mapperNextNodeMock.invokedAsyncProcessParameter?.0, request) XCTAssertFalse(cacheReaderNodeMock.invokedAsyncProcess) XCTAssertEqual(unwrappedResult, expectedResult) } diff --git a/NodeKitTests/UnitTests/Coding/EncodingTests.swift b/NodeKitTests/UnitTests/Coding/EncodingTests.swift index eec6adc7..91f0d22e 100644 --- a/NodeKitTests/UnitTests/Coding/EncodingTests.swift +++ b/NodeKitTests/UnitTests/Coding/EncodingTests.swift @@ -58,18 +58,18 @@ final class EncodingTests: XCTestCase { encoding: .formUrl ) - nextNodeMock.stubbedProccessResult = .emit(data: Json()) + nextNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) // when - _ = sut.process(encodingModel) + _ = sut.processLegacy(encodingModel) // then - XCTAssertEqual(nextNodeMock.invokedProcessCount, 1) - XCTAssertEqual(nextNodeMock.invokedProcessParameter?.url!.absoluteString, url) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyCount, 1) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyParameter?.url!.absoluteString, url) XCTAssertEqual( - nextNodeMock.invokedProcessParameter?.headers.dictionary, + nextNodeMock.invokedProcessLegacyParameter?.headers.dictionary, headersArray ) } @@ -86,17 +86,17 @@ final class EncodingTests: XCTestCase { encoding: .urlQuery ) - nextNodeMock.stubbedProccessResult = .emit(data: Json()) + nextNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) // when - _ = sut.process(encodingModel) + _ = sut.processLegacy(encodingModel) // then - XCTAssertEqual(nextNodeMock.invokedProcessCount, 1) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyCount, 1) XCTAssertEqual( - nextNodeMock?.invokedProcessParameter?.url!.absoluteString, + nextNodeMock?.invokedProcessLegacyParameter?.url!.absoluteString, "\(url)?id=12345" ) } @@ -114,17 +114,17 @@ final class EncodingTests: XCTestCase { encoding: .json ) - nextNodeMock.stubbedProccessResult = .emit(data: Json()) + nextNodeMock.stubbedProccessLegacyResult = .emit(data: Json()) // when - _ = sut.process(encodingModel) + _ = sut.processLegacy(encodingModel) // then - XCTAssertEqual(nextNodeMock.invokedProcessCount, 1) - XCTAssertEqual(nextNodeMock.invokedProcessParameter?.url!.absoluteString, url) - XCTAssertEqual(nextNodeMock.invokedProcessParameter?.headers.dictionary, headersArray) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyCount, 1) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyParameter?.url!.absoluteString, url) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyParameter?.headers.dictionary, headersArray) } func testAsyncProcess_thenFormUrlConvertinWork() async throws { @@ -154,9 +154,9 @@ final class EncodingTests: XCTestCase { let unwrappedResult = try XCTUnwrap(try result.get() as? [String: String]) XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(nextNodeMock.invokedAsyncProcessParameter?.url!.absoluteString, url) + XCTAssertEqual(nextNodeMock.invokedAsyncProcessParameter?.0.url!.absoluteString, url) XCTAssertEqual( - nextNodeMock.invokedAsyncProcessParameter?.headers.dictionary, + nextNodeMock.invokedAsyncProcessParameter?.0.headers.dictionary, headersArray ) XCTAssertEqual(unwrappedResult, expectedResult) @@ -188,7 +188,7 @@ final class EncodingTests: XCTestCase { XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) XCTAssertEqual( - nextNodeMock?.invokedAsyncProcessParameter?.url!.absoluteString, + nextNodeMock?.invokedAsyncProcessParameter?.0.url!.absoluteString, "\(url)?id=12345" ) XCTAssertEqual(unwrappedResult, expectedResult) @@ -220,9 +220,9 @@ final class EncodingTests: XCTestCase { let unwrappedResult = try XCTUnwrap(try result.get() as? [String: String]) XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(nextNodeMock.invokedAsyncProcessParameter?.url!.absoluteString, url) + XCTAssertEqual(nextNodeMock.invokedAsyncProcessParameter?.0.url!.absoluteString, url) XCTAssertEqual( - nextNodeMock.invokedAsyncProcessParameter?.headers.dictionary, + nextNodeMock.invokedAsyncProcessParameter?.0.headers.dictionary, headersArray ) XCTAssertEqual(unwrappedResult, expectedResult) diff --git a/NodeKitTests/UnitTests/DTO/DTOMapperNodeTests.swift b/NodeKitTests/UnitTests/DTO/DTOMapperNodeTests.swift index c78e7e66..3f4131ee 100644 --- a/NodeKitTests/UnitTests/DTO/DTOMapperNodeTests.swift +++ b/NodeKitTests/UnitTests/DTO/DTOMapperNodeTests.swift @@ -24,7 +24,7 @@ class DTOMapperNodeTests: XCTestCase { } @discardableResult - public func process(_ data: Json) -> Observer { + public func processLegacy(_ data: Json) -> Observer { if let error = resultError { var log = Log(self.logViewObjectName, id: self.objectName, order: LogOrder.dtoMapperNode) log += "\(error)" @@ -54,7 +54,7 @@ class DTOMapperNodeTests: XCTestCase { let exp = self.expectation(description: "\(#function)") - let result = mapperNode.process([:]).onError { error in + let result = mapperNode.processLegacy([:]).onError { error in resultError = error exp.fulfill() } @@ -86,7 +86,7 @@ class DTOMapperNodeTests: XCTestCase { let exp = self.expectation(description: "\(#function)") - let result = mapperNode.process([:]).onCompleted { user in + let result = mapperNode.processLegacy([:]).onCompleted { user in resultUser = user exp.fulfill() }.onError { error in @@ -110,7 +110,7 @@ class DTOMapperNodeTests: XCTestCase { let exp = self.expectation(description: "\(#function)") - let result = mapperNode.process([:]).onError { error in + let result = mapperNode.processLegacy([:]).onError { error in resultError = error exp.fulfill() } diff --git a/NodeKitTests/UnitTests/InputLayer/ChainConfiguratorNodeTests.swift b/NodeKitTests/UnitTests/InputLayer/ChainConfiguratorNodeTests.swift index 161ef0bb..f3b445ac 100644 --- a/NodeKitTests/UnitTests/InputLayer/ChainConfiguratorNodeTests.swift +++ b/NodeKitTests/UnitTests/InputLayer/ChainConfiguratorNodeTests.swift @@ -27,7 +27,7 @@ public class ChainConfiguratorNodeTests: XCTestCase { var queueLabel = "" - func process(_ data: Void) -> Observer { + func processLegacy(_ data: Void) -> Observer { self.queueLabel = DispatchQueue.currentLabel return .emit(data: data) } @@ -53,7 +53,7 @@ public class ChainConfiguratorNodeTests: XCTestCase { let exp = self.expectation(description: "\(#function)") - _ = testedNode.process(()).onCompleted { + _ = testedNode.processLegacy(()).onCompleted { exp.fulfill() } @@ -75,7 +75,7 @@ public class ChainConfiguratorNodeTests: XCTestCase { let exp = self.expectation(description: "\(#function)") - _ = testedNode.process(()).onCompleted { + _ = testedNode.processLegacy(()).onCompleted { currentQueueLabel = DispatchQueue.currentLabel exp.fulfill() } diff --git a/NodeKitTests/UnitTests/MockerIntegration/MockerProxyConfigNodeTests.swift b/NodeKitTests/UnitTests/MockerIntegration/MockerProxyConfigNodeTests.swift index 1d624d76..3c3b892c 100644 --- a/NodeKitTests/UnitTests/MockerIntegration/MockerProxyConfigNodeTests.swift +++ b/NodeKitTests/UnitTests/MockerIntegration/MockerProxyConfigNodeTests.swift @@ -37,22 +37,22 @@ final class MockerProxyConfigNodeTests: XCTestCase { let isProxyingOn = true let expectedNextNodeResult = RequestModel(metadata: ["test1":"value1"], raw: 15) - nextNodeMock.stubbedProccessResult = .emit(data: expectedNextNodeResult) + nextNodeMock.stubbedProccessLegacyResult = .emit(data: expectedNextNodeResult) makeSut(isProxyingOn: isProxyingOn, proxyingHost: host, proxyingScheme: scheme) // when var nextNodeResult: RequestModel? - sut.process(.init(metadata: [:], raw: 0)).onCompleted { value in + sut.processLegacy(.init(metadata: [:], raw: 0)).onCompleted { value in nextNodeResult = value } // then - let result = try XCTUnwrap(nextNodeMock.invokedProcessParameter) + let result = try XCTUnwrap(nextNodeMock.invokedProcessLegacyParameter) let nextNodeUnwrappedResult = try XCTUnwrap(nextNodeResult) - XCTAssertEqual(nextNodeMock.invokedProcessCount, 1) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyCount, 1) XCTAssertEqual(result.metadata[MockerProxyConfigKey.isProxyingOn], "\(isProxyingOn)") XCTAssertEqual(result.metadata[MockerProxyConfigKey.proxyingHost], host) XCTAssertEqual(result.metadata[MockerProxyConfigKey.proxyingScheme], scheme) @@ -68,22 +68,22 @@ final class MockerProxyConfigNodeTests: XCTestCase { let isProxyingOn = false let expectedNextNodeResult = RequestModel(metadata: ["test2":"value2"], raw: 16) - nextNodeMock.stubbedProccessResult = .emit(data: expectedNextNodeResult) + nextNodeMock.stubbedProccessLegacyResult = .emit(data: expectedNextNodeResult) makeSut(isProxyingOn: isProxyingOn, proxyingHost: host, proxyingScheme: scheme) // when var nextNodeResult: RequestModel? - sut.process(.init(metadata: [:], raw: 0)).onCompleted { value in + sut.processLegacy(.init(metadata: [:], raw: 0)).onCompleted { value in nextNodeResult = value } // then - let result = try XCTUnwrap(nextNodeMock.invokedProcessParameter) + let result = try XCTUnwrap(nextNodeMock.invokedProcessLegacyParameter) let nextNodeUnwrappedResult = try XCTUnwrap(nextNodeResult) - XCTAssertEqual(nextNodeMock.invokedProcessCount, 1) + XCTAssertEqual(nextNodeMock.invokedProcessLegacyCount, 1) XCTAssertNil(result.metadata[MockerProxyConfigKey.isProxyingOn]) XCTAssertNil(result.metadata[MockerProxyConfigKey.proxyingHost]) XCTAssertNil(result.metadata[MockerProxyConfigKey.proxyingScheme]) @@ -108,7 +108,7 @@ final class MockerProxyConfigNodeTests: XCTestCase { // then - let result = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameter) + let result = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameter?.0) XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) XCTAssertEqual(result.metadata[MockerProxyConfigKey.isProxyingOn], "\(isProxyingOn)") XCTAssertEqual(result.metadata[MockerProxyConfigKey.proxyingHost], host) @@ -134,7 +134,7 @@ final class MockerProxyConfigNodeTests: XCTestCase { // then - let result = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameter) + let result = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameter?.0) XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) XCTAssertNil(result.metadata[MockerProxyConfigKey.isProxyingOn]) XCTAssertNil(result.metadata[MockerProxyConfigKey.proxyingHost]) diff --git a/NodeKitTests/UnitTests/Node/AsyncNodeTests.swift b/NodeKitTests/UnitTests/Node/AsyncNodeTests.swift index ac9f3ef2..9d025cea 100644 --- a/NodeKitTests/UnitTests/Node/AsyncNodeTests.swift +++ b/NodeKitTests/UnitTests/Node/AsyncNodeTests.swift @@ -12,10 +12,9 @@ import XCTest final class AsyncNodeTests: XCTestCase { - // MARK: - Sut + // MARK: - Dependencies private var logContextMock: LoggingContextMock! - private var nodeMock: AsyncNodeMock! private var cancellable: Set! // MARK: - Lifecycle @@ -23,35 +22,130 @@ final class AsyncNodeTests: XCTestCase { override func setUp() { super.setUp() logContextMock = LoggingContextMock() - nodeMock = AsyncNodeMock() cancellable = Set() } override func tearDown() { super.tearDown() logContextMock = nil - nodeMock = nil cancellable = nil } // MARK: - Tests - func testCombineNode_thenCombineNodeCreated() async throws { + func testAsyncProcess_whenDataIsVoid_thenMainMethodCalled() async throws { // given + let sut = AsyncNodeMock() + let expectedResult: NodeResult = .success(2) + + sut.stubbedAsyncProccessResult = expectedResult + + // when + + let result = await sut.process() + + // then + + let unwrappedResult = try XCTUnwrap(result) + + XCTAssertEqual(sut.invokedAsyncProcessCount, 1) + XCTAssertFalse(sut.invokedAsyncProcessParameter?.1 === logContextMock) + XCTAssertEqual(unwrappedResult.castToMockError(), expectedResult.castToMockError()) + } + + func testAsyncProcess_withData_thenNewLogContextCreated() async throws { + // given + + let sut = AsyncNodeMock() + let expectedInput = 1 + let expectedResult: NodeResult = .success(2) + + sut.stubbedAsyncProccessResult = expectedResult + + // when + + let result = await sut.process(expectedInput) + + // then + + let unwrappedResult = try XCTUnwrap(result) + + XCTAssertEqual(sut.invokedAsyncProcessCount, 1) + XCTAssertEqual(sut.invokedAsyncProcessParameter?.0, expectedInput) + XCTAssertFalse(sut.invokedAsyncProcessParameter?.1 === logContextMock) + XCTAssertEqual(unwrappedResult.castToMockError(), expectedResult.castToMockError()) + } + + func testNodeResultPublisher_onMainQueue_thenDataReceivedOnMainQueue() async { + // given + + let sut = AsyncNodeMock() let expectation = expectation(description: "result") - let expectedInput = 4 - let expectedResult: NodeResult = .success(15) + + var isMainThread = false + + sut.stubbedAsyncProccessResult = .success(1) + + // when + + sut.nodeResultPublisher(for: 1, on: DispatchQueue.main, logContext: logContextMock) + .sink(receiveValue: { _ in + isMainThread = Thread.isMainThread + expectation.fulfill() + }) + .store(in: &cancellable) + + await fulfillment(of: [expectation], timeout: 0.1) + + // then + + XCTAssertTrue(isMainThread) + } + + func testNodeResultPublisher_onCustomQueue_thenDataReceivedOnCustomQueue() async { + // given + + let sut = AsyncNodeMock() + let expectation = expectation(description: "result") + let expectedQueueName = "Test Process Queue" + let queue = DispatchQueue(label: expectedQueueName) + + var queueName: String? + + sut.stubbedAsyncProccessResult = .success(1) + + // when + + sut.nodeResultPublisher(for: 1, on: queue, logContext: logContextMock) + .sink(receiveValue: { _ in + queueName = DispatchQueue.currentLabel + expectation.fulfill() + }) + .store(in: &cancellable) + + await fulfillment(of: [expectation], timeout: 0.1) + + // then + + XCTAssertEqual(queueName, expectedQueueName) + } + + func testNodeResultPublisher_whenResultIsSuccess_thenSuccessResultReceived() async throws { + // given + + let sut = AsyncNodeMock() + let expectation = expectation(description: "result") + let expectedInput = 7 + let expectedResult: NodeResult = .success(8) var result: NodeResult? - nodeMock.stubbedAsyncProccessResult = expectedResult + sut.stubbedAsyncProccessResult = expectedResult // when - let sut = nodeMock.combineNode() - sut.process(expectedInput, logContext: logContextMock) - .eraseToAnyPublisher() + sut.nodeResultPublisher(for: expectedInput, on: DispatchQueue.main, logContext: logContextMock) .sink(receiveValue: { value in result = value expectation.fulfill() @@ -64,44 +158,43 @@ final class AsyncNodeTests: XCTestCase { let unwrappedResult = try XCTUnwrap(result) - XCTAssertEqual(nodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(nodeMock.invokedAsyncProcessParameter, expectedInput) + XCTAssertEqual(sut.invokedAsyncProcessCount, 1) + XCTAssertEqual(sut.invokedAsyncProcessParameter?.0, expectedInput) XCTAssertEqual(unwrappedResult.castToMockError(), expectedResult.castToMockError()) } - func testCombineNode_withMultipleSubsciptions_thenCombineNodeCreated() async throws { + func testNodeResultPublisher_whithMultipleSubscriptions_thenResultsReceived() async throws { // given + let sut = AsyncNodeMock() let expectation1 = expectation(description: "result1") let expectation2 = expectation(description: "result2") - let expectedInput = 4 - let expectedResult: NodeResult = .success(13) + let expectedInput = 7 + let expectedResult: NodeResult = .success(8) var result1: NodeResult? var result2: NodeResult? - nodeMock.stubbedAsyncProccessResult = expectedResult + sut.stubbedAsyncProccessResult = expectedResult // when - let sut = nodeMock.combineNode() + let publisher = sut.nodeResultPublisher(for: expectedInput, on: DispatchQueue.main, logContext: logContextMock) - sut.eraseToAnyPublisher() + publisher .sink(receiveValue: { value in result1 = value expectation1.fulfill() }) .store(in: &cancellable) - sut.eraseToAnyPublisher() + publisher .sink(receiveValue: { value in result2 = value expectation2.fulfill() }) .store(in: &cancellable) - sut.process(expectedInput, logContext: logContextMock) - await fulfillment(of: [expectation1, expectation2], timeout: 0.1) // then @@ -109,9 +202,41 @@ final class AsyncNodeTests: XCTestCase { let unwrappedResult1 = try XCTUnwrap(result1) let unwrappedResult2 = try XCTUnwrap(result2) - XCTAssertEqual(nodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(nodeMock.invokedAsyncProcessParameter, expectedInput) + XCTAssertEqual(sut.invokedAsyncProcessCount, 1) + XCTAssertEqual(sut.invokedAsyncProcessParameter?.0, expectedInput) XCTAssertEqual(unwrappedResult1.castToMockError(), expectedResult.castToMockError()) XCTAssertEqual(unwrappedResult2.castToMockError(), expectedResult.castToMockError()) } + + func testNodeResultPublisher_whenResultIsFailure_thenFailureResultReceived() async throws { + // given + + let sut = AsyncNodeMock() + let expectation = expectation(description: "result") + let expectedInput = 9 + let expectedResult: NodeResult = .failure(MockError.firstError) + + var result: NodeResult? + + sut.stubbedAsyncProccessResult = expectedResult + + // when + + sut.nodeResultPublisher(for: expectedInput, on: DispatchQueue.main, logContext: logContextMock) + .sink(receiveValue: { value in + result = value + expectation.fulfill() + }) + .store(in: &cancellable) + + await fulfillment(of: [expectation], timeout: 0.1) + + // then + + let unwrappedResult = try XCTUnwrap(result) + + XCTAssertEqual(sut.invokedAsyncProcessCount, 1) + XCTAssertEqual(sut.invokedAsyncProcessParameter?.0, expectedInput) + XCTAssertEqual(unwrappedResult.castToMockError(), expectedResult.castToMockError()) + } } diff --git a/NodeKitTests/UnitTests/Node/AsyncStreamNodeTests.swift b/NodeKitTests/UnitTests/Node/AsyncStreamNodeTests.swift index 30da8bf3..e73d5483 100644 --- a/NodeKitTests/UnitTests/Node/AsyncStreamNodeTests.swift +++ b/NodeKitTests/UnitTests/Node/AsyncStreamNodeTests.swift @@ -12,10 +12,9 @@ import XCTest final class AsyncStreamNodeTests: XCTestCase { - // MARK: - Sut + // MARK: - Dependencies private var logContextMock: LoggingContextMock! - private var nodeMock: AsyncStreamNodeMock! private var cancellable: Set! // MARK: - Lifecycle @@ -23,24 +22,24 @@ final class AsyncStreamNodeTests: XCTestCase { override func setUp() { super.setUp() logContextMock = LoggingContextMock() - nodeMock = AsyncStreamNodeMock() cancellable = Set() } override func tearDown() { super.tearDown() logContextMock = nil - nodeMock = nil + cancellable.forEach { + $0.cancel() + } cancellable = nil } // MARK: - Tests - func testCombineNode_thenCombineNodeCreated() async { + func testAsyncStreamProcess_whenDataIsVoid_thenMainMethodCalled() async throws { // given - let expectation = expectation(description: "result") - let expectedInput = 43 + let sut = AsyncStreamNodeMock() let expectedResults: [Result] = [ .success(100), @@ -49,99 +48,82 @@ final class AsyncStreamNodeTests: XCTestCase { .success(99), .failure(MockError.thirdError) ] - let castedResults = expectedResults.compactMap { $0.castToMockError() } - var index: Int? var results: [NodeResult] = [] - nodeMock.stubbedAsyncStreamProccessResult = AsyncStream { continuation in - expectedResults.forEach { continuation.yield($0) } - continuation.finish() + sut.stubbedAsyncStreamProccessResult = { + AsyncStream { continuation in + expectedResults.forEach { continuation.yield($0) } + continuation.finish() + } } // when - let sut = nodeMock.combineNode() - sut.process(expectedInput, logContext: logContextMock) - .eraseToAnyPublisher() - .sink(receiveValue: { value in - results.append(value) - if let valueIndex = index ?? value.findIndex(in: castedResults) { - index = valueIndex - if results.count == expectedResults.count - valueIndex { - expectation.fulfill() - } - } - }) - .store(in: &cancellable) - - await fulfillment(of: [expectation], timeout: 1) + for await result in sut.process() { + results.append(result) + } // then - let allExpectedResults = Array(castedResults.dropFirst(index ?? 0)) - - XCTAssertEqual(nodeMock.invokedAsyncStreamProcessCount, 1) - XCTAssertEqual(nodeMock.invokedAsyncStreamProcessParameter, expectedInput) - XCTAssertEqual(results.compactMap { $0.castToMockError() }, allExpectedResults) + XCTAssertEqual(sut.invokedAsyncStreamProcessCount, 1) + XCTAssertEqual( + results.compactMap { $0.castToMockError() }, + expectedResults.compactMap { $0.castToMockError() } + ) } - func testCombineNode_withMultipleSubsciptions_thenCombineNodeCreated() async { + func testAsyncProcess_withData_thenNewLogContextCreated() async throws { // given - let expectation1 = expectation(description: "result1") - let expectation2 = expectation(description: "result2") - let expectedInput = 42 + let sut = AsyncStreamNodeMock() + let expectedInput = 32 - let expectedResults: [Result] = [ - .success(500), - .failure(.secondError), - .success(1), - .failure(.secondError), - .failure(.thirdError) + let expectedResults: [Result] = [ + .success(100), + .failure(MockError.firstError), + .failure(MockError.secondError), + .success(99), + .failure(MockError.thirdError) ] - let nodeResults: [NodeResult] = expectedResults.map { res in res.mapError { $0 } } - - var results1: [NodeResult] = [] - var results2: [NodeResult] = [] + var results: [NodeResult] = [] - nodeMock.stubbedAsyncStreamProccessResult = AsyncStream { continuation in - nodeResults.forEach { continuation.yield($0) } - continuation.finish() + sut.stubbedAsyncStreamProccessResult = { + AsyncStream { continuation in + expectedResults.forEach { continuation.yield($0) } + continuation.finish() + } } // when - let sut = nodeMock.combineNode() + for await result in sut.process(expectedInput) { + results.append(result) + } - sut.eraseToAnyPublisher() - .sink(receiveValue: { value in - results1.append(value) - if results1.count == expectedResults.count { - expectation1.fulfill() - } - }) - .store(in: &cancellable) + // then - sut.eraseToAnyPublisher() - .sink(receiveValue: { value in - results2.append(value) - if results2.count == expectedResults.count { - expectation2.fulfill() - } - }) - .store(in: &cancellable) + XCTAssertEqual(sut.invokedAsyncStreamProcessCount, 1) + XCTAssertEqual(sut.invokedAsyncStreamProcessParameter?.0, expectedInput) + XCTAssertFalse(sut.invokedAsyncStreamProcessParameter?.1 === logContextMock) + XCTAssertEqual( + results.compactMap { $0.castToMockError() }, + expectedResults.compactMap { $0.castToMockError() } + ) + } + + func testCombineNode_thenNodeIsAsyncStreamCombineNode() { + // given - sut.process(expectedInput, logContext: logContextMock) + let sut = AsyncStreamNodeMock() + + // when - await fulfillment(of: [expectation1, expectation2], timeout: 0.1) + let node = sut.combineNode() // then - XCTAssertEqual(nodeMock.invokedAsyncStreamProcessCount, 1) - XCTAssertEqual(nodeMock.invokedAsyncStreamProcessParameter, expectedInput) - XCTAssertEqual(results1.compactMap { $0.castToMockError() }, expectedResults) - XCTAssertEqual(results2.compactMap { $0.castToMockError() }, expectedResults) + XCTAssertTrue(node is AsyncStreamCombineNode) } } diff --git a/NodeKitTests/UnitTests/Node/Combine/AsyncNodeAdapterTests.swift b/NodeKitTests/UnitTests/Node/Combine/AsyncNodeAdapterTests.swift deleted file mode 100644 index e401af70..00000000 --- a/NodeKitTests/UnitTests/Node/Combine/AsyncNodeAdapterTests.swift +++ /dev/null @@ -1,103 +0,0 @@ -// -// AsyncNodeAdapterTests.swift -// NodeKitTests -// -// Created by Andrei Frolov on 29.03.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit -import XCTest - -final class AsyncNodeAdapterTests: XCTestCase { - - // MARK: - Dependencies - - private var nodeMock: AsyncNodeMock! - private var logContextMock: LoggingContextMock! - private var outputMock: NodeAdapterOutputMock! - - // MARK: - Sut - - private var sut: AsyncNodeAdapter! - - // MARK: - Lifecycle - - override func setUp() { - super.setUp() - nodeMock = AsyncNodeMock() - logContextMock = LoggingContextMock() - outputMock = NodeAdapterOutputMock() - sut = AsyncNodeAdapter(node: nodeMock) - } - - override func tearDown() { - super.tearDown() - sut = nil - outputMock = nil - logContextMock = nil - nodeMock = nil - } - - // MARK: - Tests - - func testProcess_whenSuccess_thenSuccessResultSentToSubject() async throws { - // given - - let expectation = expectation(description: "Method call") - let expectedResult: NodeResult = .success(6) - let expectedInput = 3 - - nodeMock.stubbedAsyncProccessResult = expectedResult - nodeMock.stubbedAsyncProcessRunFunction = { - expectation.fulfill() - } - - // when - - Task { - await sut.process(data: expectedInput, logContext: logContextMock, output: outputMock) - } - - await fulfillment(of: [expectation], timeout: 0.1) - - // then - - let unwrappedResult = try XCTUnwrap(outputMock.invokedSendParameter) - - XCTAssertEqual(nodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(nodeMock.invokedAsyncProcessParameter, expectedInput) - XCTAssertEqual(outputMock.invokedSendCount, 1) - XCTAssertEqual(unwrappedResult.castToMockError(), expectedResult.castToMockError()) - } - - func testProcess_whenFailure_thenFailureResultSentToSubject() async throws { - // given - - let expectation = expectation(description: "Method call") - let expectedResult: NodeResult = .failure(MockError.firstError) - let expectedInput = 10 - - nodeMock.stubbedAsyncProccessResult = expectedResult - nodeMock.stubbedAsyncProcessRunFunction = { - expectation.fulfill() - } - - // when - - Task { - await sut.process(data: expectedInput, logContext: logContextMock, output: outputMock) - } - - await fulfillment(of: [expectation], timeout: 0.1) - - // then - - let unwrappedResult = try XCTUnwrap(outputMock.invokedSendParameter) - - XCTAssertEqual(nodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(nodeMock.invokedAsyncProcessParameter, expectedInput) - XCTAssertEqual(outputMock.invokedSendCount, 1) - XCTAssertEqual(unwrappedResult.castToMockError(), expectedResult.castToMockError()) - } -} diff --git a/NodeKitTests/UnitTests/Node/Combine/AsyncStreamCombineNodeTests.swift b/NodeKitTests/UnitTests/Node/Combine/AsyncStreamCombineNodeTests.swift new file mode 100644 index 00000000..3f26bc2c --- /dev/null +++ b/NodeKitTests/UnitTests/Node/Combine/AsyncStreamCombineNodeTests.swift @@ -0,0 +1,229 @@ +// +// AsyncStreamCombineNodeTests.swift +// NodeKitTests +// +// Created by Andrei Frolov on 03.04.24. +// Copyright © 2024 Surf. All rights reserved. +// + +@testable import NodeKit +import Combine +import XCTest + +final class AsyncStreamCombineNodeTests: XCTestCase { + + // MARK: - Dependencies + + private var nodeMock: AsyncStreamNodeMock! + private var logContextMock: LoggingContextMock! + private var cancellable: Set! + + // MARK: - Sut + + private var sut: AsyncStreamCombineNode! + + // MARK: - Lifecycle + + override func setUp() { + super.setUp() + nodeMock = AsyncStreamNodeMock() + logContextMock = LoggingContextMock() + sut = AsyncStreamCombineNode(node: nodeMock) + cancellable = Set() + } + + override func tearDown() { + super.tearDown() + nodeMock = nil + logContextMock = nil + sut = nil + cancellable = Set() + } + + // MARK: - Tests + + func testProcess_withPublisherOnMainQueue_thenResultsReceivedOnMainQueue() async { + // given + + let expectation = expectation(description: "result") + + var isMainThread = false + + nodeMock.stubbedAsyncStreamProccessResult = { + AsyncStream { continuation in + continuation.yield(.success(100)) + continuation.finish() + } + } + + // when + + sut.nodeResultPublisher(on: DispatchQueue.main) + .sink(receiveValue: { value in + isMainThread = Thread.isMainThread + expectation.fulfill() + }) + .store(in: &cancellable) + + sut.process(12, logContext: logContextMock) + + await fulfillment(of: [expectation], timeout: 1) + + // then + + XCTAssertTrue(isMainThread) + } + + func testProcess_withPublisherOnCustom_thenResultsReceivedOnCustomQueue() async { + // given + + let expectation = expectation(description: "result") + let expectedLabel = "Test Process Queue" + let queue = DispatchQueue(label: expectedLabel) + + var isMainThread = false + var queueLabel: String? + + nodeMock.stubbedAsyncStreamProccessResult = { + AsyncStream { continuation in + continuation.yield(.success(100)) + continuation.finish() + } + } + + // when + + sut.nodeResultPublisher(on: queue) + .sink(receiveValue: { value in + isMainThread = Thread.isMainThread + queueLabel = DispatchQueue.currentLabel + expectation.fulfill() + }) + .store(in: &cancellable) + + sut.process(12, logContext: logContextMock) + + await fulfillment(of: [expectation], timeout: 1) + + // then + + XCTAssertFalse(isMainThread) + XCTAssertEqual(queueLabel, expectedLabel) + } + + func testProcess_thenResultsReceived() async { + // given + + let expectation = expectation(description: "result") + let expectedInput = 43 + + let expectedResults: [Result] = [ + .success(100), + .failure(MockError.firstError), + .failure(MockError.secondError), + .success(99), + .failure(MockError.thirdError) + ] + + var results: [NodeResult] = [] + + nodeMock.stubbedAsyncStreamProccessResult = { + AsyncStream { continuation in + expectedResults.forEach { continuation.yield($0) } + continuation.finish() + } + } + + // when + + sut.nodeResultPublisher(on: DispatchQueue.main) + .sink(receiveValue: { value in + results.append(value) + if results.count == expectedResults.count { + expectation.fulfill() + } + }) + .store(in: &cancellable) + + sut.process(expectedInput, logContext: logContextMock) + + await fulfillment(of: [expectation], timeout: 1) + + // then + + XCTAssertEqual(nodeMock.invokedAsyncStreamProcessCount, 1) + XCTAssertEqual(nodeMock.invokedAsyncStreamProcessParameter?.0, expectedInput) + XCTAssertTrue(nodeMock.invokedAsyncStreamProcessParameter?.1 === logContextMock) + XCTAssertEqual( + results.compactMap { $0.castToMockError() }, + expectedResults.compactMap { $0.castToMockError() } + ) + } + + func testProcess_withMultipleSubsciptions_thenResultsReceived() async { + // given + + let expectation1 = expectation(description: "result1") + let expectation2 = expectation(description: "result2") + let expectedInput = 42 + + let expectedResults: [Result] = [ + .success(500), + .failure(.secondError), + .success(1), + .failure(.secondError), + .failure(.thirdError) + ] + let nodeResults: [NodeResult] = expectedResults.map { res in res.mapError { $0 } } + + var results1: [NodeResult] = [] + var results2: [NodeResult] = [] + + nodeMock.stubbedAsyncStreamProccessResult = { + AsyncStream { continuation in + nodeResults.forEach { + continuation.yield($0) + } + continuation.finish() + } + } + + // when + + let multicast = sut.nodeResultPublisher(on: DispatchQueue.main) + .multicast { PassthroughSubject() } + + multicast + .sink(receiveValue: { value in + results1.append(value) + if results1.count == expectedResults.count { + expectation1.fulfill() + } + }) + .store(in: &cancellable) + + multicast + .sink(receiveValue: { value in + results2.append(value) + if results2.count == expectedResults.count { + expectation2.fulfill() + } + }) + .store(in: &cancellable) + + multicast.connect().store(in: &cancellable) + + sut.process(expectedInput, logContext: logContextMock) + + await fulfillment(of: [expectation1, expectation2], timeout: 1) + + // then + + XCTAssertEqual(nodeMock.invokedAsyncStreamProcessCount, 1) + XCTAssertEqual(nodeMock.invokedAsyncStreamProcessParameter?.0, expectedInput) + XCTAssertTrue(nodeMock.invokedAsyncStreamProcessParameter?.1 === logContextMock) + XCTAssertEqual(results1.compactMap { $0.castToMockError() }, expectedResults) + XCTAssertEqual(results2.compactMap { $0.castToMockError() }, expectedResults) + } + +} diff --git a/NodeKitTests/UnitTests/Node/Combine/AsyncStreamNodeAdapterTests.swift b/NodeKitTests/UnitTests/Node/Combine/AsyncStreamNodeAdapterTests.swift deleted file mode 100644 index 971e894e..00000000 --- a/NodeKitTests/UnitTests/Node/Combine/AsyncStreamNodeAdapterTests.swift +++ /dev/null @@ -1,161 +0,0 @@ -// -// AsyncStreamNodeAdapterTests.swift -// NodeKitTests -// -// Created by Andrei Frolov on 29.03.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit -import XCTest - -final class AsyncStreamNodeAdapterTests: XCTestCase { - - // MARK: - Dependencies - - private var nodeMock: AsyncStreamNodeMock! - private var logContextMock: LoggingContextMock! - private var outputMock: NodeAdapterOutputMock! - - // MARK: - Sut - - private var sut: AsyncStreamNodeAdapter! - - // MARK: - Lifecycle - - override func setUp() { - super.setUp() - nodeMock = AsyncStreamNodeMock() - logContextMock = LoggingContextMock() - outputMock = NodeAdapterOutputMock() - sut = AsyncStreamNodeAdapter(node: nodeMock) - } - - override func tearDown() { - super.tearDown() - sut = nil - outputMock = nil - logContextMock = nil - nodeMock = nil - } - - // MARK: - Tests - - func testProcess_whenSuccess_thenSuccessResultSentToSubject() async { - // given - - let expectation = expectation(description: "Method call") - let expectedResults: [NodeResult] = [.success(1), .success(3), .success(5)] - let expectedInput = 9 - - nodeMock.stubbedAsyncStreamProccessResult = AsyncStream { continuation in - expectedResults.forEach { value in - continuation.yield(value) - } - continuation.finish() - } - nodeMock.stubbedAsyncStreamProcessRunFunction = { - expectation.fulfill() - } - - // when - - Task { - await sut.process(data: expectedInput, logContext: logContextMock, output: outputMock) - } - - await fulfillment(of: [expectation], timeout: 0.1) - - // then - - let invokedOutputParameters = outputMock.invokedSendParameterList.compactMap { $0.castToMockError() } - - XCTAssertEqual(nodeMock.invokedAsyncStreamProcessCount, 1) - XCTAssertEqual(nodeMock.invokedAsyncStreamProcessParameter, expectedInput) - XCTAssertEqual(outputMock.invokedSendCount, expectedResults.count) - XCTAssertEqual(outputMock.invokedSendParameterList.count, expectedResults.count) - XCTAssertEqual(invokedOutputParameters, expectedResults.compactMap { $0.castToMockError() }) - } - - func testProcess_whenFailure_thenFailureResultSentToSubject() async { - // given - - let expectation = expectation(description: "Method call") - let expectedResults: [NodeResult] = [ - .failure(MockError.firstError), - .failure(MockError.thirdError), - .failure(MockError.secondError) - ] - let expectedInput = 8 - - nodeMock.stubbedAsyncStreamProccessResult = AsyncStream { continuation in - expectedResults.forEach { value in - continuation.yield(value) - } - continuation.finish() - } - nodeMock.stubbedAsyncStreamProcessRunFunction = { - expectation.fulfill() - } - - // when - - Task { - await sut.process(data: expectedInput, logContext: logContextMock, output: outputMock) - } - - await fulfillment(of: [expectation], timeout: 0.1) - - // then - - let invokedOutputParameters = outputMock.invokedSendParameterList.compactMap { $0.castToMockError() } - - XCTAssertEqual(nodeMock.invokedAsyncStreamProcessCount, 1) - XCTAssertEqual(nodeMock.invokedAsyncStreamProcessParameter, expectedInput) - XCTAssertEqual(outputMock.invokedSendCount, expectedResults.count) - XCTAssertEqual(outputMock.invokedSendParameterList.count, expectedResults.count) - XCTAssertEqual(invokedOutputParameters, expectedResults.compactMap { $0.castToMockError() }) - } - - func testProcess_whenSuccessWithFailure_thenSuccessWithFailureResultSentToSubject() async { - // given - - let expectation = expectation(description: "Method call") - let expectedResults: [Result] = [ - .success(5), - .failure(.secondError), - .success(2), - .failure(.thirdError) - ] - let nodeStub: [NodeResult] = expectedResults.map { res in res.mapError { $0 } } - let expectedInput = 7 - - nodeMock.stubbedAsyncStreamProccessResult = AsyncStream { continuation in - nodeStub.forEach { value in - continuation.yield(value) - } - continuation.finish() - } - nodeMock.stubbedAsyncStreamProcessRunFunction = { - expectation.fulfill() - } - - // when - - Task { - await sut.process(data: expectedInput, logContext: logContextMock, output: outputMock) - } - - await fulfillment(of: [expectation], timeout: 0.1) - - // then - - let invokedOutputParameters = outputMock.invokedSendParameterList.compactMap { $0.castToMockError() } - - XCTAssertEqual(nodeMock.invokedAsyncStreamProcessCount, 1) - XCTAssertEqual(nodeMock.invokedAsyncStreamProcessParameter, expectedInput) - XCTAssertEqual(outputMock.invokedSendCount, expectedResults.count) - XCTAssertEqual(outputMock.invokedSendParameterList.count, expectedResults.count) - XCTAssertEqual(invokedOutputParameters, expectedResults) - } -} diff --git a/NodeKitTests/UnitTests/Node/Combine/CombineCompatibleNodeTests.swift b/NodeKitTests/UnitTests/Node/Combine/CombineCompatibleNodeTests.swift deleted file mode 100644 index 62ebd3d5..00000000 --- a/NodeKitTests/UnitTests/Node/Combine/CombineCompatibleNodeTests.swift +++ /dev/null @@ -1,270 +0,0 @@ -// -// CombineCompatibleNodeTests.swift -// NodeKitTests -// -// Created by Andrei Frolov on 29.03.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit -import Combine -import XCTest - -final class CombineCompatibleNodeTests: XCTestCase { - - // MARK: - Dependencies - - private var adapterMock: NodeAdapterMock! - private var logContext: LoggingContextMock! - private var cancellable: Set! - - // MARK: - Sut - - private var sut: CombineCompatibleNode! - - // MARK: - Lifecycle - - override func setUp() { - super.setUp() - adapterMock = NodeAdapterMock() - cancellable = Set() - logContext = LoggingContextMock() - sut = CombineCompatibleNode(adapter: adapterMock) - } - - override func tearDown() { - super.tearDown() - adapterMock = nil - cancellable = nil - logContext = nil - sut = nil - } - - // MARK: - Tests - - func testProcess_withoutLogContext_thenAdapterCalled() async { - // given - - let expectation = expectation(description: "Method call") - let expectedInput = 2 - - adapterMock.stubbedAsyncProcessRunFunction = { - expectation.fulfill() - } - - // when - - Task { - sut.process(expectedInput) - } - - await fulfillment(of: [expectation], timeout: 0.1) - - // then - - XCTAssertEqual(adapterMock.invokedProcessCount, 1) - XCTAssertEqual(adapterMock.invokedProcessParameters?.data, expectedInput) - XCTAssertTrue(adapterMock.invokedProcessParameters?.output as? CombineCompatibleNode === sut) - } - - func testProcess_withLogContext_thenAdapterCalled() async { - // given - - let expectation = expectation(description: "Method call") - let expectedInput = 3 - - adapterMock.stubbedAsyncProcessRunFunction = { - expectation.fulfill() - } - - // when - - Task { - sut.process(expectedInput, logContext: logContext) - } - - await fulfillment(of: [expectation], timeout: 0.1) - - // then - - XCTAssertEqual(adapterMock.invokedProcessCount, 1) - XCTAssertEqual(adapterMock.invokedProcessParameters?.data, expectedInput) - XCTAssertTrue(adapterMock.invokedProcessParameters?.logContext === logContext) - XCTAssertTrue(adapterMock.invokedProcessParameters?.output as? CombineCompatibleNode === sut) - } - - func testSend_whenSuccess_thenSuccessResultReceived() async throws { - // given - - let expectation = expectation(description: "result") - let expectedResult = 10 - - var result: NodeResult? - var invokedCompletion = false - - // when - - sut.send(.success(10)) - sut.eraseToAnyPublisher() - .sink(receiveCompletion: { _ in - invokedCompletion = true - }, receiveValue: { value in - result = value - expectation.fulfill() - }) - .store(in: &cancellable) - - await fulfillment(of: [expectation], timeout: 0.3) - - // then - - let unwrappedResult = try XCTUnwrap(result) - - XCTAssertFalse(invokedCompletion) - - switch unwrappedResult { - case .success(let value): - XCTAssertEqual(value, expectedResult) - case .failure: - XCTFail("Неверный результат работы метода") - } - } - - func testSend_whenFailure_thenFailureResultReceived() async throws { - // given - - let expectation = expectation(description: "result") - - var result: NodeResult? - var invokedCompletion = false - - // when - - sut.send(.failure(MockError.thirdError)) - sut.eraseToAnyPublisher() - .sink(receiveCompletion: { _ in - invokedCompletion = true - }, receiveValue: { value in - result = value - expectation.fulfill() - }) - .store(in: &cancellable) - - await fulfillment(of: [expectation], timeout: 0.3) - - // then - - let unwrappedResult = try XCTUnwrap(result) - - XCTAssertFalse(invokedCompletion) - - switch unwrappedResult { - case .success: - XCTFail("Неверный результат работы метода") - case .failure(let error): - let unwrappedError = try XCTUnwrap(error as? MockError) - XCTAssertEqual(unwrappedError, .thirdError) - } - } - - @MainActor - func testSend_whenMultipleSubscribers_thenDataSent() async throws { - // given - - let expectation1 = expectation(description: "result1") - let expectation2 = expectation(description: "result2") - let expectation3 = expectation(description: "result3") - let expectedResults: [Result] = [ - .success(22), - .failure(MockError.firstError), - .success(21), - .failure(MockError.secondError) - ] - let nodeStub: [NodeResult] = expectedResults.map { res in res.mapError { $0 } } - - var invokedCompletion = false - var firstResults: [NodeResult] = [] - var secondResults: [NodeResult] = [] - var thirdResults: [NodeResult] = [] - - // when - - sut.eraseToAnyPublisher() - .sink(receiveCompletion: { _ in - invokedCompletion = true - }, receiveValue: { value in - firstResults.append(value) - if firstResults.count == expectedResults.count { - expectation1.fulfill() - } - }) - .store(in: &cancellable) - - sut.eraseToAnyPublisher() - .sink(receiveCompletion: { _ in - invokedCompletion = true - }, receiveValue: { value in - secondResults.append(value) - if secondResults.count == expectedResults.count { - expectation2.fulfill() - } - }) - .store(in: &cancellable) - - nodeStub.forEach { sut.send($0) } - - await Task { - try? await Task.sleep(nanoseconds: 100000000) - sut.eraseToAnyPublisher() - .sink(receiveCompletion: { _ in - invokedCompletion = true - }, receiveValue: { value in - thirdResults.append(value) - expectation3.fulfill() - }) - .store(in: &cancellable) - }.value - - await fulfillment(of: [expectation1, expectation2, expectation3], timeout: 0.3) - - // then - - let firstCastedResult = firstResults.compactMap { $0.castToMockError() } - let secondCastedResult = secondResults.compactMap { $0.castToMockError() } - let thirdCastedResult = thirdResults.compactMap { $0.castToMockError() } - - XCTAssertFalse(invokedCompletion) - XCTAssertEqual(firstCastedResult, expectedResults) - XCTAssertEqual(secondCastedResult, expectedResults) - XCTAssertEqual(thirdCastedResult, [.failure(MockError.secondError)]) - } - - func testEraseToAnyPublisher_withCustomQueue_thenQueueChanged() async { - // given - - let expectation = expectation(description: "result") - let expectedLabel = "Test Queue" - let expectedQueue = DispatchQueue(label: expectedLabel) - - var currentThread: Thread? - var dispatchQueueLabel: String? - - // when - - sut.send(.success(10)) - sut.eraseToAnyPublisher(queue: expectedQueue) - .sink(receiveValue: { value in - currentThread = Thread.current - dispatchQueueLabel = DispatchQueue.currentLabel - expectation.fulfill() - }) - .store(in: &cancellable) - - await fulfillment(of: [expectation], timeout: 0.3) - - // then - - XCTAssertEqual(currentThread?.isMainThread, false) - XCTAssertEqual(dispatchQueueLabel, expectedLabel) - } -} diff --git a/NodeKitTests/UnitTests/Node/Combine/CombineNodeTests.swift b/NodeKitTests/UnitTests/Node/Combine/CombineNodeTests.swift new file mode 100644 index 00000000..59ec3dcb --- /dev/null +++ b/NodeKitTests/UnitTests/Node/Combine/CombineNodeTests.swift @@ -0,0 +1,113 @@ +// +// CombineNodeTests.swift +// NodeKitTests +// +// Created by Andrei Frolov on 03.04.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Combine +import XCTest + +final class CombineNodeTests: XCTestCase { + + // MARK: - Tests + + func testNodeResultPublisher_withVoid_thenMainMethodCalled() throws { + // given + + let sut: CombineNodeMock = makeSut() + sut.stubbedNodeResultPublisherResult = PassthroughSubject().eraseToAnyPublisher() + + // when + + _ = sut.nodeResultPublisher() + .sink(receiveValue: { _ in }) + + // then + + let parameters = try XCTUnwrap(sut.invokedNodeResultPublisherParameters) + let scheduler = try XCTUnwrap(parameters.scheduler as? DispatchQueue) + + XCTAssertEqual(sut.invokedNodeResultPublisherCount, 1) + XCTAssertEqual(scheduler, .main) + } + + func testNodeResultPublisher_withData_thenMainMethodCalled() throws { + // given + + let sut: CombineNodeMock = makeSut() + let expectedInput = 1 + + sut.stubbedNodeResultPublisherResult = PassthroughSubject().eraseToAnyPublisher() + + // when + + _ = sut.nodeResultPublisher(for: expectedInput) + .sink(receiveValue: { _ in }) + + // then + + let parameters = try XCTUnwrap(sut.invokedNodeResultPublisherParameters) + let scheduler = try XCTUnwrap(parameters.scheduler as? DispatchQueue) + + XCTAssertEqual(sut.invokedNodeResultPublisherCount, 1) + XCTAssertEqual(parameters.input, expectedInput) + XCTAssertEqual(scheduler, .main) + } + + func testNodeResultPublisher_withData_onCustomQueue_thenMainMethodCalled() throws { + // given + + let sut: CombineNodeMock = makeSut() + let expectedInput = 1 + let queue = DispatchQueue(label: "Test Process Queue") + + sut.stubbedNodeResultPublisherResult = PassthroughSubject().eraseToAnyPublisher() + + // when + + _ = sut.nodeResultPublisher(for: expectedInput, on: queue) + .sink(receiveValue: { _ in }) + + // then + + let parameters = try XCTUnwrap(sut.invokedNodeResultPublisherParameters) + let scheduler = try XCTUnwrap(parameters.scheduler as? DispatchQueue) + + XCTAssertEqual(sut.invokedNodeResultPublisherCount, 1) + XCTAssertEqual(parameters.input, expectedInput) + XCTAssertEqual(scheduler, queue) + } + + func testNodeResultPublisher_withData_andLogContext_thenMainMethodCalled() throws { + // given + + let sut: CombineNodeMock = makeSut() + let logContextMock = LoggingContextMock() + let expectedInput = 3 + + sut.stubbedNodeResultPublisherResult = PassthroughSubject().eraseToAnyPublisher() + + // when + + _ = sut.nodeResultPublisher(for: expectedInput, logContext: logContextMock) + .sink(receiveValue: { _ in }) + + // then + + let parameters = try XCTUnwrap(sut.invokedNodeResultPublisherParameters) + let scheduler = try XCTUnwrap(parameters.scheduler as? DispatchQueue) + + XCTAssertEqual(sut.invokedNodeResultPublisherCount, 1) + XCTAssertEqual(parameters.input, expectedInput) + XCTAssertEqual(scheduler, .main) + XCTAssertTrue(parameters.logContext === logContextMock) + } + + // MARK: - Private Methods + + private func makeSut() -> CombineNodeMock { + return CombineNodeMock() + } +} diff --git a/NodeKitTests/UnitTests/Node/Combine/CombineStreamNodeTests.swift b/NodeKitTests/UnitTests/Node/Combine/CombineStreamNodeTests.swift new file mode 100644 index 00000000..0c5125e3 --- /dev/null +++ b/NodeKitTests/UnitTests/Node/Combine/CombineStreamNodeTests.swift @@ -0,0 +1,71 @@ +// +// CombineStreamNodeTests.swift +// NodeKitTests +// +// Created by Andrei Frolov on 03.04.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Combine +import XCTest + +final class CombineStreamNodeTests: XCTestCase { + + // MARK: - Tests + + func testPrcess_withVoid_thenMainMethodCalled() { + // given + + let sut: CombineStreamNodeMock = makeSut() + + // when + + sut.process() + + // then + + XCTAssertEqual(sut.invokedProcessCount, 1) + } + + func testPrcess_withData_thenMainMethodCalled() { + // given + + let sut: CombineStreamNodeMock = makeSut() + let expectedInput = 15 + + // when + + sut.process(expectedInput) + + // then + + XCTAssertEqual(sut.invokedProcessCount, 1) + XCTAssertEqual(sut.invokedProcessParameters?.0, expectedInput) + } + + func testNodeResultPublisher_thenMainMethodCalled() throws { + // given + + let sut: CombineStreamNodeMock = makeSut() + + sut.stubbedNodeResultPublisherResult = PassthroughSubject().eraseToAnyPublisher() + + // when + + _ = sut.nodeResultPublisher + + // then + + let parameter = try XCTUnwrap(sut.invokedNodeResultPublisherParameter) + let scheduler = try XCTUnwrap(parameter as? DispatchQueue) + + XCTAssertEqual(sut.invokedNodeResultPublisherCount, 1) + XCTAssertEqual(scheduler, .main) + } + + // MARK: - Private Methods + + private func makeSut() -> CombineStreamNodeMock { + return CombineStreamNodeMock() + } +} diff --git a/NodeKitTests/UnitTests/Node/Mocks/AsyncNodeMock.swift b/NodeKitTests/UnitTests/Node/Mocks/AsyncNodeMock.swift index 8aec528f..d2ef1bf5 100644 --- a/NodeKitTests/UnitTests/Node/Mocks/AsyncNodeMock.swift +++ b/NodeKitTests/UnitTests/Node/Mocks/AsyncNodeMock.swift @@ -7,35 +7,36 @@ // @testable import NodeKit +import Combine -final class AsyncNodeMock: AsyncNode { +class AsyncNodeMock: AsyncNode { - var invokedProcess = false - var invokedProcessCount = 0 - var invokedProcessParameter: Input? - var invokedProcessParameterList: [Input] = [] - var stubbedProccessResult: Observer! + var invokedProcessLegacy = false + var invokedProcessLegacyCount = 0 + var invokedProcessLegacyParameter: Input? + var invokedProcessLegacyParameterList: [Input] = [] + var stubbedProccessLegacyResult: Observer! - func process(_ data: Input) -> Observer { - invokedProcess = true - invokedProcessCount += 1 - invokedProcessParameter = data - invokedProcessParameterList.append(data) - return stubbedProccessResult + func processLegacy(_ data: Input) -> Observer { + invokedProcessLegacy = true + invokedProcessLegacyCount += 1 + invokedProcessLegacyParameter = data + invokedProcessLegacyParameterList.append(data) + return stubbedProccessLegacyResult } var invokedAsyncProcess = false var invokedAsyncProcessCount = 0 - var invokedAsyncProcessParameter: Input? - var invokedAsyncProcessParameterList: [Input] = [] + var invokedAsyncProcessParameter: (Input, LoggingContextProtocol)? + var invokedAsyncProcessParameterList: [(Input, LoggingContextProtocol)] = [] var stubbedAsyncProccessResult: NodeResult! var stubbedAsyncProcessRunFunction: (() async -> Void)? - func process(_ data: Input, logContext: any LoggingContextProtocol) async -> NodeResult { + func process(_ data: Input, logContext: LoggingContextProtocol) async -> NodeResult { invokedAsyncProcess = true invokedAsyncProcessCount += 1 - invokedAsyncProcessParameter = data - invokedAsyncProcessParameterList.append(data) + invokedAsyncProcessParameter = (data, logContext) + invokedAsyncProcessParameterList.append((data, logContext)) if let function = stubbedAsyncProcessRunFunction { await function() } diff --git a/NodeKitTests/UnitTests/Node/Mocks/AsyncStreamNodeMock.swift b/NodeKitTests/UnitTests/Node/Mocks/AsyncStreamNodeMock.swift index d2182f3f..7e3c7ca3 100644 --- a/NodeKitTests/UnitTests/Node/Mocks/AsyncStreamNodeMock.swift +++ b/NodeKitTests/UnitTests/Node/Mocks/AsyncStreamNodeMock.swift @@ -8,37 +8,37 @@ @testable import NodeKit -final class AsyncStreamNodeMock: AsyncStreamNode { +class AsyncStreamNodeMock: AsyncStreamNode { - var invokedProcess = false - var invokedProcessCount = 0 - var invokedProcessParameter: Input? - var invokedProcessParameterList: [Input] = [] - var stubbedProccessResult: Observer! + var invokedProcessLegacy = false + var invokedProcessLegacyCount = 0 + var invokedProcessLegacyParameter: Input? + var invokedProcessLegacyParameterList: [Input] = [] + var stubbedProccessLegacyResult: Observer! - func process(_ data: Input) -> Observer { - invokedProcess = true - invokedProcessCount += 1 - invokedProcessParameter = data - invokedProcessParameterList.append(data) - return stubbedProccessResult + func processLegacy(_ data: Input) -> Observer { + invokedProcessLegacy = true + invokedProcessLegacyCount += 1 + invokedProcessLegacyParameter = data + invokedProcessLegacyParameterList.append(data) + return stubbedProccessLegacyResult } var invokedAsyncStreamProcess = false var invokedAsyncStreamProcessCount = 0 - var invokedAsyncStreamProcessParameter: Input? - var invokedAsyncStreamProcessParameterList: [Input] = [] - var stubbedAsyncStreamProccessResult: AsyncStream>! + var invokedAsyncStreamProcessParameter: (Input, LoggingContextProtocol)? + var invokedAsyncStreamProcessParameterList: [(Input, LoggingContextProtocol)] = [] + var stubbedAsyncStreamProccessResult: (() -> AsyncStream>)! var stubbedAsyncStreamProcessRunFunction: (() -> Void)? func process(_ data: Input, logContext: LoggingContextProtocol) -> AsyncStream> { invokedAsyncStreamProcess = true invokedAsyncStreamProcessCount += 1 - invokedAsyncStreamProcessParameter = data - invokedAsyncStreamProcessParameterList.append(data) + invokedAsyncStreamProcessParameter = (data, logContext) + invokedAsyncStreamProcessParameterList.append((data, logContext)) if let function = stubbedAsyncStreamProcessRunFunction { function() } - return stubbedAsyncStreamProccessResult + return stubbedAsyncStreamProccessResult() } } diff --git a/NodeKitTests/UnitTests/Node/Mocks/CombineNodeMock.swift b/NodeKitTests/UnitTests/Node/Mocks/CombineNodeMock.swift new file mode 100644 index 00000000..443fe209 --- /dev/null +++ b/NodeKitTests/UnitTests/Node/Mocks/CombineNodeMock.swift @@ -0,0 +1,48 @@ +// +// CombineNodeMock.swift +// NodeKitTests +// +// Created by Andrei Frolov on 03.04.24. +// Copyright © 2024 Surf. All rights reserved. +// + +@testable import NodeKit +import Combine + +final class CombineNodeMock: CombineNode { + + struct NodeResultPublisherParameters { + let input: Input + let scheduler: any Scheduler + let logContext: LoggingContextProtocol + } + + var invokedNodeResultPublisher = false + var invokedNodeResultPublisherCount = 0 + var invokedNodeResultPublisherParameters: NodeResultPublisherParameters? + var invokedNodeResultPublisherParametersList: [NodeResultPublisherParameters] = [] + var stubbedNodeResultPublisherResult: AnyPublisher, Never>! + + func nodeResultPublisher(for data: Input, on scheduler: some Scheduler, logContext: LoggingContextProtocol) -> AnyPublisher, Never> { + let results = NodeResultPublisherParameters(input: data, scheduler: scheduler, logContext: logContext) + invokedNodeResultPublisher = true + invokedNodeResultPublisherCount += 1 + invokedNodeResultPublisherParameters = results + invokedNodeResultPublisherParametersList.append(results) + return stubbedNodeResultPublisherResult + } + + var invokedProcessLegacy = false + var invokedProcessLegacyCount = 0 + var invokedProcessLegacyParameter: Input? + var invokedProcessLegacyParameterList: [Input] = [] + var stubbedProccessLegacyResult: Observer! + + func processLegacy(_ data: Input) -> Observer { + invokedProcessLegacy = true + invokedProcessLegacyCount += 1 + invokedProcessLegacyParameter = data + invokedProcessLegacyParameterList.append(data) + return stubbedProccessLegacyResult + } +} diff --git a/NodeKitTests/UnitTests/Node/Mocks/CombineStreamNodeMock.swift b/NodeKitTests/UnitTests/Node/Mocks/CombineStreamNodeMock.swift new file mode 100644 index 00000000..47e5a231 --- /dev/null +++ b/NodeKitTests/UnitTests/Node/Mocks/CombineStreamNodeMock.swift @@ -0,0 +1,53 @@ +// +// CombineStreamNodeMock.swift +// NodeKitTests +// +// Created by Andrei Frolov on 03.04.24. +// Copyright © 2024 Surf. All rights reserved. +// + +@testable import NodeKit +import Combine + +final class CombineStreamNodeMock: CombineStreamNode { + + var invokedNodeResultPublisher = false + var invokedNodeResultPublisherCount = 0 + var invokedNodeResultPublisherParameter: (any Scheduler)? + var invokedNodeResultPublisherParameterList: [any Scheduler] = [] + var stubbedNodeResultPublisherResult: AnyPublisher, Never>! + + func nodeResultPublisher(on scheduler: some Scheduler) -> AnyPublisher, Never> { + invokedNodeResultPublisher = true + invokedNodeResultPublisherCount += 1 + invokedNodeResultPublisherParameter = scheduler + invokedNodeResultPublisherParameterList.append(scheduler) + return stubbedNodeResultPublisherResult + } + + var invokedProcess = false + var invokedProcessCount = 0 + var invokedProcessParameters: (Input, LoggingContextProtocol)? + var invokedProcessParameterList: [(Input, LoggingContextProtocol)] = [] + + func process(_ data: Input, logContext: LoggingContextProtocol) { + invokedProcess = true + invokedProcessCount += 1 + invokedProcessParameters = (data, logContext) + invokedProcessParameterList.append((data, logContext)) + } + + var invokedProcessLegacy = false + var invokedProcessLegacyCount = 0 + var invokedProcessLegacyParameter: Input? + var invokedProcessLegacyParameterList: [Input] = [] + var stubbedProccessLegacyResult: Observer! + + func processLegacy(_ data: Input) -> Observer { + invokedProcessLegacy = true + invokedProcessLegacyCount += 1 + invokedProcessLegacyParameter = data + invokedProcessLegacyParameterList.append(data) + return stubbedProccessLegacyResult + } +} diff --git a/NodeKitTests/UnitTests/Node/Mocks/NodeAdapterMock.swift b/NodeKitTests/UnitTests/Node/Mocks/NodeAdapterMock.swift deleted file mode 100644 index eabca775..00000000 --- a/NodeKitTests/UnitTests/Node/Mocks/NodeAdapterMock.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// NodeAdapterMock.swift -// NodeKitTests -// -// Created by Andrei Frolov on 31.03.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit - -final class NodeAdapterMock: NodeAdapter { - - struct Parameters { - let data: Input - let logContext: LoggingContextProtocol - let output: any NodeAdapterOutput - } - - var invokedProcess = false - var invokedProcessCount = 0 - var invokedProcessParameters: Parameters? - var stubbedAsyncProcessRunFunction: (() async -> Void)? - var inbokedProcessParametersList: [Parameters] = [] - - func process( - data: Input, - logContext: LoggingContextProtocol, - output: some NodeAdapterOutput - ) async { - invokedProcess = true - invokedProcessCount += 1 - invokedProcessParameters = Parameters(data: data, logContext: logContext, output: output) - inbokedProcessParametersList.append(Parameters(data: data, logContext: logContext, output: output)) - if let function = stubbedAsyncProcessRunFunction { - await function() - } - } -} diff --git a/NodeKitTests/UnitTests/Node/Mocks/NodeAdapterOutputMock.swift b/NodeKitTests/UnitTests/Node/Mocks/NodeAdapterOutputMock.swift deleted file mode 100644 index ad10db2d..00000000 --- a/NodeKitTests/UnitTests/Node/Mocks/NodeAdapterOutputMock.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// NodeAdapterOutputMock.swift -// NodeKitTests -// -// Created by Andrei Frolov on 29.03.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit - -final class NodeAdapterOutputMock: NodeAdapterOutput { - - var invokedSend = false - var invokedSendCount = 0 - var invokedSendParameter: NodeResult? - var invokedSendParameterList: [NodeResult] = [] - - func send(_ value: NodeResult) { - invokedSend = true - invokedSendCount += 1 - invokedSendParameter = value - invokedSendParameterList.append(value) - } -} diff --git a/NodeKitTests/UnitTests/Node/NodeResultTests.swift b/NodeKitTests/UnitTests/Node/NodeResultTests.swift new file mode 100644 index 00000000..a53334db --- /dev/null +++ b/NodeKitTests/UnitTests/Node/NodeResultTests.swift @@ -0,0 +1,304 @@ +// +// NodeResultTests.swift +// NodeKitTests +// +// Created by Andrei Frolov on 03.04.24. +// Copyright © 2024 Surf. All rights reserved. +// + +@testable import NodeKit +import XCTest + +final class NodeResultTests: XCTestCase { + + // MARK: - Tests + + func testAsyncFlatMap_whenSucess_thenSucessReceived() async { + // given + + let sut: NodeResult = .success(15) + let expectedResult: NodeResult = .success(21) + + // when + + let result = await sut.asyncFlatMap { value in + return expectedResult + } + + // then + + XCTAssertEqual(result.castToMockError(), expectedResult.castToMockError()) + } + + func testAsyncFlatMap_whenSucess_andTrasformToError_thenErrorReceived() async { + // given + + let sut: NodeResult = .success(15) + let expectedResult: NodeResult = .failure(MockError.firstError) + + // when + + let result = await sut.asyncFlatMap { value in + return expectedResult + } + + // then + + XCTAssertEqual(result.castToMockError(), expectedResult.castToMockError()) + } + + func testAsyncFlatMap_whenFailure_thenTransformIgnored() async { + // given + + let sut: NodeResult = .failure(MockError.thirdError) + + // when + + let result = await sut.asyncFlatMap { value in + return .success(21) + } + + // then + + XCTAssertEqual(result.castToMockError(), sut.castToMockError()) + } + + func testAsyncFlatMapError_whenFailure_thenFailureReceived() async { + // given + + let sut: NodeResult = .failure(MockError.secondError) + let expectedResult: NodeResult = .failure(MockError.firstError) + + // when + + let result = await sut.asyncFlatMapError { value in + return expectedResult + } + + // then + + XCTAssertEqual(result.castToMockError(), expectedResult.castToMockError()) + } + + func testAsyncFlatMapError_whenFailure_andTransformToSuccess_thenSuccessReceived() async { + // given + + let sut: NodeResult = .failure(MockError.secondError) + let expectedResult: NodeResult = .success(121) + + // when + + let result = await sut.asyncFlatMapError { value in + return expectedResult + } + + // then + + XCTAssertEqual(result.castToMockError(), expectedResult.castToMockError()) + } + + func testAsyncFlatMapError_whenSuccess_thenTransformIgnored() async { + // given + + let sut: NodeResult = .success(156) + + // when + + let result = await sut.asyncFlatMapError { value in + return .failure(MockError.secondError) + } + + // then + + XCTAssertEqual(result.castToMockError(), sut.castToMockError()) + } + + func testMap_whenSucess_thenNewValueReceived() { + // given + + let sut: NodeResult = .success(15) + let expectedResult = 200 + + var transform = { (value: Int) throws -> Int in + return expectedResult + } + + // when + + let result = try? sut.map(transform) + + // then + + XCTAssertEqual(result?.castToMockError(), .success(expectedResult)) + } + + func testMap_whenSucess_andTrasformThrowsError_thenErrorReceived() throws { + // given + + let sut: NodeResult = .success(15) + let expectedResult = MockError.secondError + + var transform = { (value: Int) throws -> Int in + throw expectedResult + } + + var receivedError: Error? + + // when + + do { + _ = try sut.map(transform) + } catch { + receivedError = error + } + + // then + + let custedError = try XCTUnwrap(receivedError as? MockError) + + XCTAssertEqual(custedError, expectedResult) + } + + func testMap_whenFailure_thenTransformIgnored() async { + // given + + let sut: NodeResult = .failure(MockError.thirdError) + + var transform = { (value: Int) throws -> Int in + return 221 + } + + // when + + let result = try? sut.map(transform) + + // then + + XCTAssertEqual(result?.castToMockError(), sut.castToMockError()) + } + + func testWithMappedExceptions_withSuccessValue_thenSuccessReceived() async { + // given + + let expectedResult: NodeResult = .success(91) + + // then + + let result = await NodeResult.withMappedExceptions { + return expectedResult + } + + // then + + XCTAssertEqual(result.castToMockError(), expectedResult.castToMockError()) + } + + func testWithMappedExceptions_withFailureValue_thenFailureReceived() async { + // given + + let expectedResult: NodeResult = .failure(MockError.firstError) + // then + + let result = await NodeResult.withMappedExceptions { + return expectedResult + } + + // then + + XCTAssertEqual(result.castToMockError(), expectedResult.castToMockError()) + } + + func testWithMappedExceptions_withErrorThrows_thenFailureReceived() async { + // given + + let expectedError = MockError.firstError + + var function = { () throws -> NodeResult in + throw expectedError + } + + // then + + let result = await NodeResult.withMappedExceptions(nil, function) + + // then + + XCTAssertEqual(result.castToMockError(), .failure(expectedError)) + } + + func testWithMappedExceptions_withErrorThrows_andCustomError_thenFailureReceived() async { + // given + + let expectedError = MockError.thirdError + + var function = { () throws -> NodeResult in + throw MockError.secondError + } + + // then + + let result = await NodeResult.withMappedExceptions(expectedError, function) + + // then + + XCTAssertEqual(result.castToMockError(), .failure(expectedError)) + } + + func testValue_whenSuccess_thenValueReceived() { + // given + + let expectedResult = 156 + let sut: NodeResult = .success(expectedResult) + + // when + + let result = sut.value + + // then + + XCTAssertEqual(result, expectedResult) + } + + func testValue_whenFailure_thenNilReceived() { + // given + + let sut: NodeResult = .failure(MockError.secondError) + + // when + + let result = sut.value + + // then + + XCTAssertNil(result) + } + + func testError_whenFailure_thenErrorReceived() { + // given + + let expectedError = MockError.secondError + let sut: NodeResult = .failure(expectedError) + + // when + + let result = sut.error as? MockError + + // then + + XCTAssertEqual(result, expectedError) + } + + func testError_whenSuccess_thenNilReceived() { + // given + + let sut: NodeResult = .success(201) + + // when + + let result = sut.error + + // then + + XCTAssertNil(result) + } +} diff --git a/NodeKitTests/UnitTests/RequestBuildingLayer/URLQueryInjectorNodeTests.swift b/NodeKitTests/UnitTests/RequestBuildingLayer/URLQueryInjectorNodeTests.swift index fcbadc3a..69c73b4d 100644 --- a/NodeKitTests/UnitTests/RequestBuildingLayer/URLQueryInjectorNodeTests.swift +++ b/NodeKitTests/UnitTests/RequestBuildingLayer/URLQueryInjectorNodeTests.swift @@ -10,7 +10,7 @@ public class URLQueryInjectorNodeTests: XCTestCase { typealias Model = RoutableRequestModel class StubNode: AsyncNode { - func process(_ data: Model) -> Observer { + func processLegacy(_ data: Model) -> Observer { return .emit(data: data) } @@ -38,7 +38,7 @@ public class URLQueryInjectorNodeTests: XCTestCase { var result: URL! - node.process(request).onCompleted { result = try! $0.route.url() } + node.processLegacy(request).onCompleted { result = try! $0.route.url() } // Assert @@ -59,7 +59,7 @@ public class URLQueryInjectorNodeTests: XCTestCase { var result: URL! - node.process(request).onCompleted { result = try! $0.route.url() } + node.processLegacy(request).onCompleted { result = try! $0.route.url() } // Assert @@ -83,7 +83,7 @@ public class URLQueryInjectorNodeTests: XCTestCase { var result: URL! - node.process(request).onCompleted { result = try! $0.route.url() } + node.processLegacy(request).onCompleted { result = try! $0.route.url() } // Assert @@ -109,7 +109,7 @@ public class URLQueryInjectorNodeTests: XCTestCase { var result: Model! - node.process(request).onCompleted { result = $0 } + node.processLegacy(request).onCompleted { result = $0 } // Assert @@ -132,7 +132,7 @@ public class URLQueryInjectorNodeTests: XCTestCase { var result: URL! - node.process(request).onCompleted { result = try! $0.route.url() } + node.processLegacy(request).onCompleted { result = try! $0.route.url() } // Assert @@ -156,7 +156,7 @@ public class URLQueryInjectorNodeTests: XCTestCase { var result: URL! - node.process(request).onCompleted { result = try! $0.route.url() } + node.processLegacy(request).onCompleted { result = try! $0.route.url() } // Assert @@ -180,7 +180,7 @@ public class URLQueryInjectorNodeTests: XCTestCase { var result: URL! - node.process(request).onCompleted { result = try! $0.route.url() } + node.processLegacy(request).onCompleted { result = try! $0.route.url() } // Assert @@ -204,7 +204,7 @@ public class URLQueryInjectorNodeTests: XCTestCase { var result: URL! - node.process(request).onCompleted { result = try! $0.route.url() } + node.processLegacy(request).onCompleted { result = try! $0.route.url() } // Assert diff --git a/NodeKitTests/UnitTests/TokenRefresher/TokenRefresherNodeTests.swift b/NodeKitTests/UnitTests/TokenRefresher/TokenRefresherNodeTests.swift index 59760ae5..cde5dd71 100644 --- a/NodeKitTests/UnitTests/TokenRefresher/TokenRefresherNodeTests.swift +++ b/NodeKitTests/UnitTests/TokenRefresher/TokenRefresherNodeTests.swift @@ -59,13 +59,13 @@ public class TokenRefresherNodeTests: XCTestCase { for _ in 0..() - tokenRefreshChainMock.stubbedProccessResult = context + tokenRefreshChainMock.stubbedProccessLegacyResult = context DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1)) { context.emit(data: ()) }