feat: Working on sensor client dependency
This commit is contained in:
@@ -12,9 +12,9 @@ import ServiceLifecycle
|
|||||||
@DependencyClient
|
@DependencyClient
|
||||||
public struct SensorsClient: Sendable {
|
public struct SensorsClient: Sendable {
|
||||||
|
|
||||||
public var listen: @Sendable (_ topics: [String]) async throws -> AsyncStream<MQTTPublishInfo>
|
public var listen: @Sendable ([String]) async throws -> AsyncStream<MQTTPublishInfo>
|
||||||
public var logger: Logger?
|
public var logger: Logger?
|
||||||
public var publish: @Sendable (_ value: Double, _ topic: String) async throws -> Void
|
public var publish: @Sendable (Double, String) async throws -> Void
|
||||||
public var shutdown: @Sendable () -> Void = {}
|
public var shutdown: @Sendable () -> Void = {}
|
||||||
|
|
||||||
public func listen(to topics: [String]) async throws -> AsyncStream<MQTTPublishInfo> {
|
public func listen(to topics: [String]) async throws -> AsyncStream<MQTTPublishInfo> {
|
||||||
@@ -45,7 +45,9 @@ public actor SensorsService2: Service {
|
|||||||
|
|
||||||
private var sensors: [TemperatureAndHumiditySensor]
|
private var sensors: [TemperatureAndHumiditySensor]
|
||||||
|
|
||||||
public init(sensors: [TemperatureAndHumiditySensor]) {
|
public init(
|
||||||
|
sensors: [TemperatureAndHumiditySensor]
|
||||||
|
) {
|
||||||
self.sensors = sensors
|
self.sensors = sensors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,7 +143,12 @@ final class SensorsClientTests: XCTestCase {
|
|||||||
let capturedValues = CapturedValues()
|
let capturedValues = CapturedValues()
|
||||||
|
|
||||||
try await withDependencies {
|
try await withDependencies {
|
||||||
$0.sensorsClient = .testing { value, topic in
|
$0.sensorsClient = .testing(
|
||||||
|
yielding: [
|
||||||
|
(value: 76, to: "not-listening"),
|
||||||
|
(value: 75, to: "test")
|
||||||
|
]
|
||||||
|
) { value, topic in
|
||||||
capturedValues.values.append((value, topic))
|
capturedValues.values.append((value, topic))
|
||||||
} captureShutdownEvent: {
|
} captureShutdownEvent: {
|
||||||
capturedValues.didShutdown = $0
|
capturedValues.didShutdown = $0
|
||||||
@@ -151,18 +156,21 @@ final class SensorsClientTests: XCTestCase {
|
|||||||
} operation: {
|
} operation: {
|
||||||
@Dependency(\.sensorsClient) var client
|
@Dependency(\.sensorsClient) var client
|
||||||
let stream = try await client.listen(to: ["test"])
|
let stream = try await client.listen(to: ["test"])
|
||||||
|
|
||||||
for await value in stream {
|
for await value in stream {
|
||||||
var buffer = value.payload
|
var buffer = value.payload
|
||||||
guard let double = Double(buffer: &buffer) else {
|
guard let double = Double(buffer: &buffer) else {
|
||||||
XCTFail("Failed to decode double")
|
XCTFail("Failed to decode double")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(double, 75)
|
XCTAssertEqual(double, 75)
|
||||||
XCTAssertEqual(value.topicName, "test")
|
XCTAssertEqual(value.topicName, "test")
|
||||||
try await client.publish(26, to: "publish")
|
try await client.publish(26, to: "publish")
|
||||||
try await Task.sleep(for: .milliseconds(100))
|
try await Task.sleep(for: .milliseconds(100))
|
||||||
client.shutdown()
|
client.shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(capturedValues.values.count, 1)
|
XCTAssertEqual(capturedValues.values.count, 1)
|
||||||
XCTAssertEqual(capturedValues.values.first?.value, 26)
|
XCTAssertEqual(capturedValues.values.first?.value, 26)
|
||||||
XCTAssertEqual(capturedValues.values.first?.topic, "publish")
|
XCTAssertEqual(capturedValues.values.first?.topic, "publish")
|
||||||
@@ -253,6 +261,7 @@ class PublishInfoContainer {
|
|||||||
extension SensorsClient {
|
extension SensorsClient {
|
||||||
|
|
||||||
static func testing(
|
static func testing(
|
||||||
|
yielding: [(value: Double, to: String)],
|
||||||
capturePublishedValues: @escaping (Double, String) -> Void,
|
capturePublishedValues: @escaping (Double, String) -> Void,
|
||||||
captureShutdownEvent: @escaping (Bool) -> Void
|
captureShutdownEvent: @escaping (Bool) -> Void
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -261,18 +270,17 @@ extension SensorsClient {
|
|||||||
|
|
||||||
return .init(
|
return .init(
|
||||||
listen: { topics in
|
listen: { topics in
|
||||||
guard let topic = topics.randomElement() else {
|
for (value, topic) in yielding where topics.contains(topic) {
|
||||||
throw TopicNotFoundError()
|
continuation.yield(
|
||||||
}
|
MQTTPublishInfo(
|
||||||
continuation.yield(
|
qos: .atLeastOnce,
|
||||||
MQTTPublishInfo(
|
retain: true,
|
||||||
qos: .atLeastOnce,
|
topicName: topic,
|
||||||
retain: true,
|
payload: ByteBuffer(string: "\(value)"),
|
||||||
topicName: topic,
|
properties: MQTTProperties()
|
||||||
payload: ByteBuffer(string: "75"),
|
)
|
||||||
properties: MQTTProperties()
|
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
return stream
|
return stream
|
||||||
},
|
},
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
|||||||
Reference in New Issue
Block a user