import Foundation import Testing @testable import gitbay private func makeClient() throws -> (GitbayClient, StubProtocol.Box) { let box = StubProtocol.box() let client = GitbayClient( instance: try GitbayInstance(url: "https://gitbay.org"), token: "test-token", session: box.session() ) return (client, box) } private func argv(_ url: URL) -> [String] { URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.compactMap(\.value) ?? [] } @MainActor struct SymbolSearchTests { @Test func aQueryReadsTheSymbolIndex() async throws { let (client, stub) = try makeClient() stub.enqueue(.init(status: 200, json: """ {"protocol_version":1,"data":[\ {"name":"Dispatch","kind":"function","path":"internal/control/control.go","line":120},\ {"name":"DispatchIn","kind":"function","path":"internal/control/test.go","line":9}]} """)) let model = SymbolSearchViewModel(client: client, repoPath: "krz/gitbay") await model.search(" Dispatch ") #expect(argv(try #require(stub.seen.first).url) == ["repo", "symbols", "krz/gitbay", "Dispatch"]) #expect(model.state?.value?.map(\.id) == ["internal/control/control.go:120:function:Dispatch", "internal/control/test.go:9:function:DispatchIn"]) } @Test func aKindNarrowsTheSearch() async throws { let (client, stub) = try makeClient() stub.enqueue(.init(status: 200, json: #"{"protocol_version":1}"#)) let model = SymbolSearchViewModel(client: client, repoPath: "krz/gitbay") model.kind = "method" await model.search("Ctx.") #expect(argv(try #require(stub.seen.first).url) == ["repo", "symbols", "krz/gitbay", "--kind", "method", "Ctx."]) guard case .empty(let message) = model.state else { Issue.record("not empty: \(String(describing: model.state))"); return } #expect(message == "No definitions matching \"Ctx.\".") } /// The index is built on push; a repository not pushed to since gitbay /// v1.39.0 has none, and the server's not-found says so. @Test func aRepositoryWithNoIndexShowsWhy() async throws { let (client, stub) = try makeClient() let why = "krz/old has no symbol index yet; one is built after a push to main" stub.enqueue(.init(status: 404, json: #"{"protocol_version":1,"error":"\#(why)","exit_code":3}"#)) let model = SymbolSearchViewModel(client: client, repoPath: "krz/old") await model.search("x") guard case .empty(let message) = model.state else { Issue.record("not empty"); return } #expect(message == why) } } struct FileLineTests { @Test func aFileRouteCarriesTheLineToOpenAt() { let route = RepoRoute.file(repo: "krz/gitbay", path: "a.go", ref: nil, line: 12) guard case .file(_, _, _, let line) = route else { Issue.record("not a file route"); return } #expect(line == 12) #expect(RepoRoute.file(repo: "krz/gitbay", path: "a.go", ref: nil) != route) } }