-
Notifications
You must be signed in to change notification settings - Fork 25
Navigator
Facade type erasing the type of the underlying datasource
public struct Navigator
Testing helper
typealias DismissSuccessorInvocation = DismissInvocation
var invocations = [Navigator.DismissInvocation]()
let expectectedInvocations = [
Navigator.DismissInvocation(id: .id(expectedID))
]
let sut = Navigator.mock(
path: { self.path },
dismissSuccessor: { id in
invocations.append(.init(id: id))
}
)
sut.dismissSuccessor(of: expectedID) // invoke code that invokes dismissSuccessor(of:)
XCTAssertEqual(expectectedInvocations, invocations)
init(path:go:goToOnScreen:goToPath:goToPathOnScreen:goBack:goBackToID:replace:dismiss:dismissScreen:dismissSuccessor:dismissSuccessorOfScreen:didAppear:)
public init(path: @escaping () -> [IdentifiedScreen], go: @escaping (AnyScreen, ScreenID) -> Void, goToOnScreen: @escaping (AnyScreen, AnyScreen) -> Void, goToPath: @escaping ([AnyScreen], ScreenID) -> Void, goToPathOnScreen: @escaping ([AnyScreen], AnyScreen) -> Void, goBack: @escaping (AnyScreen) -> Void, goBackToID: @escaping (ScreenID) -> Void, replace: @escaping ([AnyScreen]) -> Void, dismiss: @escaping (ScreenID) -> Void, dismissScreen: @escaping (AnyScreen) -> Void, dismissSuccessor: @escaping (ScreenID) -> Void, dismissSuccessorOfScreen: @escaping (AnyScreen) -> Void, didAppear: @escaping (ScreenID) -> Void)
Initialises a Navigator wrapping a Datasource object
init(dataSource: Navigator.Datasource)
- dataSource: The wrapped data source
let stub
mock(path:go:goToOnScreen:goToPath:goToPathOnScreen:goBack:goBackToID:replace:dismiss:dismissScreen:dismissSuccessor:dismissSuccessorOfScreen:didAppear:)
static func mock(path: @escaping () -> [IdentifiedScreen] = {
fatalError("path() unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, go: @escaping (AnyScreen, ScreenID) -> Void = { _, _ in
fatalError("go(to:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, goToOnScreen: @escaping (AnyScreen, AnyScreen) -> Void = { _, _ in
fatalError("go(to:, on screen:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, goToPath: @escaping ([AnyScreen], ScreenID) -> Void = { _, _ in
fatalError("goTo(path:, to:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, goToPathOnScreen: @escaping ([AnyScreen], AnyScreen) -> Void = { _, _ in
fatalError("goTo(path:, to:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, goBack: @escaping (AnyScreen) -> Void = { _ in
fatalError("goBack(to:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, goBackToID: @escaping (ScreenID) -> Void = { _ in
fatalError("goBack(to:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, replace: @escaping ([AnyScreen]) -> Void = { _ in
fatalError("replace(path:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, dismiss: @escaping (ScreenID) -> Void = { _ in
fatalError("dismiss(id:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, dismissScreen: @escaping (AnyScreen) -> Void = { _ in
fatalError("dismiss(screen:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, dismissSuccessor: @escaping (ScreenID) -> Void = { _ in
fatalError("dismissSuccessor(of:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, dismissSuccessorOfScreen: @escaping (AnyScreen) -> Void = { _ in
fatalError("dismissSuccessor(of:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, didAppear: @escaping (ScreenID) -> Void = { _ in
fatalError("didAppear(id:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}) -> Navigator
mock(path:goToInvoked:goToPathInvoked:goBackToInvoked:replacePathInvoked:dismissInvoked:dismissSuccessorInvoked:didAppearInvoked:)
static func mock(path: @escaping () -> [IdentifiedScreen] = {
fatalError("path() unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, goToInvoked: @escaping (Navigator.GoToInvocation) -> Void = { _ in
fatalError("go(to screen:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, goToPathInvoked: @escaping (Navigator.GoToPathInvocation) -> Void = { _ in
fatalError("go(to path:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, goBackToInvoked: @escaping (Navigator.GoBackToInvocation) -> Void = { _ in
fatalError("goBack(to:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, replacePathInvoked: @escaping (Navigator.ReplacePathInvocation) -> Void = { _ in
fatalError("replace(path:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, dismissInvoked: @escaping (Navigator.DismissInvocation) -> Void = { _ in
fatalError("dismiss(id:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, dismissSuccessorInvoked: @escaping (Navigator.DismissSuccessorInvocation) -> Void = { _ in
fatalError("dismissSuccessor(of:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}, didAppearInvoked: @escaping (Navigator.DidAppearInvocation) -> Void = { _ in
fatalError("didAppear(id:) unimplemented in stub. Make sure to wrap your application in a Root view or inject Navigator via .environment(\\.navigator, navigator) for testing purposes.")
}) -> Navigator
Append a screen after a given ScreenID
.
public func go<S: Screen>(to screen: S, on id: ScreenID)
go(to:, on:)
appends the given screen after the screen associated with the passed ScreenID
. If you call go(to:, on:)
for a ScreenID
that is not associated with the last screen in the current routing path, the routing path after the ScreenID
is replaced with [screen]
and therefore cut off.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]
navigator.go(to: C(), on: 1)
// New path
// [(A, 0), (B, 1)], (C, 2)]
- screen: Destination
- id:
ScreenID
used to identify where the destination should be appended
Append a screen after a given Screen
.
public func go<S: Screen, Parent: Screen>(to screen: S, on parent: Parent)
go(to:, on:)
appends the given screen after the last occurrence of the passed Parent
screen object.
If you call go(to:, on:)
for a Screen
that is not associated with the last screen in the current routing path, the routing path after the Parent
is replaced with [screen]
and therefore cut off.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]
navigator.go(to: C(), on: B())
// New path
// [(A, 0), (B, 1)], (C, 2)]
- screen: Destination
- parent:
Parent
screen object used to identify where the destination should be appended
Append a screen after a given ScreenID
.
public func go<S: Screen>(to screen: S, on parent: AnyScreen)
go(to:, on:)
appends the given screen after the last occurrence of the passed Parent
screen object.
If you call go(to:, on:)
for a Screen
that is not associated with the last screen in the current routing path, the routing path after the Parent
is replaced with [screen]
and therefore cut off.
Most likely used in conjunction with @Environment(.currentScreen).
// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]
navigator.go(to: C(), on: B())
// New path
// [(A, 0), (B, 1)], (C, 2)]
- screen: Destination
- parent:
AnyScreen
screen object used to identify where the destination should be appended
Replace the path after a given ScreenID
with the passed path.
public func go(to path: [AnyScreen], on id: ScreenID)
go(to:, on:)
appends the given path after the screen associated with the passed ScreenID
. If you call go(to:, on:)
for a ScreenID
that is not associated with the last screen in the current routing path, the routing path after the ScreenID
is replaced with path
and potentially cut off.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]
navigator.go(
to: [C().eraseToAnyScreen(), D().eraseToAnyScreen()],
on: 0
)
// New path
// [(A, 0), (C, 2), (D, 3)]
- path: New path after
id
- id:
ScreenID
used to identify where the path should be appended
Replace the path after the last occurrence of a given Parent
with the passed path.
public func go<Parent: Screen>(to path: [AnyScreen], on parent: Parent)
go(to:, on:)
appends the given path after the last occurrence of the passed Parent
Screen
object. If you call go(to:, on:)
for a Parent
screen that is not associated with the last screen in the current routing path, the routing path after the ScreenID
is replaced with path
and potentially cut off.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]
navigator.go(
to: [C().eraseToAnyScreen(), D().eraseToAnyScreen()],
on: A()
)
// New path
// [(A, 0), (C, 2), (D, 3)]
- path: New path after
Parent
- parent:
Screen
used to identify where the path should be appended
Replace the path after the last occurrence of a given Parent
with the passed path.
public func go(to path: [AnyScreen], on parent: AnyScreen)
go(to:, on:)
appends the given path after the last occurrence of the passed Parent
Screen
object. If you call go(to:, on:)
for a Parent
screen that is not associated with the last screen in the current routing path, the routing path after the ScreenID
is replaced with path
and potentially cut off. Most likely used in conjunction with @Environment(.currentScreen).
// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]
navigator.go(
to: [C().eraseToAnyScreen(), D().eraseToAnyScreen()],
on: A()
)
// New path
// [(A, 0), (C, 2), (D, 3)]
- path: New path after
Parent
- parent:
AnyScreen
used to identify where the path should be appended
Go back to the last occurrence of the screen instance in the routing path.
public func goBack<S: Screen>(to screen: S)
goBack(to:)
trims the routing path to up to the last occurrence of the passed screen.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2)]
navigator.goBack(to: A())
// New path
// [(A, 0)]
- screen: Destination
Go back to the last occurrence of the screen instance in the routing path.
public func goBack(to screen: AnyScreen)
goBack(to:)
trims the routing path to up to the last occurrence of the passed screen. Most likely used in conjunction with @Environment(.currentScreen).
// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2)]
navigator.goBack(to: A())
// New path
// [(A, 0)]
- screen: Destination
Go back to the specified ScreenID
in the routing path.
public func goBack(to id: ScreenID)
goBack(to:)
trims the routing path to up to the last occurrence of the passed screen.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2)]
navigator.goBack(to: 0)
// New path
// [(A, 0)]
- id: Destination ID
Replace the current routing path with a new routing path.
public func replace(path: AnyScreen)
Example
// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]
navigator.replace(
path: C().eraseToAnyScreen(), D().eraseToAnyScreen()
)
// New path
// [(C, 0), (D, 1)]
- path: The new routing path
Replace the current routing path with a new routing path.
public func replace(path: [AnyScreen])
replace(path:)
checks if a prefix of the new path was already part of the replaced routing path and makes sure to keep the IDs and hasAppeared state intact.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1)]
navigator.replace(
path: [
C().eraseToAnyScreen(),
D().eraseToAnyScreen()
]
)
// New path
// [(C, 0), (D, 1)]
- path: The new routing path
Removes the screen associated with the passed screenID from the routing path.
public func dismiss(id: ScreenID)
dismiss(id:)
does not care take the screen's presentation style into account and cuts the routing path up to the passed id.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2), (D,3)]
navigator.dismiss(id: 2)
// New path
// [(A, 0), (B, 1)]
- id: The id identifying the screen that needs to be dismissed
Removes the last occurrence screen from the routing path.
public func dismiss<S: Screen>(screen: S)
dismiss(screen:)
does not care take the screen's presentation style into account and cuts the routing path up to the passed id.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2), (D,3)]
navigator.dismiss(screen: C())
// New path
// [(A, 0), (B, 1)]
- screen: The screen that needs to be dismissed
Removes the last occurrence screen from the routing path.
public func dismiss(screen: AnyScreen)
dismiss(screen:)
does not care take the screen's presentation style into account and cuts the routing path up to the passed id. Most likely used in conjunction with @Environment(.currentScreen).
// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2), (D,3)]
navigator.dismiss(screen: currentScreen)
// New path
// [(A, 0), (B, 1)]
- screen: The screen that needs to be dismissed
Removes the screen successors from the routing path.
public func dismissSuccessor(of id: ScreenID)
dismissSuccessor(of id:)
does not care take the screen's presentation style into account and cuts the routing path after the passed id.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2), (D,3)]
navigator.dismissSuccessor(of id: 2)
// New path
// [(A, 0), (B, 1), (C, 2)]
- id: The id identifying the screen that needs to be dismissed
Removes successors of the last occurrence of the passed screen from the routing path.
public func dismissSuccessor<S: Screen>(of screen: S)
dismissSuccessor(of screen:)
does not care take the screen's presentation style into account and cuts the routing path after the passed id.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2), (D,3)]
navigator.dismissSuccessor(of: C())
// New path
// [(A, 0), (B, 1), (C, 2)]
- screen: The screen that needs to be dismissed
Removes successors of the last occurrence of the passed screen from the routing path.
public func dismissSuccessor(of screen: AnyScreen)
dismissSuccessor(of screen:)
does not care take the screen's presentation style into account and cuts the routing path after the passed id.
// Curent path [(Content, ID)]
// [(A, 0), (B, 1), (C, 2), (D,3)]
navigator.dismissSuccessor(of: C())
// New path
// [(A, 0), (B, 1), (C, 2)]
- screen: The screen that needs to be dismissed
Enable logging received function calls and path changes.
func debug() -> Navigator
Generated at 2021-04-29T07:59:04+0000 using swift-doc 1.0.0-beta.6.
Types
- AnyPathBuilder
- AnyScreen
- Deeplink
- DeeplinkComponent
- DeeplinkComponent.Argument
- DeeplinkHandler
- DeeplinkParser
- EitherAB
- EitherABC
- EitherABCD
- EitherABCDE
- EitherABCDEF
- EitherABCDEFG
- EitherABCDEFGH
- EitherABCDEFGHI
- EitherABCDEFGHIJ
- IdentifiedScreen
- NavigationNode
- NavigationTreeBuilder
- Navigator
- Navigator.Datasource
- Navigator.DidAppearInvocation
- Navigator.DismissInvocation
- Navigator.GoBackToInvocation
- Navigator.GoToInvocation
- Navigator.GoToPathInvocation
- Navigator.NavigationIdentifier
- Navigator.ReplaceContentInvocation
- Navigator.ReplacePathInvocation
- Navigator.ReplaceScreenInvocation
- NavigatorKey
- OnDismissView
- PathBuilders
- PathBuilders.EmptyBuilder
- PathBuilders.WildcardView
- PathComponentUpdate
- PathUpdate
- Root
- ScreenPresentationStyle
- TreatSheetDismissAsAppearInPresenterKey
- _PathBuilder