-
Hoping to clarify the correct way to test struct EditorClient: Sendable {
public var continuousEditing: @Sendable (Bool) async -> Void
} Reading the docs for let isContinuousEditing = ActorIsolated<Bool>(false)
store.dependencies.vesperControlsClient.continuousEditing = { await isContinuousEditing.setValue($0) }
// exercise the store...
await isContinuousEditing.withValue { XCTAssertTrue($0) } But simply marking the closure as var isContinuousEditing = false
store.dependencies.vesperControlsClient.continuousEditing = { @MainActor in isContinuousEditing = $0 }
// exercise the store...
XCTAssertTrue(isContinuousEditing) Is there a meaningful difference between these two? I'm guessing the Side note: I have another identical-looking endpoint requires marking the closure as public struct VesperRenderClient: Sendable {
public var render: @Sendable (RenderRequest) async -> Void
}
public struct RenderRequest: Equatable, Sendable { } let renderRequestCount = ActorIsolated<Int>(0)
// Removing @Sendable annotation gives warning:
// ⚠️ Converting non-sendable function value to '@Sendable (RenderRequest) async -> Void' may introduce data races
store.dependencies.vesperRenderClient.render = { @Sendable _ in
await renderRequestCount.withValue { $0 += 1 }
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Hi @rcarver, I think using And as for the second question... I'm not sure. Seems like the closure you provide is |
Beta Was this translation helpful? Give feedback.
Hi @rcarver, I think using
@MainActor
and dropping theActorIsolated
should be ok and maybe something we should even do more of in our case study tests. In the future when we finish disentangling TCA from Combine we can hopefully run theStore
on a non-main global actor, and then in that caseActorIsolated
might be more handy.And as for the second question... I'm not sure. Seems like the closure you provide is
@Sendable
so don't know why it's complaining.