native macOS codings agent orchestrator prowl.onev.cat
Something went wrong. Try again.
11 kB · 341 lines
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342import ComposableArchitectureimport DependenciesTestSupportimport Foundationimport IdentifiedCollectionsimport ProwlCLISharedimport Testing
@testable import supacode
@MainActorstruct AppFeatureTerminalSetupScriptTests { @Test(.dependencies) func newTerminalConsumesSetupScriptAndSendsCreateTabWithFlag() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState( worktree: worktree, pendingSetupScript: true, selected: true ) let sent = LockIsolated<[TerminalClient.Command]>([]) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } withDependencies: { $0.terminalClient.send = { command in sent.withValue { $0.append(command) } } }
await store.send(.newTerminal) await store.send(.terminalEvent(.setupScriptConsumed(worktreeID: worktree.id))) await store.receive(\.repositories.worktreeCreation.consumeSetupScript) { $0.repositories.pendingSetupScriptWorktreeIDs.remove(worktree.id) } await store.finish() #expect(sent.value == [.createTab(worktree, runSetupScriptIfNew: true)]) }
@Test(.dependencies) func newTerminalWithoutSetupScriptDoesNotConsume() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState( worktree: worktree, pendingSetupScript: false, selected: true ) let sent = LockIsolated<[TerminalClient.Command]>([]) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } withDependencies: { $0.terminalClient.send = { command in sent.withValue { $0.append(command) } } }
await store.send(.newTerminal) await store.finish() #expect(sent.value == [.createTab(worktree, runSetupScriptIfNew: false)]) }
@Test(.dependencies) func tabCreatedDoesNotConsumeSetupScript() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState( worktree: worktree, pendingSetupScript: true, selected: true ) let watcherCommands = LockIsolated<[WorktreeInfoWatcherClient.Command]>([]) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } withDependencies: { $0.worktreeInfoWatcher.send = { command in watcherCommands.withValue { $0.append(command) } } }
await store.send(.terminalEvent(.tabCreated(worktreeID: worktree.id))) await store.receive(\.repositories.markWorktreeOpened) { $0.repositories.openedWorktreeIDs = [worktree.id] } #expect(store.state.repositories.pendingSetupScriptWorktreeIDs.contains(worktree.id)) await store.finish() #expect(watcherCommands.value == [.setOpenedWorktreeIDs([worktree.id])]) }
@Test(.dependencies) func tabClosedSyncsOpenedWorktreesToInfoWatcher() async { let worktree = makeWorktree() var repositoriesState = makeRepositoriesState( worktree: worktree, pendingSetupScript: false, selected: true ) repositoriesState.openedWorktreeIDs = [worktree.id] let watcherCommands = LockIsolated<[WorktreeInfoWatcherClient.Command]>([]) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } withDependencies: { $0.worktreeInfoWatcher.send = { command in watcherCommands.withValue { $0.append(command) } } }
await store.send(.terminalEvent(.tabClosed(worktreeID: worktree.id, remainingTabs: 0))) await store.receive(\.repositories.markWorktreeClosed) { $0.repositories.openedWorktreeIDs = [] } await store.finish() #expect(watcherCommands.value == [.setOpenedWorktreeIDs([])]) }
@Test(.dependencies) func tabRestoredSelectsTheRestoredWorktree() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState( worktree: worktree, pendingSetupScript: false, selected: false ) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } store.exhaustivity = .off
await store.send(.terminalEvent(.tabRestored(worktreeID: worktree.id, tabID: TerminalTabID()))) await store.receive(\.repositories.selectWorktree)
#expect(store.state.repositories.selection == .worktree(worktree.id)) #expect(store.state.repositories.openedWorktreeIDs.contains(worktree.id)) }
@Test(.dependencies) func tabRestoredForUnknownWorktreeDoesNothing() async { let worktree = makeWorktree() let store = TestStore( initialState: AppFeature.State( repositories: makeRepositoriesState(worktree: worktree, pendingSetupScript: false, selected: false), settings: SettingsFeature.State() ) ) { AppFeature() }
await store.send(.terminalEvent(.tabRestored(worktreeID: "/tmp/repo/missing", tabID: TerminalTabID()))) await store.finish() }
@Test(.dependencies) func tabRestoredIntoTheSelectedWorktreeSendsNothing() async { let worktree = makeWorktree() let store = TestStore( initialState: AppFeature.State( repositories: makeRepositoriesState(worktree: worktree, pendingSetupScript: false, selected: true), settings: SettingsFeature.State() ) ) { AppFeature() }
await store.send(.terminalEvent(.tabRestored(worktreeID: worktree.id, tabID: TerminalTabID()))) await store.finish() }
@Test(.dependencies) func tabRestoredInCanvasRequestsTheCardFocus() async { let worktree = makeWorktree() var repositoriesState = makeRepositoriesState(worktree: worktree, pendingSetupScript: false, selected: false) repositoriesState.selection = .canvas let tabID = TerminalTabID() let store = TestStore( initialState: AppFeature.State(repositories: repositoriesState, settings: SettingsFeature.State()) ) { AppFeature() } store.exhaustivity = .off
await store.send(.terminalEvent(.tabRestored(worktreeID: worktree.id, tabID: tabID))) await store.receive(\.repositories.newTerminalTabCreatedInCanvas)
#expect(store.state.repositories.pendingCanvasFocusRequest?.target == .tab(tabID)) #expect(store.state.repositories.selection == .canvas) }
@Test(.dependencies) func setupScriptConsumedEventClearsPending() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState( worktree: worktree, pendingSetupScript: true, selected: true ) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() }
await store.send(.terminalEvent(.setupScriptConsumed(worktreeID: worktree.id))) await store.receive(\.repositories.worktreeCreation.consumeSetupScript) { $0.repositories.pendingSetupScriptWorktreeIDs.remove(worktree.id) } await store.finish() }
@Test(.dependencies) func worktreeCreatedTriggersEnsureInitialTabWithSetupScriptFlag() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState( worktree: worktree, pendingSetupScript: true, selected: false ) let sent = LockIsolated<[TerminalClient.Command]>([]) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } withDependencies: { $0.terminalClient.send = { command in sent.withValue { $0.append(command) } } }
await store.send(.repositories(.delegate(.worktreeCreated(worktree)))) await store.finish() #expect( sent.value == [ .ensureInitialTab(worktree, runSetupScriptIfNew: true, focusing: false) ] ) }
@Test(.dependencies) func worktreeCreatedSkipsSetupScriptFlagWhenNotPending() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState( worktree: worktree, pendingSetupScript: false, selected: false ) let sent = LockIsolated<[TerminalClient.Command]>([]) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } withDependencies: { $0.terminalClient.send = { command in sent.withValue { $0.append(command) } } }
await store.send(.repositories(.delegate(.worktreeCreated(worktree)))) await store.finish() #expect( sent.value == [ .ensureInitialTab(worktree, runSetupScriptIfNew: false, focusing: false) ] ) }
private func makeWorktree() -> Worktree { Worktree( id: "/tmp/repo/wt-1", name: "wt-1", detail: "detail", workingDirectory: URL(fileURLWithPath: "/tmp/repo/wt-1"), repositoryRootURL: URL(fileURLWithPath: "/tmp/repo") ) }
// Round 3 review finding: plain folders in Canvas. @Test(.dependencies) func tabRestoredInCanvasRequestsTheCardFocusForAPlainFolder() async { let repository = Repository( id: "/tmp/plain-folder", rootURL: URL(fileURLWithPath: "/tmp/plain-folder"), name: "plain-folder", kind: .plain, worktrees: [] ) var repositoriesState = RepositoriesFeature.State() repositoriesState.repositories = [repository] repositoriesState.selection = .canvas let tabID = TerminalTabID() let store = TestStore( initialState: AppFeature.State(repositories: repositoriesState, settings: SettingsFeature.State()) ) { AppFeature() } store.exhaustivity = .off
await store.send(.terminalEvent(.tabRestored(worktreeID: repository.id, tabID: tabID))) await store.receive(\.repositories.newTerminalTabCreatedInCanvas)
#expect(store.state.repositories.pendingCanvasFocusRequest?.target == .tab(tabID)) }
private func makeRepositoriesState( worktree: Worktree, pendingSetupScript: Bool, selected: Bool ) -> RepositoriesFeature.State { let repository = Repository( id: "/tmp/repo", rootURL: URL(fileURLWithPath: "/tmp/repo"), name: "repo", worktrees: [worktree] ) var repositoriesState = RepositoriesFeature.State() repositoriesState.repositories = [repository] if selected { repositoriesState.selection = .worktree(worktree.id) } if pendingSetupScript { repositoriesState.pendingSetupScriptWorktreeIDs = [worktree.id] } return repositoriesState }}