rainbow-dragon/Tests/ForgeCameraARRITests/CAPProtocolTests.swift

107 lines
3.7 KiB
Swift

import XCTest
import Foundation
@testable import ForgeCameraARRI
final class CAPProtocolTests: XCTestCase {
// Frame encode: length includes 7-byte header, big-endian fields.
func testEncodeFrame() {
let frame = CAP.Frame(
msgType: CAP.MsgType.command.rawValue,
msgId: 0x1234,
cmdCode: CAP.Command.live.rawValue,
payload: Data([0xAA, 0xBB]))
let data = CAP.encode(frame)
XCTAssertEqual([UInt8](data), [
0x00, 0x09, // length 9 = 7 + 2
0x01, // COMMAND
0x12, 0x34, // msgId
0x00, 0x80, // Live
0xAA, 0xBB,
])
}
// Round trip.
func testDecodeRoundTrip() throws {
let frame = CAP.Frame(msgType: 0x02, msgId: 7, cmdCode: 0x0000, payload: Data([1, 2, 3]))
var buf = CAP.encode(frame)
let decoded = try XCTUnwrap(CAP.decodeFirst(&buf))
XCTAssertEqual(decoded, frame)
XCTAssertTrue(buf.isEmpty)
}
// Partial frame buffers.
func testPartialFrame() throws {
let full = CAP.encode(CAP.Frame(msgType: 0x01, msgId: 1, cmdCode: 0x0080))
var buf = Data(full.prefix(4))
XCTAssertNil(try CAP.decodeFirst(&buf))
buf.append(full.suffix(from: 4))
XCTAssertNotNil(try CAP.decodeFirst(&buf))
}
// Two frames in one buffer.
func testTwoFrames() throws {
var buf = CAP.encode(CAP.Frame(msgType: 0x01, msgId: 1, cmdCode: 0x0080))
buf.append(CAP.encode(CAP.Frame(msgType: 0x01, msgId: 2, cmdCode: 0x0090)))
let f1 = try XCTUnwrap(CAP.decodeFirst(&buf))
let f2 = try XCTUnwrap(CAP.decodeFirst(&buf))
XCTAssertEqual(f1.msgId, 1)
XCTAssertEqual(f2.msgId, 2)
}
// Bogus length rejected.
func testShortLengthRejected() {
var buf = Data([0x00, 0x03, 0x01])
XCTAssertThrowsError(try CAP.decodeFirst(&buf))
}
// CAP string encoding.
func testStringCodec() {
var data = Data()
CAP.putString("Forge", into: &data)
XCTAssertEqual([UInt8](data.prefix(2)), [0x00, 0x05])
let read = CAP.readString(data, at: 0)
XCTAssertEqual(read?.value, "Forge")
XCTAssertEqual(read?.consumed, 7)
}
// BCD timecode.
func testTimecodeBCD() {
// 12:34:56:23 -> BCD 0x12345623
XCTAssertEqual(CAP.decodeTimecodeBCD(0x12345623), "12:34:56:23")
XCTAssertEqual(CAP.encodeTimecodeBCD("12:34:56:23"), 0x12345623)
XCTAssertEqual(CAP.decodeTimecodeBCD(CAP.encodeTimecodeBCD("09:59:00:01")!), "09:59:00:01")
}
// CDL blob: 10 F32 big-endian, 40 bytes.
func testCDLBlob() {
let blob = CAP.encodeCDLBlob(
slope: (1.1, 1.0, 0.9),
offset: (0.01, 0.0, -0.01),
power: (0.95, 1.0, 1.05),
saturation: 1.2)
XCTAssertEqual(blob.count, 40)
let values = CAP.decodeCDLBlob(blob)!
XCTAssertEqual(values[0], 1.1, accuracy: 1e-6)
XCTAssertEqual(values[2], 0.9, accuracy: 1e-6)
XCTAssertEqual(values[5], -0.01, accuracy: 1e-6)
XCTAssertEqual(values[9], 1.2, accuracy: 1e-6)
}
// Camera state bitfield.
func testCameraStateBits() {
let bits = CAP.CameraStateBits(rawValue: 0x0005)
XCTAssertTrue(bits.contains(.recording))
XCTAssertTrue(bits.contains(.standbyReady))
XCTAssertFalse(bits.contains(.playback))
}
// U32/F32 round trip.
func testNumericCodecs() {
var data = Data()
CAP.putU32(0xDEADBEEF, into: &data)
CAP.putF32(3.14159, into: &data)
XCTAssertEqual(CAP.readU32(data, at: 0), 0xDEADBEEF)
XCTAssertEqual(CAP.readF32(data, at: 4) ?? 0, 3.14159, accuracy: 1e-5)
}
}