Skip to content

Commit

Permalink
Improve Unit tests and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
SwiftedMind committed Sep 17, 2023
1 parent 0100d38 commit 1eb694c
Show file tree
Hide file tree
Showing 12 changed files with 366 additions and 213 deletions.
8 changes: 0 additions & 8 deletions Examples/ExampleApp/ExampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
9506D5702AB5882100472C0D /* View+isLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9506D56F2AB5882100472C0D /* View+isLoading.swift */; };
9506D5732AB5C8FA00472C0D /* ViewModelDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9506D5722AB5C8FA00472C0D /* ViewModelDemo.swift */; };
9506D5752AB5C98800472C0D /* Root.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9506D5742AB5C98800472C0D /* Root.swift */; };
9553409A2AB6BD3200A9C3D9 /* DemoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955340992AB6BD3200A9C3D9 /* DemoView.swift */; };
9553409C2AB6D64200A9C3D9 /* DemoView2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9553409B2AB6D64200A9C3D9 /* DemoView2.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -31,8 +29,6 @@
9506D56F2AB5882100472C0D /* View+isLoading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+isLoading.swift"; sourceTree = "<group>"; };
9506D5722AB5C8FA00472C0D /* ViewModelDemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModelDemo.swift; sourceTree = "<group>"; };
9506D5742AB5C98800472C0D /* Root.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Root.swift; sourceTree = "<group>"; };
955340992AB6BD3200A9C3D9 /* DemoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoView.swift; sourceTree = "<group>"; };
9553409B2AB6D64200A9C3D9 /* DemoView2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoView2.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -75,8 +71,6 @@
9506D5712AB5888200472C0D /* Helpers */,
9506D55D2AB5876700472C0D /* Assets.xcassets */,
9506D55F2AB5876700472C0D /* Preview Content */,
955340992AB6BD3200A9C3D9 /* DemoView.swift */,
9553409B2AB6D64200A9C3D9 /* DemoView2.swift */,
);
path = ExampleApp;
sourceTree = "<group>";
Expand Down Expand Up @@ -182,10 +176,8 @@
9506D56E2AB5880B00472C0D /* LoadingButton.swift in Sources */,
9506D55C2AB5876400472C0D /* ViewDemo.swift in Sources */,
9506D55A2AB5876400472C0D /* App.swift in Sources */,
9553409C2AB6D64200A9C3D9 /* DemoView2.swift in Sources */,
9506D5702AB5882100472C0D /* View+isLoading.swift in Sources */,
9506D5752AB5C98800472C0D /* Root.swift in Sources */,
9553409A2AB6BD3200A9C3D9 /* DemoView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
65 changes: 0 additions & 65 deletions Examples/ExampleApp/ExampleApp/DemoView.swift

This file was deleted.

71 changes: 0 additions & 71 deletions Examples/ExampleApp/ExampleApp/DemoView2.swift

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ To cancel an ongoing task, simply call `$numbers.cancel()` or throw a `CancelLoa
<details>
<summary>Use LoadableState in Classes</summary>

If you prefer to keep your state in a view model, or if you would like to use Processed completeley outside of SwiftUI, you can also do all the things from above inside a class. However, it works slightly differently because of the nature of SwiftUI property wrappers (they hold `@State` properties inside, which don't work outside the SwiftUI environment).
If you prefer to keep your state in a view model, or if you would like to use Processed completely outside of SwiftUI, you can also do all the things from above inside a class. However, it works slightly differently because of the nature of SwiftUI property wrappers (they hold `@State` properties inside, which don't work outside the SwiftUI environment).

You simply have to conform your class to the `LoadableSupport` protocol that implements the same `load`, `cancel` and `reset` methods as the `@Loadable` property wrapper, but this time defined on `self`:

Expand Down
96 changes: 67 additions & 29 deletions Sources/Processed/Loadable/LoadableSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,27 @@ public protocol LoadableSupport: AnyObject {
priority: TaskPriority?,
block: @escaping () async throws -> Value
)


func load<Value>(
_ loadableState: ReferenceWritableKeyPath<Self,LoadableState<Value>>,
silently runSilently: Bool,
priority: TaskPriority?,
block: @escaping () async throws -> Value
) async

func load<Value>(
_ loadableState: ReferenceWritableKeyPath<Self,LoadableState<Value>>,
silently runSilently: Bool,
priority: TaskPriority?,
block: @escaping (_ yield: (_ state: LoadableState<Value>) -> Void) async throws -> Void
)

func load<Value>(
_ loadableState: ReferenceWritableKeyPath<Self,LoadableState<Value>>,
silently runSilently: Bool,
priority: TaskPriority?,
block: @escaping (_ yield: (_ state: LoadableState<Value>) -> Void) async throws -> Void
) async
}

extension LoadableSupport {
Expand Down Expand Up @@ -73,24 +87,36 @@ extension LoadableSupport {
)
tasks[identifier]?.cancel()
tasks[identifier] = Task(priority: priority) {
defer {
// Cleanup
defer { // Cleanup
tasks[identifier] = nil
}

do {
if !runSilently { self[keyPath: loadableState] = .loading }
self[keyPath: loadableState] = try await .loaded(block())
} catch is CancellationError {
// Task was cancelled. Don't change the state anymore
} catch is CancelLoadable {
self[keyPath: loadableState] = .absent
} catch {
self[keyPath: loadableState] = .error(error)
}
await load(
loadableState,
silently: runSilently,
priority: priority,
block: block
)
}
}


public func load<Value>(
_ loadableState: ReferenceWritableKeyPath<Self, LoadableState<Value>>,
silently runSilently: Bool = false,
priority: TaskPriority? = nil,
block: @escaping () async throws -> Value
) async {
do {
if !runSilently { self[keyPath: loadableState] = .loading }
self[keyPath: loadableState] = try await .loaded(block())
} catch is CancellationError {
// Task was cancelled. Don't change the state anymore
} catch is CancelLoadable {
self[keyPath: loadableState] = .absent
} catch {
self[keyPath: loadableState] = .error(error)
}
}

public func load<Value>(
_ loadableState: ReferenceWritableKeyPath<Self, LoadableState<Value>>,
silently runSilently: Bool = false,
Expand All @@ -103,23 +129,35 @@ extension LoadableSupport {
)
tasks[identifier]?.cancel()
tasks[identifier] = Task(priority: priority) {
defer {
// Cleanup
defer { // Cleanup
tasks[identifier] = nil
}

do {
if !runSilently { self[keyPath: loadableState] = .loading }
try await block { state in
self[keyPath: loadableState] = state
}
} catch is CancellationError {
// Task was cancelled. Don't change the state anymore
} catch is CancelLoadable {
self[keyPath: loadableState] = .absent
} catch {
self[keyPath: loadableState] = .error(error)
await load(
loadableState,
silently: runSilently,
priority: priority,
block: block
)
}
}

public func load<Value>(
_ loadableState: ReferenceWritableKeyPath<Self, LoadableState<Value>>,
silently runSilently: Bool = false,
priority: TaskPriority? = nil,
block: @escaping (_ yield: (_ state: LoadableState<Value>) -> Void) async throws -> Void
) async {
do {
if !runSilently { self[keyPath: loadableState] = .loading }
try await block { state in
self[keyPath: loadableState] = state
}
} catch is CancellationError {
// Task was cancelled. Don't change the state anymore
} catch is CancelLoadable {
self[keyPath: loadableState] = .absent
} catch {
self[keyPath: loadableState] = .error(error)
}
}
}
1 change: 1 addition & 0 deletions Sources/Processed/Process/ProcessSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ extension ProcessSupport {
self[keyPath: processState] = .running(process)
}
try await block()
print("JOJO")
self[keyPath: processState] = .finished(process)
} catch is CancellationError {
// Task was cancelled. Don't change the state anymore
Expand Down
18 changes: 9 additions & 9 deletions Tests/ProcessedTests/Helpers/LoadableContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@
@testable import Processed
import SwiftUI

@MainActor class LoadableContainer<Value> {
private(set) var stateHistory: [LoadableState<Value>]
@MainActor final class LoadableContainer<Value>: LoadableSupport {
private(set) var loadableHistory: [LoadableState<Value>]
var task: Task<Void, Never>?
var state: LoadableState<Value> {
didSet { stateHistory.append(state) }
var loadable: LoadableState<Value> {
didSet { loadableHistory.append(loadable) }
}

init(initialState: LoadableState<Value> = .absent) {
self.state = initialState
self.stateHistory = [state]
self.loadable = initialState
self.loadableHistory = [loadable]
}

var taskBinding: Binding<Task<Void, Never>?> {
Expand All @@ -43,11 +43,11 @@ import SwiftUI
}
}

var stateBinding: Binding<LoadableState<Value>> {
var loadableBinding: Binding<LoadableState<Value>> {
.init {
self.state
self.loadable
} set: { newValue in
self.state = newValue
self.loadable = newValue
}
}
}
6 changes: 3 additions & 3 deletions Tests/ProcessedTests/Helpers/ProcessContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
import SwiftUI

@MainActor final class ProcessContainer<ProcessID>: ProcessSupport {
private(set) var stateHistory: [ProcessState<ProcessID>]
private(set) var processHistory: [ProcessState<ProcessID>]
var task: Task<Void, Never>?
var process: ProcessState<ProcessID> {
didSet { stateHistory.append(process) }
didSet { processHistory.append(process) }
}

init(initialState: ProcessState<ProcessID> = .idle) {
self.process = initialState
self.stateHistory = [process]
self.processHistory = [process]
}

var taskBinding: Binding<Task<Void, Never>?> {
Expand Down
Loading

0 comments on commit 1eb694c

Please sign in to comment.