From 6026c24ab713b46a0ac6739188bc0544d6cf3dbe Mon Sep 17 00:00:00 2001 From: Louis Debaere Date: Mon, 12 Feb 2024 14:00:58 +0100 Subject: [PATCH] Add `asDisposable` convenience property to `Task` Offers a convenient way to return Tasks as a `Disposable` instead of having to wrap it with `AnonymousDisposable`, for example in an `EffectHandler` --- .../Source/Disposables/Task+Disposable.swift | 7 +++++ MobiusCore/Test/Task+DisposableTests.swift | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 MobiusCore/Source/Disposables/Task+Disposable.swift create mode 100644 MobiusCore/Test/Task+DisposableTests.swift diff --git a/MobiusCore/Source/Disposables/Task+Disposable.swift b/MobiusCore/Source/Disposables/Task+Disposable.swift new file mode 100644 index 00000000..0d6608e2 --- /dev/null +++ b/MobiusCore/Source/Disposables/Task+Disposable.swift @@ -0,0 +1,7 @@ +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) +public extension Task { + + var asDisposable: any Disposable { + AnonymousDisposable { cancel() } + } +} diff --git a/MobiusCore/Test/Task+DisposableTests.swift b/MobiusCore/Test/Task+DisposableTests.swift new file mode 100644 index 00000000..73e7e071 --- /dev/null +++ b/MobiusCore/Test/Task+DisposableTests.swift @@ -0,0 +1,29 @@ +import MobiusCore +import Nimble +import Quick + +@available(iOS 13.0, *) +class TaskDisposableTests: QuickSpec { + override func spec() { + describe("Task+Disposable") { + var task: Task! + var disposable: Disposable! + + beforeEach { + task = Task { + try? await Task.sleep(nanoseconds: 1_000_000_000) + } + disposable = task.asDisposable + } + + it("starts off not cancelled") { + expect(task.isCancelled).to(beFalse()) + } + + it("disposable cancels the task that owns it") { + disposable.dispose() + expect(task.isCancelled).to(beTrue()) + } + } + } +}