Skip to content

Commit

Permalink
Remove the need to type-erase publisher to render the workflow view
Browse files Browse the repository at this point in the history
  • Loading branch information
soorinpark committed Nov 3, 2021
1 parent 2b727df commit 1f971a8
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 54 deletions.
22 changes: 0 additions & 22 deletions Development.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ Pod::Spec.new do |s|
s.dependency 'WorkflowUI'
s.dependency 'WorkflowReactiveSwift'
s.dependency 'WorkflowRxSwift'
# s.dependency 'WorkflowCombine' # TODO: Disabled because app specs cannot increase the deployment target of the root
s.source_files = 'Samples/Dummy.swift'

s.subspec 'Dummy' do |ss|
Expand Down Expand Up @@ -142,25 +141,4 @@ Pod::Spec.new do |s|
test_spec.dependency 'WorkflowTesting'
test_spec.dependency 'WorkflowRxSwiftTesting'
end

# TODO: Disabled because app specs cannot increase the deployment target of the root
# To use, increase the deployment target of this spec to 13.0 or higher
# s.app_spec 'WorkflowCombineSampleApp' do |app_spec|
# app_spec.source_files = 'Samples/WorkflowCombineSampleApp/WorkflowCombineSampleApp/**/*.swift'
# end

# s.test_spec 'WorkflowCombineSampleAppTests' do |test_spec|
# test_spec.dependency 'Development/WorkflowCombineSampleApp'
# test_spec.requires_app_host = true
# test_spec.app_host_name = 'Development/WorkflowCombineSampleApp'
# test_spec.source_files = 'Samples/WorkflowCombineSampleApp/WorkflowCombineSampleAppUnitTests/**/*.swift'
# end
#
# s.test_spec 'WorkflowCombineTests' do |test_spec|
# test_spec.requires_app_host = true
# test_spec.source_files = 'WorkflowCombine/Tests/**/*.swift'
# test_spec.framework = 'XCTest'
# test_spec.dependency 'WorkflowTesting'
# test_spec.dependency 'WorkflowCombineTesting'
# end
end
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import Combine
import Workflow
import WorkflowCombine
import WorkflowUI

// MARK: Workers

Expand All @@ -17,7 +16,7 @@ extension DemoWorkflow {
typealias Output = Action

// This publisher publishes the current date on a timer that fires every second
func run() -> AnyPublisher<Action, Never> {
func run() -> AnyPublisher<Output, Never> {
Timer.publish(every: 1, on: .main, in: .common)
.autoconnect()
.map { Action(publishedDate: $0) }
Expand Down
34 changes: 34 additions & 0 deletions WorkflowCombine/Sources/Publisher+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// Publisher+Extensions.swift
// WorkflowCombine
//
// Created by Soo Rin Park on 11/3/21.
//

#if canImport(Combine) && swift(>=5.1)

import Combine
import Foundation
import Workflow

@available(iOS 13.0, macOS 10.15, *)
/// This is a workaround to the fact you extensions of protocols cannot have an inheritance clause.
/// a previous solution had extending the `AnyPublisher` to conform to `AnyWorkflowConvertible`,
/// but was limited in the fact that rendering was only available to `AnyPublisher`s.
/// this solutions makes it so that all publishers can render its view.
extension Publisher where Failure == Never {
public func running<Parent>(in context: RenderContext<Parent>, key: String = "") where
Output == AnyWorkflowAction<Parent> {
asAnyWorkflow().rendered(in: context, key: key, outputMap: { $0 })
}

public func mapOutput<NewOutput>(_ transform: @escaping (Output) -> NewOutput) -> AnyWorkflow<Void, NewOutput> {
asAnyWorkflow().mapOutput(transform)
}

func asAnyWorkflow() -> AnyWorkflow<Void, Output> {
PublisherWorkflow(publisher: self).asAnyWorkflow()
}
}

#endif
8 changes: 0 additions & 8 deletions WorkflowCombine/Sources/PublisherWorkflow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@
import Foundation
import Workflow

@available(iOS 13.0, macOS 10.15, *)

extension AnyPublisher: AnyWorkflowConvertible where Failure == Never {
public func asAnyWorkflow() -> AnyWorkflow<Void, Output> {
return PublisherWorkflow(publisher: self).asAnyWorkflow()
}
}

@available(iOS 13.0, macOS 10.15, *)
struct PublisherWorkflow<WorkflowPublisher: Publisher>: Workflow where WorkflowPublisher.Failure == Never {
public typealias Output = WorkflowPublisher.Output
Expand Down
1 change: 0 additions & 1 deletion WorkflowCombine/Sources/Worker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@
)
.map { AnyWorkflowAction<Self>(sendingOutput: $0) }
}
.eraseToAnyPublisher()
.running(in: context, key: state.uuidString)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
/// - Parameters:
/// - producingOutput: An output that should be returned when this worker is requested, if any.
/// - key: Key to expect this `Workflow` to be rendered with.
public func expectPublisher<OutputType>(
producingOutput output: OutputType? = nil,
key: String = "",
file: StaticString = #file, line: UInt = #line
) -> RenderTester<WorkflowType> {
public func expectPublisher<PublisherType: Publisher>(
publisher: PublisherType.Type,
output: PublisherType.Output,
key: String = ""
) -> RenderTester<WorkflowType> where PublisherType.Failure == Never {
expectWorkflow(
type: PublisherWorkflow<AnyPublisher<OutputType, Never>>.self,
type: PublisherWorkflow<PublisherType>.self,
key: key,
producingRendering: (),
producingOutput: output,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import Workflow
import XCTest
@testable import WorkflowCombine

class AnyPublisherTests: XCTestCase {
class PublisherTests: XCTestCase {
func testPublisherWorkflow() {
TestWorkflow()
.renderTester()
.expectPublisher(producingOutput: 1, key: "123")
.expectPublisher(publisher: Publishers.Sequence<[Int], Never>.self, output: 1, key: "123")
.render {}
}

Expand All @@ -34,22 +34,21 @@ class AnyPublisherTests: XCTestCase {

func render(state: State, context: RenderContext<Self>) -> Rendering {
[1].publisher
.eraseToAnyPublisher()
.mapOutput { _ in AnyWorkflowAction<TestWorkflow>.noAction }
.running(in: context, key: "123")
}
}

func test_publisherWorkflow_usesSideEffectWithKey() {
let publisher = Just(1).eraseToAnyPublisher()
let publisher = Just(1)
PublisherWorkflow(publisher: publisher)
.renderTester()
.expectSideEffect(key: "")
.render { _ in }
}

func test_output() {
let publisher = Just(1).eraseToAnyPublisher()
let publisher = Just(1)

let host = WorkflowHost(
workflow: PublisherWorkflow(publisher: publisher)
Expand All @@ -72,7 +71,7 @@ class AnyPublisherTests: XCTestCase {
let publisher = [1, 2, 3].publisher

let host = WorkflowHost(
workflow: PublisherWorkflow(publisher: publisher.eraseToAnyPublisher())
workflow: PublisherWorkflow(publisher: publisher)
)

let expectation = XCTestExpectation()
Expand Down
13 changes: 4 additions & 9 deletions WorkflowCombine/Tests/WorkerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,13 @@ class WorkerTests: XCTestCase {
}

struct TestWorker: Worker {
typealias Output = WorkerPublisher.Output
typealias WorkerPublisher = AnyPublisher<Int, Never>
typealias Output = Int

func isEquivalent(to otherWorker: TestWorker) -> Bool {
true
}

func run() -> WorkerPublisher {
func run() -> AnyPublisher<Int, Never> {
[1, 2].publisher
.delay(for: .milliseconds(1), scheduler: RunLoop.main)
.eraseToAnyPublisher()
Expand Down Expand Up @@ -194,11 +193,7 @@ private struct PublisherTestWorkflow: Workflow {

private struct PublisherTestWorker: Worker {
typealias Output = Int
func run() -> AnyPublisher<Int, Never> {
Just(1).eraseToAnyPublisher()
}
func run() -> Just<Int> { Just(1) }

func isEquivalent(to otherWorker: PublisherTestWorker) -> Bool {
true
}
func isEquivalent(to otherWorker: PublisherTestWorker) -> Bool { true }
}

0 comments on commit 1f971a8

Please sign in to comment.