From 398b852ac88375a3a799b37ce86cb06b775f8e52 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Tue, 23 Sep 2025 16:21:25 +0200 Subject: [PATCH] Integrated the DocCMiddleware.Configuration type to the DocCMiddleware type in the library target. --- .../Public/Middlewares/DocCMiddleware.swift | 68 +++++++++----- .../Middlewares/DocCMiddlewareTests.swift | 93 ++++++++++--------- .../Types/Extensions/Tag+Constants.swift | 4 +- 3 files changed, 99 insertions(+), 66 deletions(-) diff --git a/Sources/DocCMiddleware/Public/Middlewares/DocCMiddleware.swift b/Sources/DocCMiddleware/Public/Middlewares/DocCMiddleware.swift index 9d6b03b..1abc144 100644 --- a/Sources/DocCMiddleware/Public/Middlewares/DocCMiddleware.swift +++ b/Sources/DocCMiddleware/Public/Middlewares/DocCMiddleware.swift @@ -12,7 +12,6 @@ import Hummingbird -import class NIOPosix.NIOThreadPool import struct Logging.Logger /// A middleware that proxies requests to `DocC` documentation containers within a hosting app. @@ -20,42 +19,67 @@ public struct DocCMiddleware { // MARK: Properties + /// A type that contains the parameters to configure the middleware. + let configuration: Configuration + /// A protocol that defines file system interactions. let fileProvider: any FileProvider /// A type that interacts with the logging system. let logger: Logger + /// A use case that checks whether a received URI could be processed or not. + private let checkURI: CheckURIUseCase = .init() + // MARK: Initializers /// Initializes this middleware with the root path to the `DocC` documentation containers in the file system. /// - Parameters: - /// - pathToRoot: A path to the root folder in which the `DocC` documentation container are located. + /// - configuration: A type that contains the parameters to configure the middleware. /// - logger: A type that interacts with the logging system. - /// - threadPool: A representation of the thread pool that should be used in case some blocking work needs to be performed for which no non-blocking API exists. + /// - fileProvider: A type that conforms to the protocol that defines file system interactions, if any. init( - pathToRoot rootFolder: String, + configuration: Configuration, logger: Logger, - threadPool: NIOThreadPool = .singleton + fileProvider: (any FileProvider)? = nil ) { - self.fileProvider = LocalFileSystem( - rootFolder: rootFolder, - threadPool: threadPool, - logger: logger - ) - self.logger = logger - } - - /// Initializes this middleware with a type conforming to the `FileProvider` protocol. - /// - Parameters: - /// - fileProvider: A type that conforms to the protocol that defines file system interactions. - /// - logger: A type that interacts with the logging system. - init( - fileProvider: any FileProvider, - logger: Logger - ) { - self.fileProvider = fileProvider + self.configuration = configuration + self.fileProvider = if let fileProvider { + fileProvider + } else { + LocalFileSystem( + rootFolder: configuration.folderRoot, + threadPool: configuration.threadPool, + logger: logger + ) + } self.logger = logger } } + +// MARK: - RouterMiddleware + +extension DocCMiddleware: RouterMiddleware { + + // MARK: Type aliases + + public typealias Context = RequestContext + public typealias Input = Request + public typealias Output = Response + + // MARK: Functions + + public func handle( + _ input: Input, + context: any Context, + next: (Input, any Context) async throws -> Output + ) async throws -> Output { + guard let uri = checkURI(input.uri) else { + return try await next(input, context) + } + + return try await next(input, context) + } + +} diff --git a/Tests/DocCMiddleware/Tests/Public/Middlewares/DocCMiddlewareTests.swift b/Tests/DocCMiddleware/Tests/Public/Middlewares/DocCMiddlewareTests.swift index 77c253b..1f36e8b 100644 --- a/Tests/DocCMiddleware/Tests/Public/Middlewares/DocCMiddlewareTests.swift +++ b/Tests/DocCMiddleware/Tests/Public/Middlewares/DocCMiddlewareTests.swift @@ -14,35 +14,53 @@ import Testing import struct Hummingbird.LocalFileSystem import struct Logging.Logger + import protocol Hummingbird.FileProvider -@testable import DocCMiddleware +@testable import struct DocCMiddleware.DocCMiddleware -@Suite("DocC Middleware") +@Suite("DocC Middleware", .tags(.middleware)) struct DocCMiddlewareTests { // MARK: Initializers tests #if swift(>=6.2) - @Test(.tags(.initializer)) - func `initialize with path to root`() { - assertInit(pathToRoot: "/path/to/root/docc/documentation") + @Test + func `initialize with URI and folder paths`() { + assertInit(configuration: .init( + uriRoot: "/path/to/documentation", + folderRoot: "/location/docc/documentation" + )) } - @Test(.tags(.initializer)) - func `initialize with type that conforms to the FileProvider protocol`() { - // GIVEN - assertInit(fileProvider: FileProviderStub()) + @Test + func `initialize with URI path and type that conforms to the FileProvider protocol`() { + assertInit( + configuration: .init( + uriRoot: "/path/to/documentation", + folderRoot: .empty + ), + fileProvider: FileProviderStub() + ) } #else - @Test("initialize with path to root", .tags(.initializer)) - func initWithRootPath() { - assertInit(pathToRoot: "/path/to/root/docc/documentation") + @Test("initialize with URI and folder paths") + func initWithURIAndFolderPaths() { + assertInit(configuration: .init( + uriRoot: "/path/to/documentation", + folderRoot: "/location/docc/documentation" + )) } - @Test("initialize with type that conforms to the FileProvider protocol", .tags(.initializer)) - func initWithFileProviderType() { - assertInit(fileProvider: FileProviderStub()) + @Test("initialize with type that conforms to the FileProvider protocol") + func initWithURIPathAndFileProviderType() { + assertInit( + configuration: .init( + uriRoot: "/path/to/documentation", + folderRoot: .empty + ), + fileProvider: FileProviderStub() + ) } #endif @@ -54,46 +72,37 @@ private extension DocCMiddlewareTests { // MARK: Functions - /// Asserts the initialization of a `DocCMiddleware` type with a root path in the file system. + /// Asserts the initialization of a `DocCMiddleware` type. /// - Parameters: - /// - pathToRoot: A path to the root `DocC` documentation containers. + /// - configuration: A type that contains the parameters to configure the middleware. /// - logger: A type that interacts with the logging system. + /// - fileProvider: A type that conforms to the protocol that defines file system interactions, if any. func assertInit( - pathToRoot: String, - logger: Logger = .test + configuration: DocCMiddleware.Configuration, + logger: Logger = .test, + fileProvider: (any FileProvider)? = nil ) { // GIVEN // WHEN let middleware = DocCMiddleware( - pathToRoot: pathToRoot, - logger: logger + configuration: configuration, + logger: logger, + fileProvider: fileProvider ) // THEN - #expect(middleware.fileProvider is LocalFileSystem) + #expect(middleware.configuration.folderRoot == configuration.folderRoot) + #expect(middleware.configuration.uriRoot == configuration.uriRoot) + #expect(middleware.configuration.threadPool === configuration.threadPool) + #expect(middleware.logger.label == logger.label) #expect(middleware.logger.logLevel == logger.logLevel) - } - - /// Asserts the initialization of a `DocCMiddleware` type with a type that conforms to the `FileProvider` protocol. - /// - Parameters: - /// - fileProvider: A type that conforms to the protocol that defines file system interactions. - /// - logger: A type that interacts with the logging system. - func assertInit( - fileProvider: any FileProvider, - logger: Logger = .test - ) { - // GIVEN - // WHEN - let middleware = DocCMiddleware( - fileProvider: fileProvider, - logger: logger - ) - // THEN - #expect(type(of:middleware.fileProvider) == type(of: fileProvider)) - #expect(middleware.logger.label == logger.label) - #expect(middleware.logger.logLevel == logger.logLevel) + if let fileProvider { + #expect(type(of:middleware.fileProvider) == type(of: fileProvider)) + } else { + #expect(middleware.fileProvider is LocalFileSystem) + } } } diff --git a/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift b/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift index 34ee316..2c26954 100644 --- a/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift +++ b/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift @@ -18,8 +18,8 @@ extension Tag { /// Tag that indicate a test case for an enumeration type. @Tag static var enumeration: Self - /// Tag that indicate a test case for a type initialization. - @Tag static var initializer: Self + /// Tag that indicate a test case for a middleware type. + @Tag static var middleware: Self /// Tag that indicate a test case for a use case type. @Tag static var useCase: Self