diff --git a/StoryFlow/Flow/ImplicitFlow/ImplicitFlow.swift b/StoryFlow/Flow/ImplicitFlow/ImplicitFlow.swift index f58c469..997aa16 100644 --- a/StoryFlow/Flow/ImplicitFlow/ImplicitFlow.swift +++ b/StoryFlow/Flow/ImplicitFlow/ImplicitFlow.swift @@ -1,6 +1,31 @@ import Foundation import UIKit +extension Flow { + + /** + Returns view controller by matching type of provided `value` + + See [tests examples](https://github.com/trafi/StoryFlow/blob/master/StoryFlowTests/ImplicitFlowTests.swift). + + - Parameter value: The value being passed to next view controller. + */ + public static func destination(for value: Value) -> UIViewController? { + return destination(for: (value, Value.self)) + } + + private static func destination(for output: ValueAndType) -> UIViewController? { + let (value, type) = OutputTransform.apply(output) + + for inType in inputRequiringTypes where oneOf(inType._inputType, contains: type) { + return inType._create(input: value) + } + + return nil + } + +} + extension Flow { public static func implicit() -> Flow { @@ -24,9 +49,8 @@ extension Flow { } // MARK: Input - - for inType in inputRequiringTypes where oneOf(inType._inputType, contains: type) { - let to = inType._create(input: value) + + if let to = Flow.destination(for: output) { let transition = TransitionInfo(from: from, producedType: output.type, receivedType: type, to: to, isUnwind: false) if CustomTransition.attempt(transition) == false { from.show(to, sender: nil) diff --git a/StoryFlowTests/ImplicitFlowTests.swift b/StoryFlowTests/ImplicitFlowTests.swift index a47f790..aabe2d6 100644 --- a/StoryFlowTests/ImplicitFlowTests.swift +++ b/StoryFlowTests/ImplicitFlowTests.swift @@ -2,6 +2,41 @@ import XCTest import StoryFlow class ImplicitFlowTests: XCTestCase { + + // MARK: Destination + + func testDestination_itReturnsNilWhenNoVcFound() { + + // Arrange + class T {} + + let output = T() + + // Act + let destination = Flow.destination(for: output) + + // Assert + XCTAssert(destination == nil) + } + + + func testDestination_itReturnsVcWithInput() { + + // Arrange + class T {} + + class To: UIViewController, InputRequiring { typealias InputType = T } + + let output = T() + + // Act + let destination = Flow.destination(for: output) + + // Assert + XCTAssert(destination is To) + XCTAssert((destination as! To).input === output) + } + // MARK: Show @@ -483,6 +518,29 @@ class ImplicitFlowTests: XCTestCase { } // MARK: Output transforms + + func testDestination_itReturnsNextVcByTransformedOutput() { + + // Arrange + class T1 {} + class T2 {} + + class To: UIViewController, InputRequiring { typealias InputType = T2 } + + let transformedOutput = T2() + + OutputTransform.register { (_: T1) in transformedOutput } + + // Act + let destination = Flow.destination(for: T1()) + + // Assert + XCTAssert(destination is To) + XCTAssert((destination as! To).input === transformedOutput) + + // Clean up + OutputTransform.reset() + } func testProduce_itShowsNextVcByTransformedOutput() {