Files
nucleic/Tests/NucleicProtocolTests/CBORTests.swift
T
abkslmandClaude Opus 4.8 daeaa13d3d M4: CBOR codec, length-prefixed framing, and the sync wire message set
NucleicProtocol/CBOR: a deterministic Codable CBOR encoder/decoder (value-tree
parse/serialize + Encoder/Decoder adapters) with type-flexible numeric decoding
(so JSONValue's int/double probing round-trips) and sorted map keys. Plus
length-prefixed framing (4-byte BE) with a FrameAccumulator that reassembles
across arbitrary stream chunks and caps frame size.

NucleicProtocol/Sync: the SYNC_PROTOCOL §5 message set — ClientMsg/HostMsg with
tagged Codable, Hello/Welcome handshake, Subscribe/Verbosity, SessionSummary,
SessionSnapshot, EventBatch, WireError, DeviceScope. HostMsg decodes unknown
tags to .unknown for forward compatibility.

15 NucleicProtocol tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-13 00:34:52 -07:00

92 lines
3.4 KiB
Swift

import Foundation
import Testing
@testable import NucleicProtocol
@Suite struct CBORTests {
private func roundTrip<T: Codable & Equatable>(_ value: T) throws -> T {
let data = try CBOREncoder().encode(value)
return try CBORDecoder().decode(T.self, from: data)
}
@Test func primitivesRoundTrip() throws {
#expect(try roundTrip(true) == true)
#expect(try roundTrip("héllo • world") == "héllo • world")
#expect(try roundTrip(Int(42)) == 42)
#expect(try roundTrip(Int(-7)) == -7)
#expect(try roundTrip(UInt64.max) == UInt64.max)
#expect(try roundTrip(Double(3.14159)) == 3.14159)
let ints: [Int] = [1, 2, 3]
#expect(try roundTrip(ints) == ints)
let dict: [String: Int] = ["a": 1, "b": 2]
#expect(try roundTrip(dict) == dict)
}
@Test func optionalsAndNil() throws {
struct Box: Codable, Equatable { var a: Int?; var b: String? }
#expect(try roundTrip(Box(a: nil, b: "x")) == Box(a: nil, b: "x"))
#expect(try roundTrip(Box(a: 5, b: nil)) == Box(a: 5, b: nil))
}
@Test func jsonValueRoundTripsThroughCBOR() throws {
let v: JSONValue = [
"tool": "Bash",
"argv": ["git", "status"],
"nested": ["count": 3, "ok": true, "ratio": 0.5, "missing": nil],
]
#expect(try roundTrip(v) == v)
}
@Test func wholeNumbersDecodeAsIntegers() throws {
// JSONValue encodes whole numbers as ints; ensure they probe back as .number.
let v: JSONValue = ["exitCode": 0, "tokens": 12345]
let back = try roundTrip(v)
#expect(back["exitCode"]?.intValue == 0)
#expect(back["tokens"]?.intValue == 12345)
}
@Test func agentEventRoundTrips() throws {
let event = AgentEvent(
sessionID: SessionID(rawValue: "s1"),
seq: 99,
at: Date(timeIntervalSince1970: 1_700_000_000),
backend: .claudeCode,
nativeType: "assistant",
kind: .toolCallStarted(ToolCall(
toolCallID: "t1", name: "Bash",
input: ["command": "ls -la"], parentToolCallID: nil)))
let back = try roundTrip(event)
#expect(back == event)
}
@Test func mapKeyOrderIsDeterministic() throws {
// Same logical object, different dict literal order → identical bytes.
let a: JSONValue = ["z": 1, "a": 2, "m": 3]
let b: JSONValue = ["a": 2, "m": 3, "z": 1]
let ea = try CBOREncoder().encode(a)
let eb = try CBOREncoder().encode(b)
#expect(ea == eb)
}
@Test func framingReassemblesAcrossChunks() throws {
let payloads = [Data("alpha".utf8), Data("bravo-bravo".utf8), Data([], )]
var stream = Data()
for p in payloads { stream.append(WireFraming.frame(p)) }
let acc = FrameAccumulator()
var got: [Data] = []
// Feed one byte at a time to stress boundary handling.
for byte in stream {
got.append(contentsOf: try acc.push(Data([byte])))
}
#expect(got == payloads)
}
@Test func framingRejectsOversizeLength() throws {
let acc = FrameAccumulator(maxFrameSize: 8)
var bogus = Data([0x00, 0x00, 0x10, 0x00]) // claims 4096 bytes
bogus.append(Data(repeating: 0, count: 10))
#expect(throws: FrameAccumulator.FramingError.self) { try acc.push(bogus) }
}
}