fix(mac): avoid crash decoding gateway frames
parent
1f19ca1665
commit
fcc8d59588
|
|
@ -62,7 +62,7 @@ let package = Package(
|
||||||
]),
|
]),
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "ClawdisIPCTests",
|
name: "ClawdisIPCTests",
|
||||||
dependencies: ["ClawdisIPC", "Clawdis"],
|
dependencies: ["ClawdisIPC", "Clawdis", "ClawdisProtocol"],
|
||||||
swiftSettings: [
|
swiftSettings: [
|
||||||
.enableUpcomingFeature("StrictConcurrency"),
|
.enableUpcomingFeature("StrictConcurrency"),
|
||||||
.enableExperimentalFeature("SwiftTesting"),
|
.enableExperimentalFeature("SwiftTesting"),
|
||||||
|
|
|
||||||
|
|
@ -500,7 +500,12 @@ public enum GatewayFrame: Codable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func decodePayload<T: Decodable>(_ type: T.Type, from raw: [String: AnyCodable]) throws -> T {
|
private static func decodePayload<T: Decodable>(_ type: T.Type, from raw: [String: AnyCodable]) throws -> T {
|
||||||
let data = try JSONSerialization.data(withJSONObject: raw)
|
// Re-encode the already-decoded map using `JSONEncoder` instead of
|
||||||
|
// `JSONSerialization` because `AnyCodable` values are not bridged to
|
||||||
|
// Objective-C types and `JSONSerialization` throws an ObjC exception,
|
||||||
|
// crashing the app (seen on macOS 26.1). `JSONEncoder` understands
|
||||||
|
// `Encodable` values and stays in Swift land.
|
||||||
|
let data = try JSONEncoder().encode(raw)
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
return try decoder.decode(T.self, from: data)
|
return try decoder.decode(T.self, from: data)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
import ClawdisProtocol
|
||||||
|
|
||||||
|
@Suite struct GatewayFrameDecodeTests {
|
||||||
|
@Test func decodesEventFrameWithAnyCodablePayload() throws {
|
||||||
|
let json = """
|
||||||
|
{
|
||||||
|
"type": "event",
|
||||||
|
"event": "presence",
|
||||||
|
"payload": { "foo": "bar", "count": 1 },
|
||||||
|
"seq": 7
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let frame = try JSONDecoder().decode(GatewayFrame.self, from: Data(json.utf8))
|
||||||
|
|
||||||
|
#expect({
|
||||||
|
if case .event = frame { true } else { false }
|
||||||
|
}(), "expected .event frame")
|
||||||
|
|
||||||
|
guard case let .event(evt) = frame else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let payload = evt.payload?.value as? [String: AnyCodable]
|
||||||
|
#expect(payload?["foo"]?.value as? String == "bar")
|
||||||
|
#expect(payload?["count"]?.value as? Int == 1)
|
||||||
|
#expect(evt.seq == 7)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue