Skip to content

Commit db44320

Browse files
committed
Assert appropriate completion doc based on full doc support in sourcekitd
1 parent 2b40e78 commit db44320

File tree

2 files changed

+99
-32
lines changed

2 files changed

+99
-32
lines changed

Tests/SourceKitLSPTests/SwiftCompletionTests.swift

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import Csourcekitd
1314
import LanguageServerProtocol
1415
import SKTestSupport
16+
import SourceKitD
1517
import SourceKitLSP
1618
import SwiftExtensions
19+
import ToolchainRegistry
1720
import XCTest
1821

1922
final class SwiftCompletionTests: XCTestCase {
@@ -67,9 +70,10 @@ final class SwiftCompletionTests: XCTestCase {
6770
if let abc = abc {
6871
XCTAssertEqual(abc.kind, .property)
6972
XCTAssertEqual(abc.detail, "Int")
70-
assertMarkdown(
73+
try await assertDocumentation(
7174
documentation: abc.documentation,
72-
expected: """
75+
expectedBrief: "Documentation for abc.",
76+
expectedFull: """
7377
```swift
7478
var abc: Int
7579
```
@@ -95,9 +99,10 @@ final class SwiftCompletionTests: XCTestCase {
9599
// If we switch to server-side filtering this will change.
96100
XCTAssertEqual(abc.kind, .property)
97101
XCTAssertEqual(abc.detail, "Int")
98-
assertMarkdown(
102+
try await assertDocumentation(
99103
documentation: abc.documentation,
100-
expected: """
104+
expectedBrief: "Documentation for abc.",
105+
expectedFull: """
101106
```swift
102107
var abc: Int
103108
```
@@ -1203,9 +1208,10 @@ final class SwiftCompletionTests: XCTestCase {
12031208
let item = try XCTUnwrap(completions.items.only)
12041209
XCTAssertNil(item.documentation)
12051210
let resolvedItem = try await testClient.send(CompletionItemResolveRequest(item: item))
1206-
assertMarkdown(
1211+
try await assertDocumentation(
12071212
documentation: resolvedItem.documentation,
1208-
expected: """
1213+
expectedBrief: "Creates a true value",
1214+
expectedFull: """
12091215
```swift
12101216
func makeBool() -> Bool
12111217
```
@@ -1217,6 +1223,9 @@ final class SwiftCompletionTests: XCTestCase {
12171223
func testCompletionBriefDocumentationFallback() async throws {
12181224
try await SkipUnless.sourcekitdSupportsPlugin()
12191225

1226+
let fullDocumentationSupported = try await sourcekitdSupportsFullDocumentation()
1227+
try XCTSkipUnless(fullDocumentationSupported)
1228+
12201229
let testClient = try await TestSourceKitLSPClient()
12211230
let uri = DocumentURI(for: .swift)
12221231

@@ -1310,6 +1319,30 @@ private func assertMarkdown(
13101319
XCTAssertEqual(documentation, .markupContent(MarkupContent(kind: .markdown, value: expected)))
13111320
}
13121321

1322+
/// Asserts that documentation matches the expected values based on whether full documentation is supported in sourcekitd or not.
1323+
private func assertDocumentation(
1324+
documentation: StringOrMarkupContent?,
1325+
expectedBrief: String,
1326+
expectedFull: String,
1327+
file: StaticString = #filePath,
1328+
line: UInt = #line
1329+
) async throws {
1330+
let supportsFullDocumentation = try await sourcekitdSupportsFullDocumentation()
1331+
let expected = supportsFullDocumentation ? expectedFull : expectedBrief
1332+
1333+
assertMarkdown(documentation: documentation, expected: expected, file: file, line: line)
1334+
}
1335+
1336+
private func sourcekitdSupportsFullDocumentation() async throws -> Bool {
1337+
let sourcekitdPath = await ToolchainRegistry.forTesting.default!.sourcekitd!
1338+
let sourcekitd = try await SourceKitD.getOrCreate(
1339+
dylibPath: sourcekitdPath,
1340+
pluginPaths: sourceKitPluginPaths
1341+
)
1342+
1343+
return sourcekitd.ideApi.completion_item_get_doc_full_copy != nil
1344+
}
1345+
13131346
fileprivate extension Position {
13141347
func adding(columns: Int) -> Position {
13151348
return Position(line: line, utf16index: utf16index + columns)

Tests/SwiftSourceKitPluginTests/SwiftSourceKitPluginTests.swift

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ final class SwiftSourceKitPluginTests: XCTestCase {
203203
XCTAssertEqual(result2.items.count, 1)
204204
XCTAssertEqual(result2.items[0].name, "")
205205
let doc = try await sourcekitd.completeDocumentation(id: result2.items[0].id)
206-
XCTAssertEqual(doc.docFullAsXML, nil)
206+
XCTAssertNil(doc.docFullAsXML)
207+
XCTAssertNil(doc.docBrief)
207208
}
208209

209210
func testMultipleFiles() async throws {
@@ -436,38 +437,47 @@ final class SwiftSourceKitPluginTests: XCTestCase {
436437
let sym3 = try unwrap(result.items.first(where: { $0.name == "foo3()" }), "did not find foo3; got \(result.items)")
437438

438439
let sym1Doc = try await sourcekitd.completeDocumentation(id: sym1.id)
439-
XCTAssertEqual(sym1Doc.docFullAsXML,
440-
"""
441-
<Function file="\(path)" line="3" column="8">\
442-
<Name>foo1()</Name>\
443-
<USR>s:1a1PP4foo1yyF</USR>\
444-
<Declaration>func foo1()</Declaration>\
445-
<CommentParts>\
446-
<Abstract><Para>Protocol P foo1</Para></Abstract>\
447-
<Discussion><Note>\
448-
<Para>This documentation comment was inherited from <codeVoice>P</codeVoice>.</Para>\
449-
</Note></Discussion>\
450-
</CommentParts>\
451-
</Function>
452-
""")
440+
assertDocumentation(
441+
full: sourcekitd.supportsFullDocumentationInCompletion,
442+
documentation: sym1Doc,
443+
expectedBrief: "Protocol P foo1",
444+
expectedFull: """
445+
<Function file="\(path)" line="3" column="8">\
446+
<Name>foo1()</Name>\
447+
<USR>s:1a1PP4foo1yyF</USR>\
448+
<Declaration>func foo1()</Declaration>\
449+
<CommentParts>\
450+
<Abstract><Para>Protocol P foo1</Para></Abstract>\
451+
<Discussion><Note>\
452+
<Para>This documentation comment was inherited from <codeVoice>P</codeVoice>.</Para>\
453+
</Note></Discussion>\
454+
</CommentParts>\
455+
</Function>
456+
"""
457+
)
453458
XCTAssertEqual(sym1Doc.associatedUSRs, ["s:1a1SV4foo1yyF", "s:1a1PP4foo1yyF"])
454459

455460
let sym2Doc = try await sourcekitd.completeDocumentation(id: sym2.id)
456-
XCTAssertEqual(sym2Doc.docFullAsXML,
457-
"""
458-
<Function file="\(path)" line="8" column="8">\
459-
<Name>foo2()</Name>\
460-
<USR>s:1a1SV4foo2yyF</USR>\
461-
<Declaration>func foo2()</Declaration>\
462-
<CommentParts>\
463-
<Abstract><Para>Struct S foo2</Para></Abstract>\
464-
</CommentParts>\
465-
</Function>
466-
""")
461+
assertDocumentation(
462+
full: sourcekitd.supportsFullDocumentationInCompletion,
463+
documentation: sym2Doc,
464+
expectedBrief: "Struct S foo2",
465+
expectedFull: """
466+
<Function file="\(path)" line="8" column="8">\
467+
<Name>foo2()</Name>\
468+
<USR>s:1a1SV4foo2yyF</USR>\
469+
<Declaration>func foo2()</Declaration>\
470+
<CommentParts>\
471+
<Abstract><Para>Struct S foo2</Para></Abstract>\
472+
</CommentParts>\
473+
</Function>
474+
"""
475+
)
467476
XCTAssertEqual(sym2Doc.associatedUSRs, ["s:1a1SV4foo2yyF"])
468477

469478
let sym3Doc = try await sourcekitd.completeDocumentation(id: sym3.id)
470479
XCTAssertNil(sym3Doc.docFullAsXML)
480+
XCTAssertNil(sym3Doc.docBrief)
471481
XCTAssertEqual(sym3Doc.associatedUSRs, ["s:1a1SV4foo3yyF"])
472482
}
473483

@@ -1789,11 +1799,13 @@ fileprivate struct CompletionResult: Equatable, Sendable {
17891799
}
17901800

17911801
fileprivate struct CompletionDocumentation {
1802+
var docBrief: String? = nil
17921803
var docFullAsXML: String? = nil
17931804
var associatedUSRs: [String] = []
17941805

17951806
init(_ dict: SKDResponseDictionary) {
17961807
let keys = dict.sourcekitd.keys
1808+
self.docBrief = dict[keys.docBrief]
17971809
self.docFullAsXML = dict[keys.docFullAsXML]
17981810
self.associatedUSRs = dict[keys.associatedUSRs]?.asStringArray ?? []
17991811
}
@@ -2072,6 +2084,10 @@ fileprivate extension SourceKitD {
20722084
try await openDocument(path, contents: textWithoutMarker, compilerArguments: [path])
20732085
return (positions["1️⃣"], recent)
20742086
}
2087+
2088+
nonisolated var supportsFullDocumentationInCompletion: Bool {
2089+
return ideApi.completion_item_get_doc_full_copy != nil
2090+
}
20752091
}
20762092

20772093
private struct ExpectationNotFulfilledError: Error {}
@@ -2094,3 +2110,21 @@ private func runAsync<T: Sendable>(_ body: @escaping @Sendable () async throws -
20942110
}
20952111
return try result.get()
20962112
}
2113+
2114+
/// Asserts that documentation matches the expected values based on whether full documentation is supported in sourcekitd or not.
2115+
private func assertDocumentation(
2116+
full: Bool,
2117+
documentation: CompletionDocumentation,
2118+
expectedBrief: String,
2119+
expectedFull: String,
2120+
file: StaticString = #filePath,
2121+
line: UInt = #line
2122+
) {
2123+
if full {
2124+
XCTAssertEqual(documentation.docFullAsXML, expectedFull, file: file, line: line)
2125+
XCTAssertNil(documentation.docBrief, "Expected brief documentation to not be available", file: file, line: line)
2126+
} else {
2127+
XCTAssertEqual(documentation.docBrief, expectedBrief, file: file, line: line)
2128+
XCTAssertNil(documentation.docFullAsXML, "Expected full documentation to not be available", file: file, line: line)
2129+
}
2130+
}

0 commit comments

Comments
 (0)