From b3d0dd367d73fe1107d31e9227bf6ce2231a3282 Mon Sep 17 00:00:00 2001 From: Andrew Watt Date: Wed, 13 Nov 2024 15:33:47 -0800 Subject: [PATCH] feat: expose helpers for static models --- WorkflowSwiftUI/Sources/ActionModel.swift | 17 ++++++++++++++++ WorkflowSwiftUI/Sources/StateAccessor.swift | 12 +++++++++++ WorkflowSwiftUI/Sources/Store+Preview.swift | 22 ++++++++------------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/WorkflowSwiftUI/Sources/ActionModel.swift b/WorkflowSwiftUI/Sources/ActionModel.swift index 7c494bbc..40baa5bd 100644 --- a/WorkflowSwiftUI/Sources/ActionModel.swift +++ b/WorkflowSwiftUI/Sources/ActionModel.swift @@ -5,6 +5,11 @@ public struct ActionModel: ObservableModel, SingleActionModel { public let accessor: StateAccessor public let sendAction: (Action) -> Void + + public init(accessor: StateAccessor, sendAction: @escaping (Action) -> Void) { + self.accessor = accessor + self.sendAction = sendAction + } } /// An observable model with a single action. @@ -22,3 +27,15 @@ extension ActionModel: Identifiable where State: Identifiable { accessor.id } } + +#if DEBUG + +public extension ActionModel { + /// Creates a static model which ignores all sent values, suitable for static previews + /// or testing. + static func `static`(state: State) -> ActionModel { + ActionModel(accessor: .static(state: state), sendAction: { _ in }) + } +} + +#endif diff --git a/WorkflowSwiftUI/Sources/StateAccessor.swift b/WorkflowSwiftUI/Sources/StateAccessor.swift index 24278483..b5ae7738 100644 --- a/WorkflowSwiftUI/Sources/StateAccessor.swift +++ b/WorkflowSwiftUI/Sources/StateAccessor.swift @@ -31,3 +31,15 @@ extension StateAccessor: Identifiable where State: Identifiable { state.id } } + +#if DEBUG + +public extension StateAccessor { + /// Creates a static state accessor which ignores all sent values, suitable for static previews + /// or testing. + static func `static`(state: State) -> StateAccessor { + StateAccessor(state: state, sendValue: { _ in }) + } +} + +#endif diff --git a/WorkflowSwiftUI/Sources/Store+Preview.swift b/WorkflowSwiftUI/Sources/Store+Preview.swift index f31a4b24..1fef3727 100644 --- a/WorkflowSwiftUI/Sources/Store+Preview.swift +++ b/WorkflowSwiftUI/Sources/Store+Preview.swift @@ -12,23 +12,17 @@ public struct StaticStorePreviewContext { } public func makeStateAccessor(state: State) -> StateAccessor { - StateAccessor( - state: state, - sendValue: { _ in } - ) + .static(state: state) } public func makeActionModel( state: State ) -> ActionModel { - ActionModel( - accessor: makeStateAccessor(state: state), - sendAction: makeSink(of: Action.self).send - ) + .static(state: state) } } -extension Store { +public extension Store { /// Generates a static store for previews. /// /// Previews generated with this method are static and do not update state. To generate a @@ -38,7 +32,7 @@ extension Store { /// - Parameter makeModel: A closure to create the store's model. The provided `context` param /// is a convenience to generate dummy sinks and state accessors. /// - Returns: A store for previews. - public static func preview( + static func preview( makeModel: (StaticStorePreviewContext) -> Model ) -> Store { let context = StaticStorePreviewContext() @@ -46,7 +40,7 @@ extension Store { let (store, _) = make(model: model) return store } - + /// Generates a static store for previews. /// /// Previews generated with this method are static and do not update state. To generate a @@ -55,14 +49,14 @@ extension Store { /// /// - Parameter state: The state of the view. /// - Returns: A store for previews. - public static func preview( + static func preview( state: State ) -> Store> where Model == ActionModel { preview { context in context.makeActionModel(state: state) } } - + /// Generates a static store for previews. /// /// Previews generated with this method are static and do not update state. To generate a @@ -71,7 +65,7 @@ extension Store { /// /// - Parameter state: The state of the view. /// - Returns: A store for previews. - public static func preview( + static func preview( state: State ) -> Store> where Model == StateAccessor { preview { context in