feat: Moved cli client tests to XCTest to work in docker
Some checks failed
CI / Run Tests (push) Has been cancelled

This commit is contained in:
2024-11-18 15:53:23 -05:00
parent ce18c44363
commit 24f2ad63a7
14 changed files with 227 additions and 486 deletions

2
.gitignore vendored
View File

@@ -5,7 +5,7 @@
xcuserdata/ xcuserdata/
DerivedData/ DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.dewPoint-env .dewPoint-env*
.topics .topics
mqtt_password.txt mqtt_password.txt
.env .env

View File

@@ -1,2 +1,9 @@
disabled_rules: disabled_rules:
- closing_brace - closing_brace
- fuction_body_length
included:
- Sources
- Tests
ignore_multiline_statement_conditions: true

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1610"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "MQTTConnectionService"
BuildableName = "MQTTConnectionService"
BlueprintName = "MQTTConnectionService"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "MQTTConnectionService"
BuildableName = "MQTTConnectionService"
BlueprintName = "MQTTConnectionService"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1610"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "MQTTManager"
BuildableName = "MQTTManager"
BlueprintName = "MQTTManager"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "MQTTManager"
BuildableName = "MQTTManager"
BlueprintName = "MQTTManager"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1330"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Models"
BuildableName = "Models"
BlueprintName = "Models"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Models"
BuildableName = "Models"
BlueprintName = "Models"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1610"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "SensorsService"
BuildableName = "SensorsService"
BlueprintName = "SensorsService"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "SensorsService"
BuildableName = "SensorsService"
BlueprintName = "SensorsService"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -7,6 +7,20 @@
buildImplicitDependencies = "YES" buildImplicitDependencies = "YES"
buildArchitectures = "Automatic"> buildArchitectures = "Automatic">
<BuildActionEntries> <BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CliClient"
BuildableName = "CliClient"
BlueprintName = "CliClient"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry <BuildActionEntry
buildForTesting = "YES" buildForTesting = "YES"
buildForRunning = "YES" buildForRunning = "YES"
@@ -77,48 +91,25 @@
ReferencedContainer = "container:"> ReferencedContainer = "container:">
</BuildableReference> </BuildableReference>
</BuildActionEntry> </BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "IntegrationTests"
BuildableName = "IntegrationTests"
BlueprintName = "IntegrationTests"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CliClient"
BuildableName = "CliClient"
BlueprintName = "CliClient"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries> </BuildActionEntries>
</BuildAction> </BuildAction>
<TestAction <TestAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES"
<TestPlans> shouldAutocreateTestPlan = "YES">
<TestPlanReference
reference = "container:.swiftpm/dewpoint-controller-Package.xctestplan"
default = "YES">
</TestPlanReference>
</TestPlans>
<Testables> <Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CliClientTests"
BuildableName = "CliClientTests"
BlueprintName = "CliClientTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
<TestableReference <TestableReference
skipped = "NO"> skipped = "NO">
<BuildableReference <BuildableReference

View File

@@ -1,78 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1610"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "dewpoint-controller"
BuildableName = "dewpoint-controller"
BlueprintName = "dewpoint-controller"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "dewpoint-controller"
BuildableName = "dewpoint-controller"
BlueprintName = "dewpoint-controller"
ReferencedContainer = "container:">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "dewpoint-controller"
BuildableName = "dewpoint-controller"
BlueprintName = "dewpoint-controller"
ReferencedContainer = "container:">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -48,7 +48,8 @@ let package = Package(
"CliClient" "CliClient"
], ],
resources: [ resources: [
.copy("test.env") .copy("test.env"),
.copy("test-env.json")
] ]
), ),
.executableTarget( .executableTarget(

View File

@@ -67,6 +67,7 @@ public struct CliClient {
self.logger = logger self.logger = logger
self.mqttClientVersion = mqttClientVersion self.mqttClientVersion = mqttClientVersion
} }
} }
} }
@@ -121,8 +122,8 @@ extension EnvVars {
@Dependency(\.environment) var environment @Dependency(\.environment) var environment
let defaultEnvVars = EnvVars() let defaultEnvVars = EnvVars()
let encoder = JSONEncoder() let encoder = environment.jsonEncoder()
let decoder = JSONDecoder() let decoder = environment.jsonDecoder()
let defaultEnvDict = (try? encoder.encode(defaultEnvVars)) let defaultEnvDict = (try? encoder.encode(defaultEnvVars))
.flatMap { try? decoder.decode([String: String].self, from: $0) } .flatMap { try? decoder.decode([String: String].self, from: $0) }

View File

@@ -6,6 +6,11 @@ import Models
@_spi(Internal) @_spi(Internal)
public extension DependencyValues { public extension DependencyValues {
/// A dependecy responsible for loding environment variables.
///
/// This is just used internally of this module, but is useful to
/// override for testing purposes, so import using `@_spi(Internal)`.
var environment: EnvironmentDependency { var environment: EnvironmentDependency {
get { self[EnvironmentDependency.self] } get { self[EnvironmentDependency.self] }
set { self[EnvironmentDependency.self] = newValue } set { self[EnvironmentDependency.self] = newValue }
@@ -19,16 +24,27 @@ public extension DependencyValues {
@DependencyClient @DependencyClient
public struct EnvironmentDependency: Sendable { public struct EnvironmentDependency: Sendable {
/// A json decoder to use to decode files and environment variables.
public var jsonDecoder: @Sendable () -> JSONDecoder = { JSONDecoder() }
/// A json encoder to use to encode files and environment variables.
public var jsonEncoder: @Sendable () -> JSONEncoder = { JSONEncoder() }
/// Load the variables based on the request. /// Load the variables based on the request.
public var load: @Sendable (FileType) async throws -> [String: String] = { _ in [:] } public var load: @Sendable (FileType) async throws -> [String: String] = { _ in [:] }
/// Load the environment variables based on the current process environment.
///
/// You can override this to use an empty environment, which is useful for testing purposes.
public var processInfo: @Sendable () -> [String: String] = { [:] } public var processInfo: @Sendable () -> [String: String] = { [:] }
/// Represents the types of files that can be loaded and decoded into
/// the environment.
public enum FileType: Equatable { public enum FileType: Equatable {
case dotEnv(path: String) case dotEnv(path: String)
case json(path: String) case json(path: String)
init?(path: String) { public init?(path: String) {
let strings = path.split(separator: ".") let strings = path.split(separator: ".")
guard let ext = strings.last else { guard let ext = strings.last else {
return nil return nil
@@ -50,22 +66,39 @@ extension EnvironmentDependency: DependencyKey {
public static let testValue: EnvironmentDependency = Self() public static let testValue: EnvironmentDependency = Self()
public static let liveValue: EnvironmentDependency = Self( public static func live(
load: { file in decoder: JSONDecoder = .init(),
switch file { encoder: JSONEncoder = .init()
case let .dotEnv(path: path): ) -> Self {
let file = try DotEnv.read(path: path) Self(
return file.lines.reduce(into: [String: String]()) { partialResult, line in jsonDecoder: { decoder },
partialResult[line.key] = line.value jsonEncoder: { encoder },
load: { file in
switch file {
case let .dotEnv(path: path):
let file = try DotEnv.read(path: path)
return file.lines.reduce(into: [String: String]()) { partialResult, line in
partialResult[line.key] = line.value
}
case let .json(path: path):
let url = url(for: path)
return try decoder.decode(
[String: String].self,
from: Data(contentsOf: url)
)
} }
case let .json(path: path): },
let url = URL(filePath: path) processInfo: { ProcessInfo.processInfo.environment }
return try JSONDecoder().decode( )
[String: String].self, }
from: Data(contentsOf: url)
) public static let liveValue: EnvironmentDependency = .live()
} }
},
processInfo: { ProcessInfo.processInfo.environment } private func url(for path: String) -> URL {
) #if os(Linux)
return URL(fileURLWithPath: path)
#else
return URL(filePath: path)
#endif
} }

View File

@@ -4,96 +4,139 @@ import Foundation
import Logging import Logging
import Models import Models
import MQTTNIO import MQTTNIO
import Testing import XCTest
@Test final class CliClientTests: XCTestCase {
func checkTesting() {
#expect(Bool(true))
}
@Test( override func invokeTest() {
arguments: [ withDependencies {
(MQTTClient.Version.v3_1_1, ["3", "3.1", "3.1.1", "00367894"]), $0.cliClient = .liveValue
(MQTTClient.Version.v5_0, ["5", "5.1", "5.1.1", "00000500012"]), $0.environment = .liveValue
(nil, ["0", "0.1", "0.1.1", "0000000001267894", "blob"]) $0.environment.processInfo = { [:] }
] } operation: {
) super.invokeTest()
func checkParseMQTTVersion(
version: MQTTClient.Version?,
strings: [String]
) {
withDependencies {
$0.cliClient = .liveValue
} operation: {
@Dependency(\.cliClient) var cliClient
for string in strings {
#expect(cliClient.parseMqttClientVersion(string) == version)
#expect(cliClient.parseMqttClientVersion("v\(string)") == version)
} }
} }
}
@Test( func testParsingMQTTVersion() {
arguments: [
(Logger.Level.debug, EnvVars(appEnv: .staging, logLevel: nil)),
(Logger.Level.debug, EnvVars(appEnv: .development, logLevel: nil)),
(Logger.Level.info, EnvVars(appEnv: .production, logLevel: nil)),
(Logger.Level.trace, EnvVars(appEnv: .testing, logLevel: nil)),
(Logger.Level.info, EnvVars(appEnv: .staging, logLevel: .info)),
(Logger.Level.trace, EnvVars(appEnv: .development, logLevel: .trace)),
(Logger.Level.warning, EnvVars(appEnv: .production, logLevel: .warning)),
(Logger.Level.debug, EnvVars(appEnv: .testing, logLevel: .debug))
]
)
func logLevelFromEnvVars(expectedLevel: Logger.Level, environment: EnvVars) {
withDependencies {
$0.cliClient = .liveValue
} operation: {
@Dependency(\.cliClient) var cliClient @Dependency(\.cliClient) var cliClient
#expect(cliClient.logLevel(environment) == expectedLevel)
}
}
@Test( let arguments = [
arguments: [ (MQTTClient.Version.v3_1_1, ["3", "3.1", "3.1.1", "00367894"]),
( (MQTTClient.Version.v5_0, ["5", "5.1", "5.1.1", "00000500012"]),
CliClient.EnvVarsRequest(envFilePath: nil, logger: nil, version: nil), (nil, ["0", "0.1", "0.1.1", "0000000001267894", "blob"])
EnvVars() ]
),
( for (version, strings) in arguments {
CliClient.EnvVarsRequest(envFilePath: nil, logger: nil, version: "3"), for string in strings {
EnvVars(version: "3") XCTAssertEqual(cliClient.parseMqttClientVersion(string), version)
), }
( }
CliClient.EnvVarsRequest( }
envFilePath: "Tests/CliClientTests/test.env",
logger: nil, func testLogLevelFromEnvironment() {
version: nil @Dependency(\.cliClient) var cliClient
let arguments = [
(Logger.Level.debug, EnvVars(appEnv: .staging, logLevel: nil)),
(Logger.Level.debug, EnvVars(appEnv: .development, logLevel: nil)),
(Logger.Level.info, EnvVars(appEnv: .production, logLevel: nil)),
(Logger.Level.trace, EnvVars(appEnv: .testing, logLevel: nil)),
(Logger.Level.info, EnvVars(appEnv: .staging, logLevel: .info)),
(Logger.Level.trace, EnvVars(appEnv: .development, logLevel: .trace)),
(Logger.Level.warning, EnvVars(appEnv: .production, logLevel: .warning)),
(Logger.Level.debug, EnvVars(appEnv: .testing, logLevel: .debug))
]
for (expected, envVars) in arguments {
XCTAssertEqual(expected, cliClient.logLevel(envVars))
}
}
func testMakeEnvVars() async throws {
@Dependency(\.cliClient) var cliClient
@Dependency(\.environment) var environment
let arguments = [
(
CliClient.EnvVarsRequest(envFilePath: nil, logger: nil, version: nil),
EnvVars()
), ),
EnvVars( (
appEnv: .testing, CliClient.EnvVarsRequest(envFilePath: nil, logger: nil, version: "3"),
host: "test.mqtt", EnvVars(version: "3")
port: "1234", ),
identifier: "testing-mqtt", (
userName: "test-user", CliClient.EnvVarsRequest(
password: "super-secret", envFilePath: "test.env", // Needs to be a bundled resource.
logLevel: .debug, logger: nil,
version: "5.0" version: nil
),
EnvVars.test
),
(
CliClient.EnvVarsRequest(
envFilePath: "test-env.json", // Needs to be a bundled resource.
logger: nil,
version: nil
),
EnvVars.test
) )
) ]
]
) for (request, expectedEnvVars) in arguments {
func checkMakeEnvVars( var request = request
request: CliClient.EnvVarsRequest, if let file = request.envFilePath {
expectedEnvVars: EnvVars request = .init(
) async throws { envFilePath: cleanFilePath(file),
try await withDependencies { logger: request.logger,
$0.cliClient = .liveValue version: request.mqttClientVersion
$0.environment = .liveValue )
$0.environment.processInfo = { [:] } }
} operation: { let result = try await cliClient.makeEnvVars(request)
@Dependency(\.cliClient) var cliClient XCTAssertEqual(result, expectedEnvVars)
let result = try await cliClient.makeEnvVars(request) }
#expect(result == expectedEnvVars) }
func testFileType() {
let arguments = [
(EnvironmentDependency.FileType.dotEnv(path: "test.env"), "test.env"),
(EnvironmentDependency.FileType.json(path: "test.json"), "test.json"),
(nil, "test"),
(nil, "")
]
for (expected, file) in arguments {
XCTAssertEqual(EnvironmentDependency.FileType(path: file), expected)
}
}
func testEnvironmentLiveValueProcessInfo() {
let environment = EnvironmentDependency.liveValue
XCTAssertEqual(environment.processInfo(), ProcessInfo.processInfo.environment)
} }
} }
// - MARK: Helper
private func cleanFilePath(_ path: String) -> String {
let split = path.split(separator: ".")
let fileName = split.first!
let ext = split.last!
let url = Bundle.module.url(forResource: String(fileName), withExtension: String(ext))!.absoluteString
let cleaned = url.split(separator: "file://").last!
return String(cleaned)
}
extension EnvVars {
static let test = EnvVars(
appEnv: .testing,
host: "test.mqtt",
port: "1234",
identifier: "testing-mqtt",
userName: "test-user",
password: "super-secret",
logLevel: .debug,
version: "5.0"
)
}

View File

@@ -0,0 +1,10 @@
{
"APP_ENV": "testing",
"MQTT_HOST": "test.mqtt",
"MQTT_PORT": "1234",
"MQTT_IDENTIFIER": "testing-mqtt",
"MQTT_USERNAME": "test-user",
"MQTT_PASSWORD": "super-secret",
"LOG_LEVEL": "debug",
"MQTT_VERSION": "5.0"
}

View File

@@ -1,5 +1,6 @@
# Used to build a test image. # Used to build a test image.
FROM swift:5.10 ARG SWIFT_IMAGE_VERSION="5.10"
FROM swift:${SWIFT_IMAGE_VERSION}
WORKDIR /app WORKDIR /app
COPY ./Package.* ./ COPY ./Package.* ./
RUN swift package resolve RUN swift package resolve