native macOS codings agent orchestrator prowl.onev.cat
Something went wrong. Try again.
7.9 kB · 248 lines
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249import Foundationimport ProwlCLISharedimport Testing
@testable import supacode
@MainActorstruct CLIKeyCommandHandlerTests {
// MARK: - Helpers
private static let testPaneID = UUID(uuidString: "6E1A2A10-D99F-4E3F-920C-D93AA3C05764")! private static let testTabID = UUID(uuidString: "2FC00CF0-3974-4E1B-BEF8-7A08A8E3B7C0")!
private static func makeTarget() -> KeyResolvedTarget { KeyResolvedTarget( worktreeID: "Prowl:/Users/onevcat/Projects/Prowl", worktreeName: "Prowl", worktreePath: "/Users/onevcat/Projects/Prowl", worktreeRootPath: "/Users/onevcat/Projects/Prowl", worktreeKind: .git, tabID: testTabID, tabTitle: "Prowl 1", tabSelected: true, paneID: testPaneID, paneTitle: "zsh", paneCWD: "/Users/onevcat/Projects/Prowl", paneFocused: true ) }
private static func makeHandler( resolveResult: Result<KeyResolvedTarget, TargetResolverError> = .success(makeTarget()), deliverySuccess: Bool = true, keyDelivery: (@MainActor (KeyResolvedTarget, String, Int) -> KeyDeliveryResult)? = nil ) -> KeyCommandHandler { KeyCommandHandler( resolveProvider: { _ in resolveResult }, keyDelivery: keyDelivery ?? { _, _, repeatCount in KeyDeliveryResult( attempted: repeatCount, delivered: deliverySuccess ? repeatCount : 0 ) } ) }
private static func makeEnvelope( rawToken: String = "enter", token: String = "enter", repeatCount: Int = 1, selector: TargetSelector = .none ) -> CommandEnvelope { CommandEnvelope( output: .json, command: .key( KeyInput( selector: selector, rawToken: rawToken, token: token, repeatCount: repeatCount )) ) }
// MARK: - Success tests
@Test func successfulKeyDelivery() async throws { let handler = Self.makeHandler() let response = await handler.handle(envelope: Self.makeEnvelope())
#expect(response.ok) #expect(response.command == "key") #expect(response.schemaVersion == "prowl.cli.key.v1")
let payload = try #require(try response.data?.decode(as: KeyCommandPayload.self)) #expect(payload.requested.token == "enter") #expect(payload.requested.repeat == 1) #expect(payload.key.normalized == "enter") #expect(payload.key.category == .editing) #expect(payload.delivery.attempted == 1) #expect(payload.delivery.delivered == 1) #expect(payload.delivery.mode == "keyDownUp") #expect(payload.target.worktree.id == "Prowl:/Users/onevcat/Projects/Prowl") #expect(payload.target.worktree.kind == "git") #expect(payload.target.tab.id == Self.testTabID.uuidString) #expect(payload.target.tab.selected == true) #expect(payload.target.pane.id == Self.testPaneID.uuidString) #expect(payload.target.pane.focused == true) }
@Test func repeatCountPassesThroughToDelivery() async throws { var deliveredRepeatCount: Int? let handler = Self.makeHandler( keyDelivery: { _, _, repeatCount in deliveredRepeatCount = repeatCount return KeyDeliveryResult(attempted: repeatCount, delivered: repeatCount) } ) let response = await handler.handle( envelope: Self.makeEnvelope(repeatCount: 5) )
#expect(response.ok) #expect(deliveredRepeatCount == 5) let payload = try #require(try response.data?.decode(as: KeyCommandPayload.self)) #expect(payload.requested.repeat == 5) #expect(payload.delivery.attempted == 5) #expect(payload.delivery.delivered == 5) }
@Test func rawTokenPreservedInResponse() async throws { let handler = Self.makeHandler() let response = await handler.handle( envelope: Self.makeEnvelope(rawToken: "Return", token: "enter") )
#expect(response.ok) let payload = try #require(try response.data?.decode(as: KeyCommandPayload.self)) #expect(payload.requested.token == "Return") #expect(payload.key.normalized == "enter") }
@Test func deliveryReceivesCorrectTokenAndTarget() async throws { var deliveredToken: String? var deliveredTarget: KeyResolvedTarget? let handler = Self.makeHandler( keyDelivery: { target, token, repeatCount in deliveredTarget = target deliveredToken = token return KeyDeliveryResult(attempted: repeatCount, delivered: repeatCount) } ) _ = await handler.handle( envelope: Self.makeEnvelope(token: "ctrl-c") )
#expect(deliveredToken == "ctrl-c") #expect(deliveredTarget?.paneID == Self.testPaneID) }
// MARK: - Category tests
@Test func navigationCategory() async throws { let handler = Self.makeHandler() let response = await handler.handle( envelope: Self.makeEnvelope(token: "up") )
#expect(response.ok) let payload = try #require(try response.data?.decode(as: KeyCommandPayload.self)) #expect(payload.key.category == .navigation) }
@Test func controlCategory() async throws { let handler = Self.makeHandler() let response = await handler.handle( envelope: Self.makeEnvelope(token: "ctrl-c") )
#expect(response.ok) let payload = try #require(try response.data?.decode(as: KeyCommandPayload.self)) #expect(payload.key.category == .control) }
@Test func editingCategory() async throws { let handler = Self.makeHandler() let response = await handler.handle( envelope: Self.makeEnvelope(token: "backspace") )
#expect(response.ok) let payload = try #require(try response.data?.decode(as: KeyCommandPayload.self)) #expect(payload.key.category == .editing) }
// MARK: - Error tests
@Test func deliveryFailureReturnsError() async throws { let handler = Self.makeHandler(deliverySuccess: false) let response = await handler.handle( envelope: Self.makeEnvelope(repeatCount: 3) )
#expect(response.ok == false) #expect(response.error?.code == CLIErrorCode.keyDeliveryFailed) }
@Test func partialDeliveryReturnsError() async throws { let handler = Self.makeHandler( keyDelivery: { _, _, repeatCount in KeyDeliveryResult(attempted: repeatCount, delivered: repeatCount - 1) } ) let response = await handler.handle( envelope: Self.makeEnvelope(repeatCount: 3) )
#expect(response.ok == false) #expect(response.error?.code == CLIErrorCode.keyDeliveryFailed) }
@Test func noActivePaneWhenNoSelector() async throws { let handler = Self.makeHandler( resolveResult: .failure(.notFound("No focused pane in selected tab.")) ) let response = await handler.handle( envelope: Self.makeEnvelope(selector: .none) )
#expect(response.ok == false) #expect(response.error?.code == CLIErrorCode.noActivePane) }
@Test func targetNotFoundWithExplicitSelector() async throws { let handler = Self.makeHandler( resolveResult: .failure(.notFound("Worktree 'missing' not found.")) ) let response = await handler.handle( envelope: Self.makeEnvelope(selector: .worktree("missing")) )
#expect(response.ok == false) #expect(response.error?.code == CLIErrorCode.targetNotFound) }
@Test func targetNotUniqueError() async throws { let handler = Self.makeHandler( resolveResult: .failure(.notUnique("Worktree 'Prowl' matches 2 worktrees.")) ) let response = await handler.handle( envelope: Self.makeEnvelope(selector: .worktree("Prowl")) )
#expect(response.ok == false) #expect(response.error?.code == CLIErrorCode.targetNotUnique) }
@Test func unsupportedKeyReturnsError() async throws { let handler = Self.makeHandler() let response = await handler.handle( envelope: Self.makeEnvelope(token: "hyper-k") )
#expect(response.ok == false) #expect(response.error?.code == CLIErrorCode.unsupportedKey) }}