native macOS codings agent orchestrator prowl.onev.cat
Something went wrong. Try again.
9.8 kB · 265 lines
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266import AppKitimport ComposableArchitectureimport DependenciesTestSupportimport Foundationimport ProwlCLISharedimport Testing
@testable import supacode
@MainActorstruct AppFeatureDefaultEditorTests { nonisolated private static var xcodeInstalled: Bool { NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.apple.dt.Xcode") != nil } @Test(.dependencies) func defaultEditorAppliesToAutomaticRepositorySettings() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState(worktree: worktree) let storage = SettingsTestStorage() let settingsFileURL = URL( fileURLWithPath: "/tmp/supacode-settings-\(UUID().uuidString).json" ) let store = withDependencies { $0.settingsFileStorage = storage.storage $0.settingsFileURL = settingsFileURL } operation: { var settings = GlobalSettings.default settings.defaultEditorID = OpenWorktreeAction.finder.settingsID @Shared(.settingsFile) var settingsFile $settingsFile.withLock { $0.global = settings } return TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State(settings: settings) ) ) { AppFeature() } }
await store.send(.repositories(.delegate(.selectedWorktreeChanged(worktree)))) await store.receive(\.worktreeSettingsLoaded) await store.receive(\.worktreeUserSettingsLoaded) #expect(store.state.openActionSelection == .finder) #expect(store.state.selectedRunScript == "") await store.finish() }
@Test(.dependencies) func repositoryLocalSettingsOverrideGlobalRepositorySettings() async throws { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState(worktree: worktree) let settingsStorage = SettingsTestStorage() let localStorage = RepositoryLocalSettingsTestStorage() let settingsFileURL = URL( fileURLWithPath: "/tmp/supacode-settings-\(UUID().uuidString).json" ) let repositoryID = worktree.repositoryRootURL.standardizedFileURL.path(percentEncoded: false) var globalRepositorySettings = RepositorySettings.default globalRepositorySettings.openActionID = OpenWorktreeAction.finder.settingsID var localRepositorySettings = RepositorySettings.default localRepositorySettings.openActionID = OpenWorktreeAction.terminal.settingsID localRepositorySettings.runScript = "pnpm dev"
withDependencies { $0.settingsFileStorage = settingsStorage.storage $0.settingsFileURL = settingsFileURL $0.repositoryLocalSettingsStorage = localStorage.storage } operation: { @Shared(.settingsFile) var settingsFile $settingsFile.withLock { $0.repositories[repositoryID] = globalRepositorySettings } }
let encoder = JSONEncoder() encoder.outputFormatting = [.prettyPrinted, .sortedKeys] try localStorage.save( encoder.encode(localRepositorySettings), at: SupacodePaths.repositorySettingsURL(for: worktree.repositoryRootURL) )
let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } withDependencies: { $0.settingsFileStorage = settingsStorage.storage $0.settingsFileURL = settingsFileURL $0.repositoryLocalSettingsStorage = localStorage.storage }
await store.send(.repositories(.delegate(.selectedWorktreeChanged(worktree)))) await store.receive(\.worktreeSettingsLoaded) { $0.openActionSelection = .terminal $0.openActionIsAutomatic = false $0.selectedRunScript = "pnpm dev" } await store.receive(\.worktreeUserSettingsLoaded) await store.finish() }
@Test(.dependencies, .enabled(if: xcodeInstalled)) func automaticSelectionPrefersXcodeForSwiftPackageWorktree() async throws { let worktree = makeWorktree() let fileManager = FileManager.default try fileManager.createDirectory( at: worktree.workingDirectory, withIntermediateDirectories: true ) defer { try? fileManager.removeItem(at: worktree.repositoryRootURL) } try Data().write(to: worktree.workingDirectory.appending(path: "Package.swift")) let repositoriesState = makeRepositoriesState(worktree: worktree) let storage = SettingsTestStorage() let settingsFileURL = URL( fileURLWithPath: "/tmp/supacode-settings-\(UUID().uuidString).json" ) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } withDependencies: { $0.settingsFileStorage = storage.storage $0.settingsFileURL = settingsFileURL }
await store.send(.repositories(.delegate(.selectedWorktreeChanged(worktree)))) await store.receive(\.worktreeSettingsLoaded) { $0.openActionSelection = .xcode } await store.receive(\.worktreeUserSettingsLoaded) await store.finish() }
@Test(.dependencies) func selectedWorktreeChangedOnlyUpdatesWatcherSelection() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState(worktree: worktree) let expectedOpenActionSelection = OpenWorktreeAction.preferredDefault() let watcherCommands = LockIsolated<[WorktreeInfoWatcherClient.Command]>([]) let storage = SettingsTestStorage() let settingsFileURL = URL( fileURLWithPath: "/tmp/supacode-settings-\(UUID().uuidString).json" ) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } withDependencies: { $0.repositoryPersistence.saveLastFocusedWorktreeID = { _ in } $0.terminalClient.send = { _ in } $0.worktreeInfoWatcher.send = { command in watcherCommands.withValue { $0.append(command) } } $0.settingsFileStorage = storage.storage $0.settingsFileURL = settingsFileURL }
await store.send(.repositories(.delegate(.selectedWorktreeChanged(worktree)))) await store.receive(\.worktreeSettingsLoaded) { $0.openActionSelection = expectedOpenActionSelection } await store.receive(\.worktreeUserSettingsLoaded) await store.finish()
#expect(watcherCommands.value == [.setSelectedWorktreeID(worktree.id)]) }
@Test(.dependencies) func selectingAppPinsItAndClearsAutomatic() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState(worktree: worktree) let storage = SettingsTestStorage() let localStorage = RepositoryLocalSettingsTestStorage() let settingsFileURL = URL( fileURLWithPath: "/tmp/supacode-settings-\(UUID().uuidString).json" ) let store = TestStore( initialState: AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State() ) ) { AppFeature() } withDependencies: { $0.settingsFileStorage = storage.storage $0.settingsFileURL = settingsFileURL $0.repositoryLocalSettingsStorage = localStorage.storage }
await store.send(.openActionSelectionChanged(.terminal)) { $0.openActionSelection = .terminal $0.openActionIsAutomatic = false } await store.finish() }
@Test(.dependencies) func resetToAutomaticClearsRepositoryPinAndReopens() async { let worktree = makeWorktree() let repositoriesState = makeRepositoriesState(worktree: worktree) let storage = SettingsTestStorage() let localStorage = RepositoryLocalSettingsTestStorage() let settingsFileURL = URL( fileURLWithPath: "/tmp/supacode-settings-\(UUID().uuidString).json" ) let store = withDependencies { $0.settingsFileStorage = storage.storage $0.settingsFileURL = settingsFileURL $0.repositoryLocalSettingsStorage = localStorage.storage } operation: { var settings = GlobalSettings.default settings.defaultEditorID = OpenWorktreeAction.finder.settingsID @Shared(.settingsFile) var settingsFile $settingsFile.withLock { $0.global = settings } var initialState = AppFeature.State( repositories: repositoriesState, settings: SettingsFeature.State(settings: settings) ) // Simulate a worktree whose repository has pinned a specific app. initialState.openActionSelection = .terminal initialState.openActionIsAutomatic = false return TestStore(initialState: initialState) { AppFeature() } } store.exhaustivity = .off
await store.send(.openActionResetToAutomatic) { $0.openActionSelection = .finder $0.openActionIsAutomatic = true } await store.receive(\.openSelectedWorktree) await store.receive(\.openWorktree) }
private func makeWorktree() -> Worktree { let repositoryRootURL = URL(fileURLWithPath: "/tmp/repo-\(UUID().uuidString)") let worktreeURL = repositoryRootURL.appending(path: "wt-1") return Worktree( id: worktreeURL.path(percentEncoded: false), name: "wt-1", detail: "detail", workingDirectory: worktreeURL, repositoryRootURL: repositoryRootURL ) }
private func makeRepositoriesState(worktree: Worktree) -> RepositoriesFeature.State { let repository = Repository( id: worktree.repositoryRootURL.path(percentEncoded: false), rootURL: worktree.repositoryRootURL, name: "repo", worktrees: [worktree] ) var repositoriesState = RepositoriesFeature.State() repositoriesState.repositories = [repository] repositoriesState.selection = .worktree(worktree.id) return repositoriesState }}