Skip to content

Commit

Permalink
feat: expose helpers for static models
Browse files Browse the repository at this point in the history
  • Loading branch information
watt committed Nov 13, 2024
1 parent a29d9d1 commit b3d0dd3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 14 deletions.
17 changes: 17 additions & 0 deletions WorkflowSwiftUI/Sources/ActionModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
public struct ActionModel<State: ObservableState, Action>: ObservableModel, SingleActionModel {
public let accessor: StateAccessor<State>
public let sendAction: (Action) -> Void

public init(accessor: StateAccessor<State>, sendAction: @escaping (Action) -> Void) {
self.accessor = accessor
self.sendAction = sendAction
}
}

/// An observable model with a single action.
Expand All @@ -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<State, Action> {
ActionModel(accessor: .static(state: state), sendAction: { _ in })
}
}

#endif
12 changes: 12 additions & 0 deletions WorkflowSwiftUI/Sources/StateAccessor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<State> {
StateAccessor(state: state, sendValue: { _ in })
}
}

#endif
22 changes: 8 additions & 14 deletions WorkflowSwiftUI/Sources/Store+Preview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,17 @@ public struct StaticStorePreviewContext {
}

public func makeStateAccessor<State>(state: State) -> StateAccessor<State> {
StateAccessor(
state: state,
sendValue: { _ in }
)
.static(state: state)
}

public func makeActionModel<State, Action>(
state: State
) -> ActionModel<State, Action> {
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
Expand All @@ -38,15 +32,15 @@ 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()
let model = makeModel(context)
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
Expand All @@ -55,14 +49,14 @@ extension Store {
///
/// - Parameter state: The state of the view.
/// - Returns: A store for previews.
public static func preview<State, Action>(
static func preview<State, Action>(
state: State
) -> Store<ActionModel<State, Action>> where Model == ActionModel<State, Action> {
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
Expand All @@ -71,7 +65,7 @@ extension Store {
///
/// - Parameter state: The state of the view.
/// - Returns: A store for previews.
public static func preview<State>(
static func preview<State>(
state: State
) -> Store<StateAccessor<State>> where Model == StateAccessor<State> {
preview { context in
Expand Down

0 comments on commit b3d0dd3

Please sign in to comment.