@_spi(Internal) @_exported import CommandClient @_exported import Dependencies import Foundation import Logging @_exported import ShellClient public protocol TestCase {} public extension TestCase { static var loggingOptions: LoggingOptions { let levelString = ProcessInfo.processInfo.environment["LOG_LEVEL"] ?? "debug" let logLevel = Logger.Level(rawValue: levelString) ?? .debug return .init(commandName: "\(Self.self)", logLevel: logLevel) } func withCapturingCommandClient( _ key: String, dependencies setupDependencies: @escaping (inout DependencyValues) -> Void = { _ in }, run: @Sendable @escaping () async throws -> Void, assert: @Sendable @escaping (CommandClient.RunCommandOptions) -> Void ) async throws { let captured = CommandClient.CapturingClient() try await withDependencies { $0.commandClient = .capturing(captured) setupDependencies(&$0) } operation: { try await Self.loggingOptions.withLogger { try await run() guard let options = await captured.options else { throw TestSupportError.optionsNotSet } assert(options) } } } func withTestLogger( key: String, logLevel: Logger.Level = .debug, operation: @escaping @Sendable () throws -> Void ) rethrows { try TestSupport.withTestLogger( key: key, label: "\(Self.self)", logLevel: logLevel ) { try operation() } } func withTestLogger( key: String, logLevel: Logger.Level = .debug, dependencies setupDependencies: @escaping (inout DependencyValues) -> Void, operation: @escaping @Sendable () throws -> Void ) rethrows { try TestSupport.withTestLogger( key: key, label: "\(Self.self)", logLevel: logLevel, dependencies: setupDependencies ) { try operation() } } func withTestLogger( key: String, logLevel: Logger.Level = .debug, operation: @escaping @Sendable () async throws -> Void ) async rethrows { try await TestSupport.withTestLogger( key: key, label: "\(Self.self)", logLevel: logLevel ) { try await operation() } } func withTestLogger( key: String, logLevel: Logger.Level = .debug, dependencies setupDependencies: @escaping (inout DependencyValues) -> Void, operation: @escaping @Sendable () async throws -> Void ) async rethrows { try await TestSupport.withTestLogger( key: key, label: "\(Self.self)", logLevel: logLevel, dependencies: setupDependencies ) { try await operation() } } } public func withTestLogger( key: String, label: String, logLevel: Logger.Level = .debug, operation: @escaping @Sendable () throws -> Void ) rethrows { try withDependencies { $0.logger = .init(label: label) $0.logger[metadataKey: "test"] = "\(key)" $0.logger.logLevel = logLevel } operation: { try operation() } } public func withTestLogger( key: String, label: String, logLevel: Logger.Level = .debug, dependencies setupDependencies: @escaping (inout DependencyValues) -> Void, operation: @escaping @Sendable () throws -> Void ) rethrows { try withDependencies { $0.logger = .init(label: label) $0.logger[metadataKey: "test"] = "\(key)" $0.logger.logLevel = logLevel setupDependencies(&$0) } operation: { try operation() } } public func withTestLogger( key: String, label: String, logLevel: Logger.Level = .debug, operation: @escaping @Sendable () async throws -> Void ) async rethrows { try await withDependencies { $0.logger = .init(label: label) $0.logger[metadataKey: "test"] = "\(key)" $0.logger.logLevel = logLevel } operation: { try await operation() } } public func withTestLogger( key: String, label: String, logLevel: Logger.Level = .debug, dependencies setupDependencies: @escaping (inout DependencyValues) -> Void, operation: @escaping @Sendable () async throws -> Void ) async rethrows { try await withDependencies { $0.logger = .init(label: label) $0.logger[metadataKey: "test"] = "\(key)" $0.logger.logLevel = logLevel setupDependencies(&$0) } operation: { try await operation() } } enum TestSupportError: Error { case optionsNotSet }