From 064833c1f90ac8dac0c4d8675eb724c8d2b85746 Mon Sep 17 00:00:00 2001 From: Hamzah Malik Date: Mon, 13 Jan 2025 14:34:47 +0000 Subject: [PATCH] Add channel intilizer closure to NIOAsyncTestingChannel.init --- Sources/NIOEmbedded/AsyncTestingChannel.swift | 25 +++++++++++++++---- .../AsyncTestingChannelTests.swift | 11 ++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Sources/NIOEmbedded/AsyncTestingChannel.swift b/Sources/NIOEmbedded/AsyncTestingChannel.swift index d3a4834f7e..8e0ca9c33a 100644 --- a/Sources/NIOEmbedded/AsyncTestingChannel.swift +++ b/Sources/NIOEmbedded/AsyncTestingChannel.swift @@ -307,12 +307,27 @@ public final class NIOAsyncTestingChannel: Channel { handlers: [ChannelHandler & Sendable], loop: NIOAsyncTestingEventLoop = NIOAsyncTestingEventLoop() ) async { - self.init(loop: loop) - - try! await self._pipeline.addHandlers(handlers) + try! await self.init(loop: loop) { channel in + try channel.pipeline.syncOperations.addHandlers(handlers) + } + } - // This will never throw... - try! await self.register() + /// Create a new instance. + /// + /// During creation it will automatically also register itself on the ``NIOAsyncTestingEventLoop``. + /// + /// - Parameters: + /// - loop: The ``NIOAsyncTestingEventLoop`` to use. + /// - channelInitializer: The initialization closure which will be run on the `EventLoop` before registration. This could be used to add handlers using `syncOperations`. + public convenience init( + loop: NIOAsyncTestingEventLoop = NIOAsyncTestingEventLoop(), + channelInitializer: @escaping @Sendable (NIOAsyncTestingChannel) throws -> Void + ) async throws { + self.init(loop: loop) + try await loop.submit { + try channelInitializer(self) + }.get() + try await self.register() } /// Asynchronously closes the ``NIOAsyncTestingChannel``. diff --git a/Tests/NIOEmbeddedTests/AsyncTestingChannelTests.swift b/Tests/NIOEmbeddedTests/AsyncTestingChannelTests.swift index 5022dcd3ca..4e9cd07547 100644 --- a/Tests/NIOEmbeddedTests/AsyncTestingChannelTests.swift +++ b/Tests/NIOEmbeddedTests/AsyncTestingChannelTests.swift @@ -65,6 +65,17 @@ class AsyncTestingChannelTests: XCTestCase { XCTAssertNoThrow(try channel.pipeline.removeHandler(name: "handler2").wait()) } + func testClosureInit() async throws { + final class Handler: ChannelInboundHandler, Sendable { + typealias InboundIn = Never + } + + let channel = try await NIOAsyncTestingChannel { + try $0.pipeline.syncOperations.addHandler(Handler()) + } + XCTAssertNoThrow(try channel.pipeline.handler(type: Handler.self).wait()) + } + func testWaitForInboundWrite() async throws { let channel = NIOAsyncTestingChannel() let task = Task {