mirror of
https://github.com/wu736139669/hapi.git
synced 2026-10-09 19:29:41 +00:00
99 lines
3.4 KiB
Swift
99 lines
3.4 KiB
Swift
import Foundation
|
|
import HapiClient
|
|
import HapiProtocol
|
|
import Testing
|
|
|
|
private struct DirectoryBrowserCall: Equatable, Sendable {
|
|
let machineId: String
|
|
let path: String
|
|
let includeHidden: Bool
|
|
}
|
|
|
|
private actor FakeMachineDirectoryRequester: MachineDirectoryRequesting {
|
|
private(set) var calls: [DirectoryBrowserCall] = []
|
|
|
|
func listMachineDirectory(
|
|
machineId: String,
|
|
path: String,
|
|
includeHidden: Bool
|
|
) async throws -> MachineListDirectoryResponse {
|
|
calls.append(DirectoryBrowserCall(
|
|
machineId: machineId,
|
|
path: path,
|
|
includeHidden: includeHidden
|
|
))
|
|
return MachineListDirectoryResponse(
|
|
success: true,
|
|
entries: [
|
|
MachineDirectoryEntry(name: "repo", type: .directory),
|
|
MachineDirectoryEntry(name: "README.md", type: .file),
|
|
]
|
|
)
|
|
}
|
|
}
|
|
|
|
@MainActor
|
|
private func directoryBrowserEventually(
|
|
timeout: Duration = .seconds(5),
|
|
_ condition: @MainActor () -> Bool
|
|
) async -> Bool {
|
|
let clock = ContinuousClock()
|
|
let deadline = clock.now.advanced(by: timeout)
|
|
while clock.now < deadline {
|
|
if condition() { return true }
|
|
try? await Task.sleep(for: .milliseconds(10))
|
|
}
|
|
return condition()
|
|
}
|
|
|
|
@Suite("RemoteDirectoryBrowserModel")
|
|
@MainActor
|
|
struct RemoteDirectoryBrowserModelTests {
|
|
@Test func pathBoundariesSupportPosixDriveAndUNCPaths() {
|
|
#expect(RemoteDirectoryPath.isWithinRoot(path: "/workspace/repo", root: "/workspace"))
|
|
#expect(!RemoteDirectoryPath.isWithinRoot(path: "/workspace-other/repo", root: "/workspace"))
|
|
#expect(RemoteDirectoryPath.isWithinRoot(path: "/workspace", root: "/"))
|
|
#expect(RemoteDirectoryPath.isWithinRoot(path: "c:\\Work\\Repo", root: "C:\\work"))
|
|
#expect(!RemoteDirectoryPath.isWithinRoot(
|
|
path: "C:\\workspace-other",
|
|
root: "C:\\workspace"
|
|
))
|
|
#expect(RemoteDirectoryPath.isWithinRoot(
|
|
path: "\\\\SERVER\\Share\\Repo",
|
|
root: "\\\\server\\share"
|
|
))
|
|
#expect(RemoteDirectoryPath.parent("C:\\Users") == "C:\\")
|
|
#expect(
|
|
RemoteDirectoryPath.parent("\\\\server\\share\\repo")
|
|
== "\\\\server\\share"
|
|
)
|
|
}
|
|
|
|
@Test func modelOwnsNavigationLoadingAndHiddenDirectoryState() async {
|
|
let requester = FakeMachineDirectoryRequester()
|
|
let model = RemoteDirectoryBrowserModel(requester: requester)
|
|
|
|
model.open(machineId: "machine-1", roots: ["/workspace"], initialPath: "/workspace")
|
|
#expect(await directoryBrowserEventually { !model.isLoading })
|
|
#expect(model.entries.map(\.name) == ["repo"])
|
|
|
|
model.navigate(to: "/workspace-other")
|
|
try? await Task.sleep(for: .milliseconds(20))
|
|
#expect(await requester.calls.count == 1)
|
|
|
|
model.navigateEntry("repo")
|
|
#expect(await directoryBrowserEventually { !model.isLoading && model.path == "/workspace/repo" })
|
|
#expect(model.canGoUp)
|
|
|
|
model.setIncludeHidden(true)
|
|
#expect(await directoryBrowserEventually { !model.isLoading })
|
|
#expect(await requester.calls.last?.includeHidden == true)
|
|
|
|
model.navigateUp()
|
|
#expect(await directoryBrowserEventually { !model.isLoading && model.path == "/workspace" })
|
|
|
|
model.close()
|
|
#expect(!model.isPresented)
|
|
}
|
|
}
|