From a2483b9fd67996ece10a19f44632fdb406c6deb2 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Thu, 18 Sep 2025 23:08:52 +0200 Subject: [PATCH] Implemented the initialization functions for the DocCMiddleware type in the library target. --- .../Public/Middlewares/DocCMiddleware.swift | 61 ++++++++++++ .../Middlewares/DocCMiddlewareTests.swift | 99 +++++++++++++++++++ .../Types/Extensions/Logger+Constants.swift | 29 ++++++ .../Types/Extensions/Tag+Constants.swift | 22 +++++ .../Types/Stubs/FileProviderStub.swift | 53 ++++++++++ 5 files changed, 264 insertions(+) create mode 100644 Sources/DocCMiddleware/Public/Middlewares/DocCMiddleware.swift create mode 100644 Tests/DocCMiddleware/Tests/Public/Middlewares/DocCMiddlewareTests.swift create mode 100644 Tests/DocCMiddleware/Types/Extensions/Logger+Constants.swift create mode 100644 Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift create mode 100644 Tests/DocCMiddleware/Types/Stubs/FileProviderStub.swift diff --git a/Sources/DocCMiddleware/Public/Middlewares/DocCMiddleware.swift b/Sources/DocCMiddleware/Public/Middlewares/DocCMiddleware.swift new file mode 100644 index 0000000..9d6b03b --- /dev/null +++ b/Sources/DocCMiddleware/Public/Middlewares/DocCMiddleware.swift @@ -0,0 +1,61 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the Hummingbird DocC Middleware open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the Hummingbird DocC Middleware project authors +// Licensed under the EUPL 1.2 or later. +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of Hummingbird DocC Middleware project authors +// +// ===----------------------------------------------------------------------=== + +import Hummingbird + +import class NIOPosix.NIOThreadPool +import struct Logging.Logger + +/// A middleware that proxies requests to `DocC` documentation containers within a hosting app. +public struct DocCMiddleware { + + // MARK: Properties + + /// A protocol that defines file system interactions. + let fileProvider: any FileProvider + + /// A type that interacts with the logging system. + let logger: Logger + + // 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. + /// - 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. + init( + pathToRoot rootFolder: String, + logger: Logger, + threadPool: NIOThreadPool = .singleton + ) { + 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.logger = logger + } + +} diff --git a/Tests/DocCMiddleware/Tests/Public/Middlewares/DocCMiddlewareTests.swift b/Tests/DocCMiddleware/Tests/Public/Middlewares/DocCMiddlewareTests.swift new file mode 100644 index 0000000..77c253b --- /dev/null +++ b/Tests/DocCMiddleware/Tests/Public/Middlewares/DocCMiddlewareTests.swift @@ -0,0 +1,99 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the Hummingbird DocC Middleware open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the Hummingbird DocC Middleware project authors +// Licensed under the EUPL 1.2 or later. +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of Hummingbird DocC Middleware project authors +// +// ===----------------------------------------------------------------------=== + +import Testing + +import struct Hummingbird.LocalFileSystem +import struct Logging.Logger +import protocol Hummingbird.FileProvider + +@testable import DocCMiddleware + +@Suite("DocC 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(.tags(.initializer)) + func `initialize with type that conforms to the FileProvider protocol`() { + // GIVEN + assertInit(fileProvider: FileProviderStub()) + } +#else + @Test("initialize with path to root", .tags(.initializer)) + func initWithRootPath() { + assertInit(pathToRoot: "/path/to/root/docc/documentation") + } + + @Test("initialize with type that conforms to the FileProvider protocol", .tags(.initializer)) + func initWithFileProviderType() { + assertInit(fileProvider: FileProviderStub()) + } +#endif + +} + +// MARK: - Assertions + +private extension DocCMiddlewareTests { + + // MARK: Functions + + /// Asserts the initialization of a `DocCMiddleware` type with a root path in the file system. + /// - Parameters: + /// - pathToRoot: A path to the root `DocC` documentation containers. + /// - logger: A type that interacts with the logging system. + func assertInit( + pathToRoot: String, + logger: Logger = .test + ) { + // GIVEN + // WHEN + let middleware = DocCMiddleware( + pathToRoot: pathToRoot, + logger: logger + ) + + // THEN + #expect(middleware.fileProvider is LocalFileSystem) + #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) + } + +} diff --git a/Tests/DocCMiddleware/Types/Extensions/Logger+Constants.swift b/Tests/DocCMiddleware/Types/Extensions/Logger+Constants.swift new file mode 100644 index 0000000..a006a09 --- /dev/null +++ b/Tests/DocCMiddleware/Types/Extensions/Logger+Constants.swift @@ -0,0 +1,29 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the Hummingbird DocC Middleware open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the Hummingbird DocC Middleware project authors +// Licensed under the EUPL 1.2 or later. +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of Hummingbird DocC Middleware project authors +// +// ===----------------------------------------------------------------------=== + +import Logging +import Testing + +extension Logger { + + // MARK: Constants + + /// Creates a logger instance that is ready to use in test cases. + static let test: Self = { + var logger = Logger(label: "test.hummingbird-docc-middleware.logger") + + logger.logLevel = try! #require(Logger.Level.allCases.randomElement()) + + return logger + }() + +} diff --git a/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift b/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift new file mode 100644 index 0000000..d180d37 --- /dev/null +++ b/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift @@ -0,0 +1,22 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the Hummingbird DocC Middleware open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the Hummingbird DocC Middleware project authors +// Licensed under the EUPL 1.2 or later. +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of Hummingbird DocC Middleware project authors +// +// ===----------------------------------------------------------------------=== + +import Testing + +extension Tag { + + // MARK: Constants + + /// Tag that indicate a test case for a type initialization. + @Tag static var initializer: Self + +} diff --git a/Tests/DocCMiddleware/Types/Stubs/FileProviderStub.swift b/Tests/DocCMiddleware/Types/Stubs/FileProviderStub.swift new file mode 100644 index 0000000..ab4f4b3 --- /dev/null +++ b/Tests/DocCMiddleware/Types/Stubs/FileProviderStub.swift @@ -0,0 +1,53 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the Hummingbird DocC Middleware open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the Hummingbird DocC Middleware project authors +// Licensed under the EUPL 1.2 or later. +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of Hummingbird DocC Middleware project authors +// +// ===----------------------------------------------------------------------=== + +import Hummingbird + +/// A stub that conforms to the `FileProvider` protocol. +struct FileProviderStub {} + +// MARK: - FileProvider + +extension FileProviderStub: FileProvider { + + // MARK: Type aliases + + typealias FileAttributes = String + typealias FileIdentifier = String + + // MARK: Functions + + func getFileIdentifier(_ path: String) -> String? { + nil + } + + func getAttributes(id: String) async throws -> String? { + nil + } + + func loadFile( + id: String, + context: some RequestContext + ) async throws -> ResponseBody { + .init() + } + + func loadFile( + id: String, + range: ClosedRange, + context: some RequestContext + ) async throws -> ResponseBody { + .init() + } + +} +