Skip to content

Commit f84dd52

Browse files
committed
Add a request to get all tests within a file
1 parent e1e2d9c commit f84dd52

File tree

4 files changed

+104
-5
lines changed

4 files changed

+104
-5
lines changed

Sources/LanguageServerProtocol/Messages.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public let builtinRequests: [_RequestType.Type] = [
4545
DocumentSemanticTokensRangeRequest.self,
4646
DocumentSemanticTokensRequest.self,
4747
DocumentSymbolRequest.self,
48+
DocumentTestsRequest.self,
4849
ExecuteCommandRequest.self,
4950
FoldingRangeRequest.self,
5051
HoverRequest.self,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
/// A request that returns symbols for all the test classes and test methods within a file.
14+
///
15+
/// **(LSP Extension)**
16+
public struct DocumentTestsRequest: TextDocumentRequest, Hashable {
17+
public static let method: String = "workspace/tests"
18+
public typealias Response = [WorkspaceSymbolItem]?
19+
20+
public var textDocument: TextDocumentIdentifier
21+
22+
public init(textDocument: TextDocumentIdentifier) {
23+
self.textDocument = textDocument
24+
}
25+
}

Sources/SourceKitLSP/SourceKitServer.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,8 @@ extension SourceKitServer: MessageHandler {
840840
await request.reply { try await workspaceSymbols(request.params) }
841841
case let request as RequestAndReply<WorkspaceTestsRequest>:
842842
await request.reply { try await workspaceTests(request.params) }
843+
case let request as RequestAndReply<DocumentTestsRequest>:
844+
await self.handleRequest(for: request, requestHandler: self.documentTests)
843845
case let request as RequestAndReply<PollIndexRequest>:
844846
await request.reply { try await pollIndex(request.params) }
845847
case let request as RequestAndReply<BarrierRequest>:
@@ -1500,14 +1502,20 @@ extension SourceKitServer {
15001502

15011503
func workspaceTests(_ req: WorkspaceTestsRequest) async throws -> [WorkspaceSymbolItem]? {
15021504
let testSymbols = workspaces.flatMap { (workspace) -> [SymbolOccurrence] in
1503-
guard let index = workspace.index else {
1504-
return []
1505-
}
1506-
return index.unitTests()
1505+
return workspace.index?.unitTests() ?? []
15071506
}
15081507
return testSymbols.map(WorkspaceSymbolItem.init)
15091508
}
15101509

1510+
func documentTests(
1511+
_ req: DocumentTestsRequest,
1512+
workspace: Workspace,
1513+
languageService: ToolchainLanguageServer
1514+
) async throws -> [WorkspaceSymbolItem]? {
1515+
let testSymbols = workspace.index?.unitTests(referencedByMainFiles: [req.textDocument.uri.pseudoPath]) ?? []
1516+
return testSymbols.map(WorkspaceSymbolItem.init)
1517+
}
1518+
15111519
/// Forwards a SymbolInfoRequest to the appropriate toolchain service for this document.
15121520
func symbolInfo(
15131521
_ req: SymbolInfoRequest,

Tests/SourceKitLSPTests/WorkspaceTestsTests.swift renamed to Tests/SourceKitLSPTests/TestDiscoveryTests.swift

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import LanguageServerProtocol
1414
import SKTestSupport
1515
import XCTest
1616

17-
final class WorkspaceTestsTests: XCTestCase {
17+
final class TestDiscoveryTests: XCTestCase {
1818
func testWorkspaceTests() async throws {
1919
try XCTSkipIf(longTestsDisabled)
2020

@@ -71,4 +71,69 @@ final class WorkspaceTestsTests: XCTestCase {
7171
]
7272
)
7373
}
74+
75+
func testDocumentTests() async throws {
76+
try XCTSkipIf(longTestsDisabled)
77+
78+
let ws = try await SwiftPMTestWorkspace(
79+
files: [
80+
"Tests/MyLibraryTests/MyTests.swift": """
81+
import XCTest
82+
83+
class 1️⃣MyTests: XCTestCase {
84+
func 2️⃣testMyLibrary() {}
85+
func unrelatedFunc() {}
86+
var testVariable: Int = 0
87+
}
88+
""",
89+
"Tests/MyLibraryTests/MoreTests.swift": """
90+
import XCTest
91+
92+
class MoreTests: XCTestCase {
93+
func testSomeMore() {}
94+
}
95+
"""
96+
],
97+
manifest: """
98+
// swift-tools-version: 5.7
99+
100+
import PackageDescription
101+
102+
let package = Package(
103+
name: "MyLibrary",
104+
targets: [.testTarget(name: "MyLibraryTests")]
105+
)
106+
""",
107+
build: true
108+
)
109+
110+
let (uri, positions) = try ws.openDocument("MyTests.swift")
111+
let tests = try await ws.testClient.send(DocumentTestsRequest(textDocument: TextDocumentIdentifier(uri)))
112+
XCTAssertEqual(
113+
tests,
114+
[
115+
WorkspaceSymbolItem.symbolInformation(
116+
SymbolInformation(
117+
name: "MyTests",
118+
kind: .class,
119+
location: Location(
120+
uri: uri,
121+
range: Range(positions["1️⃣"])
122+
)
123+
)
124+
),
125+
WorkspaceSymbolItem.symbolInformation(
126+
SymbolInformation(
127+
name: "testMyLibrary()",
128+
kind: .method,
129+
location: Location(
130+
uri: try ws.uri(for: "MyTests.swift"),
131+
range: Range(positions["2️⃣"])
132+
),
133+
containerName: "MyTests"
134+
)
135+
),
136+
]
137+
)
138+
}
74139
}

0 commit comments

Comments
 (0)