gitbayTests/SymbolTests.swift

v1.12.0
gitbay-ios/gitbayTests/SymbolTests.swift history · blame · raw

73 lines · 3071 bytes

 1import Foundation
 2import Testing
 3@testable import gitbay
 4
 5private func makeClient() throws -> (GitbayClient, StubProtocol.Box) {
 6    let box = StubProtocol.box()
 7    let client = GitbayClient(
 8        instance: try GitbayInstance(url: "https://gitbay.org"),
 9        token: "test-token",
10        session: box.session()
11    )
12    return (client, box)
13}
14
15private func argv(_ url: URL) -> [String] {
16    URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.compactMap(\.value) ?? []
17}
18
19@MainActor
20struct SymbolSearchTests {
21
22    @Test func aQueryReadsTheSymbolIndex() async throws {
23        let (client, stub) = try makeClient()
24        stub.enqueue(.init(status: 200, json: """
25            {"protocol_version":1,"data":[\
26            {"name":"Dispatch","kind":"function","path":"internal/control/control.go","line":120},\
27            {"name":"DispatchIn","kind":"function","path":"internal/control/test.go","line":9}]}
28            """))
29        let model = SymbolSearchViewModel(client: client, repoPath: "krz/gitbay")
30
31        await model.search("  Dispatch ")
32
33        #expect(argv(try #require(stub.seen.first).url) == ["repo", "symbols", "krz/gitbay", "Dispatch"])
34        #expect(model.state?.value?.map(\.id) == ["internal/control/control.go:120:function:Dispatch", "internal/control/test.go:9:function:DispatchIn"])
35    }
36
37    @Test func aKindNarrowsTheSearch() async throws {
38        let (client, stub) = try makeClient()
39        stub.enqueue(.init(status: 200, json: #"{"protocol_version":1}"#))
40        let model = SymbolSearchViewModel(client: client, repoPath: "krz/gitbay")
41        model.kind = "method"
42
43        await model.search("Ctx.")
44
45        #expect(argv(try #require(stub.seen.first).url) == ["repo", "symbols", "krz/gitbay", "--kind", "method", "Ctx."])
46        guard case .empty(let message) = model.state else { Issue.record("not empty: \(String(describing: model.state))"); return }
47        #expect(message == "No definitions matching \"Ctx.\".")
48    }
49
50    /// The index is built on push; a repository not pushed to since gitbay
51    /// v1.39.0 has none, and the server's not-found says so.
52    @Test func aRepositoryWithNoIndexShowsWhy() async throws {
53        let (client, stub) = try makeClient()
54        let why = "krz/old has no symbol index yet; one is built after a push to main"
55        stub.enqueue(.init(status: 404, json: #"{"protocol_version":1,"error":"\#(why)","exit_code":3}"#))
56        let model = SymbolSearchViewModel(client: client, repoPath: "krz/old")
57
58        await model.search("x")
59
60        guard case .empty(let message) = model.state else { Issue.record("not empty"); return }
61        #expect(message == why)
62    }
63}
64
65struct FileLineTests {
66
67    @Test func aFileRouteCarriesTheLineToOpenAt() {
68        let route = RepoRoute.file(repo: "krz/gitbay", path: "a.go", ref: nil, line: 12)
69        guard case .file(_, _, _, let line) = route else { Issue.record("not a file route"); return }
70        #expect(line == 12)
71        #expect(RepoRoute.file(repo: "krz/gitbay", path: "a.go", ref: nil) != route)
72    }
73}