108 lines
3.7 KiB
Swift
108 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)
|
||
|
|
}
|
||
|
|
}
|