diff --git a/Sources/Atoms/Core/StoreContext.swift b/Sources/Atoms/Core/StoreContext.swift index d2dc9668..c3bbeb80 100644 --- a/Sources/Atoms/Core/StoreContext.swift +++ b/Sources/Atoms/Core/StoreContext.swift @@ -306,33 +306,29 @@ private extension StoreContext { updatedScopes[currentScope.key] = currentScope } - // Performs update of the given atom with the dependency's context. - func performUpdate(for key: AtomKey, cache: some AtomCacheProtocol, dependency: some Atom) { - dependency.producer.performUpdate { - // Dependents must be updated with the scope at which they were initialised. - let localContext = StoreContext( - store: store, - rootScope: rootScope, - currentScope: cache.initializedScope - ) - - let didUpdate = localContext.transitiveUpdate(for: key, cache: cache) - - guard didUpdate else { - // Record the atom to avoid downstream from being update. - skippedDependencies.insert(key) - return - } + func transitiveUpdate(for key: AtomKey, cache: some AtomCacheProtocol) { + // Dependents must be updated with the scope at which they were initialised. + let localContext = StoreContext( + store: store, + rootScope: rootScope, + currentScope: cache.initializedScope + ) - if let scope = cache.initializedScope { - updatedScopes[scope.key] = scope - } + let didUpdate = localContext.transitiveUpdate(for: key, cache: cache) + + guard didUpdate else { + // Record the atom to avoid downstream from being update. + skippedDependencies.insert(key) + return + } + + if let scope = cache.initializedScope { + updatedScopes[scope.key] = scope } } - // Performs update of the given subscription with the dependency's context. - func performUpdate(subscription: Subscription, dependency: some Atom) { - dependency.producer.performUpdate(subscription.update) + func performUpdate(dependency: some Atom, body: @MainActor () -> Void) { + dependency.producer.performUpdate(body) } func validEdge(_ edge: Edge) -> Edge? { @@ -365,7 +361,9 @@ private extension StoreContext { let dependencyCache = store.state.caches[edge.from] if let cache, let dependencyCache { - performUpdate(for: key, cache: cache, dependency: dependencyCache.atom) + performUpdate(dependency: dependencyCache.atom) { + transitiveUpdate(for: key, cache: cache) + } } case .subscriber(let key): @@ -377,7 +375,7 @@ private extension StoreContext { let dependencyCache = store.state.caches[edge.from] if let subscription, let dependencyCache { - performUpdate(subscription: subscription, dependency: dependencyCache.atom) + performUpdate(dependency: dependencyCache.atom, body: subscription.update) } } } diff --git a/Tests/AtomsTests/Atom/AsyncPhaseAtomTests.swift b/Tests/AtomsTests/Atom/AsyncPhaseAtomTests.swift index 6d4f0ac5..6409b36e 100644 --- a/Tests/AtomsTests/Atom/AsyncPhaseAtomTests.swift +++ b/Tests/AtomsTests/Atom/AsyncPhaseAtomTests.swift @@ -70,9 +70,7 @@ final class AsyncPhaseAtomTests: XCTestCase { await context.refresh(atom) } - Task { - refreshTask.cancel() - } + refreshTask.cancel() let phase = await refreshTask.value XCTAssertTrue(phase.isSuspending) diff --git a/Tests/AtomsTests/Atom/TaskAtomTests.swift b/Tests/AtomsTests/Atom/TaskAtomTests.swift index fd350496..5e3f238c 100644 --- a/Tests/AtomsTests/Atom/TaskAtomTests.swift +++ b/Tests/AtomsTests/Atom/TaskAtomTests.swift @@ -66,16 +66,13 @@ final class TaskAtomTests: XCTestCase { do { // Cancellation - let refreshTask0 = Task { + let refreshTask = Task { await context.refresh(atom) } - Task { - refreshTask0.cancel() - } - - let task = await refreshTask0.value + refreshTask.cancel() + let task = await refreshTask.value XCTAssertTrue(task.isCancelled) } @@ -89,19 +86,15 @@ final class TaskAtomTests: XCTestCase { do { // Override cancellation - context.override(atom) { _ in Task { 400 } } let refreshTask = Task { await context.refresh(atom) } - Task { - refreshTask.cancel() - } + refreshTask.cancel() let task = await refreshTask.value - XCTAssertTrue(task.isCancelled) } } diff --git a/Tests/AtomsTests/Atom/ThrowingTaskAtomTests.swift b/Tests/AtomsTests/Atom/ThrowingTaskAtomTests.swift index e9ce70c4..81a9307c 100644 --- a/Tests/AtomsTests/Atom/ThrowingTaskAtomTests.swift +++ b/Tests/AtomsTests/Atom/ThrowingTaskAtomTests.swift @@ -85,12 +85,9 @@ final class ThrowingTaskAtomTests: XCTestCase { await context.refresh(atom) } - Task { - refreshTask.cancel() - } + refreshTask.cancel() let task = await refreshTask.value - XCTAssertTrue(task.isCancelled) } @@ -104,20 +101,16 @@ final class ThrowingTaskAtomTests: XCTestCase { do { // Override cancellation - context.override(atom) { _ in Task { 400 } } - let refreshTask1 = Task { + let refreshTask = Task { await context.refresh(atom) } - Task { - refreshTask1.cancel() - } - - let task1 = await refreshTask1.value + refreshTask.cancel() - XCTAssertTrue(task1.isCancelled) + let task = await refreshTask.value + XCTAssertTrue(task.isCancelled) } } diff --git a/scripts/test.sh b/scripts/test.sh index 46347b56..bdb6e777 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -44,4 +44,4 @@ while [[ $# -gt 0 ]]; do esac done -eval xcodebuild clean test "${options[@]-}" "${args[@]-}" +eval xcodebuild clean test -configuration Release ENABLE_TESTABILITY=YES "${options[@]-}" "${args[@]-}"