Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: expose helpers for static models #311

Merged
merged 1 commit into from
Nov 14, 2024

Conversation

watt
Copy link
Collaborator

@watt watt commented Nov 14, 2024

Creating a static model is useful for testing, and the missing public init on ActionModel makes that difficult to do. This PR adds that init along with a couple static factory methods for that use case.

Checklist

  • Unit Tests
  • UI Tests
  • Snapshot Tests (iOS only)
  • I have made corresponding changes to the documentation

@watt watt requested review from a team as code owners November 14, 2024 01:18
Copy link

@g-mark g-mark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are nice additions!

Two comments:

  • If I could bike-shed for a moment, static feels close, but also ambiguous due to the overloaded meaning in Swift. Hoping there might be a more explicit name. Some ideas: noOp, noOperation, identity, ignored, ignore, ignoringChanges/ignoringActions, immutable.

  • Noticed this warning (Worker.swift, line 77):

    passing argument of non-sendable type 'WorkerType.Output' into main actor-isolated context may introduce data races

    We should mark Output as Sendable soon.

}
}

extension Store {
public extension Store {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the access control on the individual methods.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but the linter did this!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approve me! #315

@@ -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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there any reasons we'd want to restrict clients' ability to create these types in general?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To reduce the chance of folks using it wrong, mainly. You can't create something like a RenderContext either. The type's docs already hint at this, and I can copy it to the init as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be clear – you think the convenience of exposing the public constructor outweighs the chance of misuse?

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> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

per @g-mark's naming thoughts – this form of utility could perhaps be named 'just' if we want to lean into Combine's parlance

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or follow Binding.constant(_:)'s lead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

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> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or follow Binding.constant(_:)'s lead.

@watt watt force-pushed the awatt/observablescreen-static-helpers branch from b3d0dd3 to 13631b0 Compare November 14, 2024 19:45
@watt watt force-pushed the awatt/observablescreen-static-helpers branch from 13631b0 to d3b1e4b Compare November 14, 2024 19:53
@watt
Copy link
Collaborator Author

watt commented Nov 14, 2024

  • If I could bike-shed for a moment, static feels close, but also ambiguous due to the overloaded meaning in Swift. Hoping there might be a more explicit name. Some ideas: noOp, noOperation, identity, ignored, ignore, ignoringChanges/ignoringActions, immutable.

Changed to constant per Rob's suggestion.

  • Noticed this warning (Worker.swift, line 77):

    passing argument of non-sendable type 'WorkerType.Output' into main actor-isolated context may introduce data races

    We should mark Output as Sendable soon.

Feel free to take that on! I think it might take some integration work since it'll affect a lot of types.

@watt watt merged commit 87c8f25 into main Nov 14, 2024
6 checks passed
@watt watt deleted the awatt/observablescreen-static-helpers branch November 14, 2024 20:02
@g-mark
Copy link

g-mark commented Nov 14, 2024

We should mark Output as Sendable soon.

Feel free to take that on! I think it might take some integration work since it'll affect a lot of types.

On it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants