Skip to content

Commit 9935aae

Browse files
committed
Test Specialized Document Type
1 parent 5587a83 commit 9935aae

File tree

6 files changed

+125
-21
lines changed

6 files changed

+125
-21
lines changed

CodeEdit.xcodeproj/project.pbxproj

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@
375375
6C18620A298BF5A800C663EA /* RecentProjectsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C186209298BF5A800C663EA /* RecentProjectsListView.swift */; };
376376
6C1A7E942D5D557D001B951C /* CodeEditSourceEditor in Frameworks */ = {isa = PBXBuildFile; productRef = 6C5246732D1E612700F57F11 /* CodeEditSourceEditor */; };
377377
6C1A7E962D5D5762001B951C /* LanguageServerDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C1A7E952D5D5762001B951C /* LanguageServerDocument.swift */; };
378+
6C1A7E9B2D5D5E0E001B951C /* LanguageServer+DocumentObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C1A7E9A2D5D5E0E001B951C /* LanguageServer+DocumentObjects.swift */; };
378379
6C1CC9982B1E770B0002349B /* AsyncFileIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C1CC9972B1E770B0002349B /* AsyncFileIterator.swift */; };
379380
6C1CC99B2B1E7CBC0002349B /* FindNavigatorIndexBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C1CC99A2B1E7CBC0002349B /* FindNavigatorIndexBar.swift */; };
380381
6C1F3DA22C18C55800F6DEF6 /* ShellIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C1F3DA12C18C55800F6DEF6 /* ShellIntegrationTests.swift */; };
@@ -485,7 +486,7 @@
485486
6CD26C7B2C8EA8A500ADBA38 /* LSPCache+Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD26C792C8EA8A500ADBA38 /* LSPCache+Data.swift */; };
486487
6CD26C7D2C8EA8F400ADBA38 /* LanguageServer+DocumentSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD26C7C2C8EA8F400ADBA38 /* LanguageServer+DocumentSync.swift */; };
487488
6CD26C812C8F8A4400ADBA38 /* LanguageIdentifier+CodeLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD26C802C8F8A4400ADBA38 /* LanguageIdentifier+CodeLanguage.swift */; };
488-
6CD26C8A2C8F91ED00ADBA38 /* LanguageServer+DocumentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD26C892C8F91ED00ADBA38 /* LanguageServer+DocumentTests.swift */; };
489+
6CD26C8A2C8F91ED00ADBA38 /* LanguageServer+CodeFileDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD26C892C8F91ED00ADBA38 /* LanguageServer+CodeFileDocument.swift */; };
489490
6CD3CA552C8B508200D83DCD /* CodeEditSourceEditor in Frameworks */ = {isa = PBXBuildFile; productRef = 6CD3CA542C8B508200D83DCD /* CodeEditSourceEditor */; };
490491
6CDA84AD284C1BA000C1CC3A /* EditorTabBarContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CDA84AC284C1BA000C1CC3A /* EditorTabBarContextMenu.swift */; };
491492
6CDAFDDD2D35B2A0002B2D47 /* CEWorkspaceFileManager+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CDAFDDC2D35B2A0002B2D47 /* CEWorkspaceFileManager+Error.swift */; };
@@ -1084,6 +1085,7 @@
10841085
6C14CEB22877A68F001468FE /* FindNavigatorMatchListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FindNavigatorMatchListCell.swift; sourceTree = "<group>"; };
10851086
6C186209298BF5A800C663EA /* RecentProjectsListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentProjectsListView.swift; sourceTree = "<group>"; };
10861087
6C1A7E952D5D5762001B951C /* LanguageServerDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageServerDocument.swift; sourceTree = "<group>"; };
1088+
6C1A7E9A2D5D5E0E001B951C /* LanguageServer+DocumentObjects.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageServer+DocumentObjects.swift"; sourceTree = "<group>"; };
10871089
6C1CC9972B1E770B0002349B /* AsyncFileIterator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncFileIterator.swift; sourceTree = "<group>"; };
10881090
6C1CC99A2B1E7CBC0002349B /* FindNavigatorIndexBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FindNavigatorIndexBar.swift; sourceTree = "<group>"; };
10891091
6C1F3DA12C18C55800F6DEF6 /* ShellIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellIntegrationTests.swift; sourceTree = "<group>"; };
@@ -1178,7 +1180,7 @@
11781180
6CD26C792C8EA8A500ADBA38 /* LSPCache+Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LSPCache+Data.swift"; sourceTree = "<group>"; };
11791181
6CD26C7C2C8EA8F400ADBA38 /* LanguageServer+DocumentSync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LanguageServer+DocumentSync.swift"; sourceTree = "<group>"; };
11801182
6CD26C802C8F8A4400ADBA38 /* LanguageIdentifier+CodeLanguage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageIdentifier+CodeLanguage.swift"; sourceTree = "<group>"; };
1181-
6CD26C892C8F91ED00ADBA38 /* LanguageServer+DocumentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageServer+DocumentTests.swift"; sourceTree = "<group>"; };
1183+
6CD26C892C8F91ED00ADBA38 /* LanguageServer+CodeFileDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LanguageServer+CodeFileDocument.swift"; sourceTree = "<group>"; };
11821184
6CDA84AC284C1BA000C1CC3A /* EditorTabBarContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorTabBarContextMenu.swift; sourceTree = "<group>"; };
11831185
6CDAFDDC2D35B2A0002B2D47 /* CEWorkspaceFileManager+Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CEWorkspaceFileManager+Error.swift"; sourceTree = "<group>"; };
11841186
6CDAFDDE2D35DADD002B2D47 /* String+ValidFileName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+ValidFileName.swift"; sourceTree = "<group>"; };
@@ -2963,6 +2965,15 @@
29632965
path = Features;
29642966
sourceTree = "<group>";
29652967
};
2968+
6C1A7E992D5D5D9C001B951C /* SemanticTokens */ = {
2969+
isa = PBXGroup;
2970+
children = (
2971+
6C3B4CD32D0E2CB000C6759E /* SemanticTokenMapTests.swift */,
2972+
6C52466A2D1E506C00F57F11 /* SemanticTokenStorageTests.swift */,
2973+
);
2974+
path = SemanticTokens;
2975+
sourceTree = "<group>";
2976+
};
29662977
6C2384302C796EBD003FBDD4 /* ChangedFile */ = {
29672978
isa = PBXGroup;
29682979
children = (
@@ -3234,9 +3245,9 @@
32343245
isa = PBXGroup;
32353246
children = (
32363247
6C7D6D452C9092EC00B69EE0 /* BufferingServerConnection.swift */,
3237-
6CD26C892C8F91ED00ADBA38 /* LanguageServer+DocumentTests.swift */,
3238-
6C3B4CD32D0E2CB000C6759E /* SemanticTokenMapTests.swift */,
3239-
6C52466A2D1E506C00F57F11 /* SemanticTokenStorageTests.swift */,
3248+
6CD26C892C8F91ED00ADBA38 /* LanguageServer+CodeFileDocument.swift */,
3249+
6C1A7E9A2D5D5E0E001B951C /* LanguageServer+DocumentObjects.swift */,
3250+
6C1A7E992D5D5D9C001B951C /* SemanticTokens */,
32403251
);
32413252
path = LSP;
32423253
sourceTree = "<group>";
@@ -4684,14 +4695,15 @@
46844695
587B61012934170A00D5CD8F /* UnitTests_Extensions.swift in Sources */,
46854696
6C1F3DA22C18C55800F6DEF6 /* ShellIntegrationTests.swift in Sources */,
46864697
283BDCC52972F236002AFF81 /* AcknowledgementsTests.swift in Sources */,
4687-
6CD26C8A2C8F91ED00ADBA38 /* LanguageServer+DocumentTests.swift in Sources */,
4698+
6CD26C8A2C8F91ED00ADBA38 /* LanguageServer+CodeFileDocument.swift in Sources */,
46884699
4EE96ECB2960565E00FFBEA8 /* DocumentsUnitTests.swift in Sources */,
46894700
4EE96ECE296059E000FFBEA8 /* NSHapticFeedbackPerformerMock.swift in Sources */,
46904701
61FB03AE2C3C2493001B3671 /* CEActiveTaskTests.swift in Sources */,
46914702
6130535C2B23933D00D767E3 /* MemoryIndexingTests.swift in Sources */,
46924703
6195E3112B640485007261CA /* WorkspaceDocument+SearchState+IndexTests.swift in Sources */,
46934704
6130536B2B24722C00D767E3 /* AsyncIndexingTests.swift in Sources */,
46944705
613899C02B6E70FE00A5CAF6 /* FuzzySearchTests.swift in Sources */,
4706+
6C1A7E9B2D5D5E0E001B951C /* LanguageServer+DocumentObjects.swift in Sources */,
46954707
6C3B4CD42D0E2CB000C6759E /* SemanticTokenMapTests.swift in Sources */,
46964708
6195E30D2B64044F007261CA /* WorkspaceDocument+SearchState+FindTests.swift in Sources */,
46974709
6195E30F2B640474007261CA /* WorkspaceDocument+SearchState+FindAndReplaceTests.swift in Sources */,

CodeEdit/Features/LSP/LanguageServer/Capabilities/LanguageServer+DocumentSync.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@ extension LanguageServer {
4141
/// - Throws: Throws errors produced by the language server connection.
4242
func closeDocument(_ uri: String) async throws {
4343
do {
44-
guard resolveOpenCloseSupport() && openFiles.document(for: uri) != nil else { return }
44+
guard resolveOpenCloseSupport(), let document = openFiles.document(for: uri) else { return }
4545
logger.debug("Closing document \(uri, privacy: .private)")
46+
4647
openFiles.removeDocument(for: uri)
48+
await clearIsolatedDocument(document)
49+
4750
let params = DidCloseTextDocumentParams(textDocument: TextDocumentIdentifier(uri: uri))
4851
try await lspInstance.textDocumentDidClose(params)
4952
} catch {
@@ -125,8 +128,15 @@ extension LanguageServer {
125128

126129
@MainActor
127130
private func updateIsolatedDocument(_ document: DocumentType) {
128-
document.languageServerObjects.textCoordinator = openFiles.contentCoordinator(for: document)
129-
document.languageServerObjects.highlightProvider = openFiles.semanticHighlighter(for: document)
131+
document.languageServerObjects = LanguageServerDocumentObjects(
132+
textCoordinator: openFiles.contentCoordinator(for: document),
133+
highlightProvider: openFiles.semanticHighlighter(for: document)
134+
)
135+
}
136+
137+
@MainActor
138+
private func clearIsolatedDocument(_ document: DocumentType) {
139+
document.languageServerObjects = LanguageServerDocumentObjects()
130140
}
131141

132142
// swiftlint:disable line_length

CodeEditTests/Features/LSP/LanguageServer+DocumentTests.swift renamed to CodeEditTests/Features/LSP/LanguageServer+CodeFileDocument.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// LanguageServer+DocumentTests.swift
2+
// LanguageServer+CodeFileDocument.swift
33
// CodeEditTests
44
//
55
// Created by Khan Winter on 9/9/24.
@@ -13,10 +13,12 @@ import LanguageServerProtocol
1313

1414
@testable import CodeEdit
1515

16-
final class LanguageServerDocumentTests: XCTestCase {
16+
final class LanguageServerCodeFileDocumentTests: XCTestCase {
1717
// Test opening documents in CodeEdit triggers creating a language server,
1818
// further opened documents don't create new servers
1919

20+
typealias LanguageServerType = LanguageServer<CodeFileDocument>
21+
2022
var tempTestDir: URL!
2123

2224
override func setUp() {
@@ -44,7 +46,7 @@ final class LanguageServerDocumentTests: XCTestCase {
4446
}
4547
}
4648

47-
func makeTestServer() async throws -> (connection: BufferingServerConnection, server: LanguageServer) {
49+
func makeTestServer() async throws -> (connection: BufferingServerConnection, server: LanguageServerType) {
4850
let bufferingConnection = BufferingServerConnection()
4951
var capabilities = ServerCapabilities()
5052
capabilities.textDocumentSync = .optionA(
@@ -56,12 +58,12 @@ final class LanguageServerDocumentTests: XCTestCase {
5658
save: nil
5759
)
5860
)
59-
let server = LanguageServer(
61+
let server = LanguageServerType(
6062
languageId: .swift,
6163
binary: .init(execPath: "", args: [], env: nil),
6264
lspInstance: InitializingServer(
6365
server: bufferingConnection,
64-
initializeParamsProvider: LanguageServer.getInitParams(workspacePath: tempTestDir.path())
66+
initializeParamsProvider: LanguageServerType.getInitParams(workspacePath: tempTestDir.path())
6567
),
6668
serverCapabilities: capabilities,
6769
rootPath: tempTestDir
@@ -81,7 +83,7 @@ final class LanguageServerDocumentTests: XCTestCase {
8183
}
8284

8385
func openCodeFile(
84-
for server: LanguageServer,
86+
for server: LanguageServerType,
8587
connection: BufferingServerConnection,
8688
file: CEWorkspaceFile,
8789
syncOption: TwoTypeOption<TextDocumentSyncOptions, TextDocumentSyncKind>?
@@ -138,7 +140,7 @@ final class LanguageServerDocumentTests: XCTestCase {
138140
CodeEditDocumentController.shared.addDocument(workspace)
139141

140142
// Add a CEWorkspaceFile
141-
try fileManager.addFile(fileName: "example", toFile: fileManager.workspaceItem, useExtension: "swift")
143+
_ = try fileManager.addFile(fileName: "example", toFile: fileManager.workspaceItem, useExtension: "swift")
142144
guard let file = fileManager.childrenOfFile(fileManager.workspaceItem)?.first else {
143145
XCTFail("No File")
144146
return
@@ -201,7 +203,7 @@ final class LanguageServerDocumentTests: XCTestCase {
201203
let (_, fileManager) = try makeTestWorkspace()
202204

203205
// Make our example file
204-
try fileManager.addFile(fileName: "example", toFile: fileManager.workspaceItem, useExtension: "swift")
206+
_ = try fileManager.addFile(fileName: "example", toFile: fileManager.workspaceItem, useExtension: "swift")
205207
guard let file = fileManager.childrenOfFile(fileManager.workspaceItem)?.first else {
206208
XCTFail("No File")
207209
return
@@ -261,7 +263,7 @@ final class LanguageServerDocumentTests: XCTestCase {
261263
let (_, fileManager) = try makeTestWorkspace()
262264

263265
// Make our example file
264-
try fileManager.addFile(fileName: "example", toFile: fileManager.workspaceItem, useExtension: "swift")
266+
_ = try fileManager.addFile(fileName: "example", toFile: fileManager.workspaceItem, useExtension: "swift")
265267
guard let file = fileManager.childrenOfFile(fileManager.workspaceItem)?.first else {
266268
XCTFail("No File")
267269
return
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//
2+
// LanguageServer+DocumentObjects.swift
3+
// CodeEditTests
4+
//
5+
// Created by Khan Winter on 2/12/25.
6+
//
7+
8+
import XCTest
9+
import CodeEditTextView
10+
import CodeEditSourceEditor
11+
import CodeEditLanguages
12+
import LanguageClient
13+
import LanguageServerProtocol
14+
15+
@testable import CodeEdit
16+
17+
final class LanguageServerDocumentObjectsTests: XCTestCase {
18+
final class MockDocumentType: LanguageServerDocument {
19+
var content: NSTextStorage?
20+
var languageServerURI: String?
21+
var languageServerObjects: LanguageServerDocumentObjects<MockDocumentType>
22+
23+
init() {
24+
self.content = NSTextStorage(string: "hello world")
25+
self.languageServerURI = "/test/file/path"
26+
self.languageServerObjects = .init()
27+
}
28+
29+
func getLanguage() -> CodeLanguage {
30+
.swift
31+
}
32+
}
33+
34+
typealias LanguageServerType = LanguageServer<MockDocumentType>
35+
36+
var document: MockDocumentType!
37+
var server: LanguageServerType!
38+
39+
// MARK: - Set Up
40+
41+
override func setUp() async throws {
42+
var capabilities = ServerCapabilities()
43+
capabilities.textDocumentSync = .optionA(.init(openClose: true, change: .full))
44+
capabilities.semanticTokensProvider = .optionA(.init(legend: .init(tokenTypes: [], tokenModifiers: [])))
45+
server = LanguageServerType(
46+
languageId: .swift,
47+
binary: .init(execPath: "", args: [], env: nil),
48+
lspInstance: InitializingServer(
49+
server: BufferingServerConnection(),
50+
initializeParamsProvider: LanguageServerType.getInitParams(workspacePath: "/")
51+
),
52+
serverCapabilities: capabilities,
53+
rootPath: URL(fileURLWithPath: "")
54+
)
55+
_ = try await server.lspInstance.initializeIfNeeded()
56+
document = MockDocumentType()
57+
}
58+
59+
// MARK: - Tests
60+
61+
func testOpenDocumentRegistersObjects() async throws {
62+
try await server.openDocument(document)
63+
XCTAssertNotNil(document.languageServerObjects.highlightProvider)
64+
XCTAssertNotNil(document.languageServerObjects.textCoordinator)
65+
XCTAssertNotNil(server.openFiles.document(for: document.languageServerURI ?? ""))
66+
}
67+
68+
func testCloseDocumentClearsObjects() async throws {
69+
guard let languageServerURI = document.languageServerURI else {
70+
XCTFail("Language server URI missing on a mock object")
71+
return
72+
}
73+
try await server.openDocument(document)
74+
XCTAssertNotNil(server.openFiles.document(for: languageServerURI))
75+
76+
try await server.closeDocument(languageServerURI)
77+
XCTAssertNil(document.languageServerObjects.highlightProvider)
78+
XCTAssertNil(document.languageServerObjects.textCoordinator)
79+
}
80+
}

CodeEditTests/Features/LSP/SemanticTokenStorageTests.swift renamed to CodeEditTests/Features/LSP/SemanticTokens/SemanticTokenStorageTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import LanguageServerProtocol
1212

1313
final class SemanticTokenStorageTests: XCTestCase {
1414
func testInvalidation() {
15-
let storage = LSPSemanticTokenStorage()
16-
storage.state = LSPSemanticTokenStorage.CurrentState(
17-
requestId: nil,
15+
let storage = SemanticTokenStorage()
16+
storage.state = SemanticTokenStorage.CurrentState(
17+
resultId: nil,
1818
tokenData: [0, 0, 2, 0, 0],
1919
tokens: [SemanticToken(line: 0, char: 0, length: 2, type: 0, modifiers: 0)]
2020
)

0 commit comments

Comments
 (0)