From acd7a3cc807bdd5a54a12de9852d6c5a34c16a6a Mon Sep 17 00:00:00 2001 From: Tommaso Madonia Date: Thu, 7 Sep 2023 21:20:13 +0100 Subject: [PATCH 1/2] MobiusExtras: Add compactMap operation to Connectable --- .../Source/ConnectableCompactMap.swift | 30 +++++++++ .../Test/ConnectableCompactMapTests.swift | 66 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 MobiusExtras/Source/ConnectableCompactMap.swift create mode 100644 MobiusExtras/Test/ConnectableCompactMapTests.swift diff --git a/MobiusExtras/Source/ConnectableCompactMap.swift b/MobiusExtras/Source/ConnectableCompactMap.swift new file mode 100644 index 00000000..6427f00c --- /dev/null +++ b/MobiusExtras/Source/ConnectableCompactMap.swift @@ -0,0 +1,30 @@ +// Copyright 2019-2022 Spotify AB. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import MobiusCore + +public extension Connectable { + /// Transform the output type of this `Connectable` by applying the `transform` function to each output + /// and returning only the non-`nil` values. + /// + /// - Parameter transform: The function which should be used to transform the output of this `Connectable`. + /// - Returns: A `Connectable` which applies `transform` to each output value. + func compactMap(_ transform: @escaping (Output) -> NewOutput?) -> AnyConnectable { + AnyConnectable { dispatch in + self.connect { output in + transform(output).map(dispatch) + } + } + } +} diff --git a/MobiusExtras/Test/ConnectableCompactMapTests.swift b/MobiusExtras/Test/ConnectableCompactMapTests.swift new file mode 100644 index 00000000..0aac7beb --- /dev/null +++ b/MobiusExtras/Test/ConnectableCompactMapTests.swift @@ -0,0 +1,66 @@ +// Copyright 2019-2022 Spotify AB. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import MobiusCore +import MobiusExtras +import Nimble +import Quick + +final class ConnectableCompactMapTests: QuickSpec { + override func spec() { + context("Connectable Compact Map") { + it("applies the `transform` function to the output") { + var output: [Int] = [] + let connection = TestConnectable() + .compactMap { Int($0) } + .connect { + output.append($0) + } + + connection.accept("1") + connection.accept("A") + connection.accept("2") + connection.accept("B") + connection.accept("3") + connection.accept("C") + + expect(output).to(equal([1, 2, 3])) + + connection.dispose() + } + + it("preserves the connectable's `Disposable` conformance") { + let testConnectable = TestConnectable() + expect(testConnectable.isDisposed).to(beFalse()) + + testConnectable + .connect { _ in } + .dispose() + + expect(testConnectable.isDisposed).to(beTrue()) + } + } + } +} + +private final class TestConnectable: Connectable { + var isDisposed = false + + func connect(_ consumer: @escaping Consumer) -> Connection { + return Connection( + acceptClosure: consumer, + disposeClosure: { self.isDisposed = true } + ) + } +} From e18fde8cddd6988715cdfc39962d387da268e9be Mon Sep 17 00:00:00 2001 From: Tommaso Madonia Date: Thu, 7 Sep 2023 22:30:08 +0100 Subject: [PATCH 2/2] MobiusExtras: Fix tests --- MobiusExtras/Test/ConnectableCompactMapTests.swift | 1 + MobiusExtras/Test/ConnectableMapTests.swift | 1 + 2 files changed, 2 insertions(+) diff --git a/MobiusExtras/Test/ConnectableCompactMapTests.swift b/MobiusExtras/Test/ConnectableCompactMapTests.swift index 0aac7beb..35ef4079 100644 --- a/MobiusExtras/Test/ConnectableCompactMapTests.swift +++ b/MobiusExtras/Test/ConnectableCompactMapTests.swift @@ -45,6 +45,7 @@ final class ConnectableCompactMapTests: QuickSpec { expect(testConnectable.isDisposed).to(beFalse()) testConnectable + .compactMap { Int($0) } .connect { _ in } .dispose() diff --git a/MobiusExtras/Test/ConnectableMapTests.swift b/MobiusExtras/Test/ConnectableMapTests.swift index 48ff74b7..c8c29f59 100644 --- a/MobiusExtras/Test/ConnectableMapTests.swift +++ b/MobiusExtras/Test/ConnectableMapTests.swift @@ -42,6 +42,7 @@ class ConnectableMapTests: QuickSpec { expect(testConnectable.isDisposed).to(beFalse()) testConnectable + .map { Int($0) } .connect { _ in } .dispose()