From 2663e6f54142d62111129648c17e3b302a0677e9 Mon Sep 17 00:00:00 2001 From: Zach Date: Wed, 1 Feb 2023 17:59:14 -0700 Subject: [PATCH] Add an Immutable Plugin protocol (#4) * Add ab Immutable Plugin protocol * Add missing immutable keyPath * Clean up usage and make test for immutable plugin --- Sources/Plugin/ImmutablePlugin.swift | 24 ++++++++++++++++++ Tests/PluginTests/PluginTests.swift | 38 ++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 Sources/Plugin/ImmutablePlugin.swift diff --git a/Sources/Plugin/ImmutablePlugin.swift b/Sources/Plugin/ImmutablePlugin.swift new file mode 100644 index 0000000..7c3cbe2 --- /dev/null +++ b/Sources/Plugin/ImmutablePlugin.swift @@ -0,0 +1,24 @@ +public protocol ImmutablePlugin: Plugin where Output == Void { + /// The input value that the plugin will handle. + associatedtype Value + + /// Handles the input value. + /// + /// - Parameters: + /// - value: The input value that the plugin will handle. + /// - Throws: Any errors that occur during handling of the input value. + func handle(value: Value) async throws +} + +extension ImmutablePlugin where Value == Input { + /// A keypath that provides access to the `immutable` property of the `Source`. + public var keyPath: WritableKeyPath { + get { \.immutable } + set { } + } + + public func handle(value: Value, output: inout ()) async throws { + try await handle(value: value) + } +} + diff --git a/Tests/PluginTests/PluginTests.swift b/Tests/PluginTests/PluginTests.swift index 9fc2e21..ba8c393 100644 --- a/Tests/PluginTests/PluginTests.swift +++ b/Tests/PluginTests/PluginTests.swift @@ -86,4 +86,42 @@ final class PluginTests: XCTestCase { let token = try XCTUnwrap(urlRequest.request.allHTTPHeaderFields)["auth"] XCTAssertEqual(token, "token") } + + func testImmutablePlugin() async throws { + class MockService: Pluginable { + var plugins: [any Plugin] = [] + } + + class CountPlugin: ImmutablePlugin { + typealias Source = MockService + + static let shared = CountPlugin() + + var count: Int = 0 + + private init() {} + + func handle(value: Void) async throws { + count += 1 + } + } + + let service = MockService() + + XCTAssertEqual(service.pluginTypes, []) + + service.register( + plugin: CountPlugin.shared + ) + + XCTAssertEqual(service.pluginTypes, ["(input: (), output: ())"]) + + try await service.handle(value: "Woot") + + XCTAssertEqual(CountPlugin.shared.count, 0) + + try await service.handle() + + XCTAssertEqual(CountPlugin.shared.count, 1) + } }