import XCTest import Foundation #if canImport(FoundationNetworking) import FoundationNetworking #endif import ForgeCamera import ForgeGrade import ForgeColor import ForgeSim @testable import ForgeCameraSony final class SonyDriverTests: XCTestCase { var sim: SonySimulator! override func setUp() async throws { sim = SonySimulator() try await sim.start(port: 0) } override func tearDown() async throws { try? await sim.stop() sim = nil } func makeDriver() async -> SonyDriver { let port = await sim.boundPort! return SonyDriver(host: "127.0.0.1", port: port, pollInterval: .milliseconds(20)) } // Venice 2: NO native CDL — capability-narrow. func testCapabilities() async { let driver = await makeDriver() XCTAssertEqual(driver.capabilities.vendor, .sony) XCTAssertFalse(driver.capabilities.supportsNativeCDL) XCTAssertTrue(driver.capabilities.lut3dSizes.contains(33)) } func testConnectEmitsConnected() async throws { let driver = await makeDriver() var iterator = driver.state.makeAsyncIterator() try await driver.connect() var connected = false for _ in 0..<5 { if let s = await iterator.next(), s.connection == .connected { connected = true break } } XCTAssertTrue(connected) await driver.disconnect() } func testRecStateAndMetadata() async throws { let driver = await makeDriver() var iterator = driver.state.makeAsyncIterator() try await driver.connect() await sim.setState(recording: true, clipName: "C0001", ei: 500, wb: 5500, tint: 1, fps: 24, timecode: "09:15:00:00") var got = false for _ in 0..<30 { if let s = await iterator.next(), s.isRecording { XCTAssertEqual(s.clipName, "C0001") XCTAssertEqual(s.metadata?.exposureIndex, 500) got = true break } } XCTAssertTrue(got) await driver.disconnect() } // LUT-only push accepted. func testPushLutOnly() async throws { let driver = await makeDriver() try await driver.connect() let look = FlattenedLook(cdl: nil, lut: Lut3D.identity(size: 33), latticeSize: 33) try await driver.push(look: look) let count = await sim.uploadedLutCount XCTAssertEqual(count, 1) await driver.disconnect() } // Push with split CDL to a no-native-CDL camera must throw unsupportedLook — // caller (gang layer) is responsible for re-flattening full-bake. func testPushSplitCDLRejected() async throws { let driver = await makeDriver() try await driver.connect() let cdl = CDL(slope: SIMD3(1.2, 1, 1), offset: .zero, power: .one, saturation: 1) let look = FlattenedLook(cdl: cdl, lut: Lut3D.identity(size: 33), latticeSize: 33) do { try await driver.push(look: look) XCTFail("expected unsupportedLook") } catch let e as CameraError { guard case .unsupportedLook = e else { return XCTFail("wrong error") } } await driver.disconnect() } }