mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
The implementation of which file’s dependencies have been updated is common across all build systems and thus build systems shouldn’t need to implement this logic. This also allows us to remove `BuildSystemDelegate`.
156 lines
5.4 KiB
Swift
156 lines
5.4 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import BuildServerProtocol
|
|
import BuildSystemIntegration
|
|
import Foundation
|
|
import ISDBTestSupport
|
|
import LanguageServerProtocol
|
|
import SKTestSupport
|
|
import TSCBasic
|
|
import XCTest
|
|
|
|
/// The path to the INPUTS directory of shared test projects.
|
|
private let skTestSupportInputsDirectory: URL = {
|
|
#if os(macOS)
|
|
var resources =
|
|
productsDirectory
|
|
.appendingPathComponent("SourceKitLSP_SKTestSupport.bundle")
|
|
.appendingPathComponent("Contents")
|
|
.appendingPathComponent("Resources")
|
|
if !FileManager.default.fileExists(atPath: resources.path) {
|
|
// Xcode and command-line swiftpm differ about the path.
|
|
resources.deleteLastPathComponent()
|
|
resources.deleteLastPathComponent()
|
|
}
|
|
#else
|
|
let resources = XCTestCase.productsDirectory
|
|
.appendingPathComponent("SourceKitLSP_SKTestSupport.resources")
|
|
#endif
|
|
guard FileManager.default.fileExists(atPath: resources.path) else {
|
|
fatalError("missing resources \(resources.path)")
|
|
}
|
|
return resources.appendingPathComponent("INPUTS", isDirectory: true).standardizedFileURL
|
|
}()
|
|
|
|
final class BuildServerBuildSystemTests: XCTestCase {
|
|
private var root: AbsolutePath {
|
|
try! AbsolutePath(
|
|
validating:
|
|
skTestSupportInputsDirectory
|
|
.appendingPathComponent(testDirectoryName, isDirectory: true).path
|
|
)
|
|
}
|
|
let buildFolder = try! AbsolutePath(validating: NSTemporaryDirectory())
|
|
|
|
func testServerInitialize() async throws {
|
|
let buildSystem = try await BuildServerBuildSystem(projectRoot: root, messageHandler: nil)
|
|
|
|
assertEqual(
|
|
await buildSystem.indexDatabasePath,
|
|
try AbsolutePath(validating: "some/index/db/path", relativeTo: root)
|
|
)
|
|
assertEqual(
|
|
await buildSystem.indexStorePath,
|
|
try AbsolutePath(validating: "some/index/store/path", relativeTo: root)
|
|
)
|
|
}
|
|
|
|
func testFileRegistration() async throws {
|
|
let uri = DocumentURI(filePath: "/some/file/path", isDirectory: false)
|
|
let expectation = self.expectation(description: "\(uri) settings updated")
|
|
let buildSystemDelegate = TestDelegate(targetExpectations: [
|
|
(DidChangeBuildTargetNotification(changes: nil), expectation)
|
|
])
|
|
defer {
|
|
// BuildSystemManager has a weak reference to delegate. Keep it alive.
|
|
_fixLifetime(buildSystemDelegate)
|
|
}
|
|
let buildSystem = try await BuildServerBuildSystem(projectRoot: root, messageHandler: buildSystemDelegate)
|
|
_ = try await buildSystem.sourceKitOptions(
|
|
request: SourceKitOptionsRequest(
|
|
textDocument: TextDocumentIdentifier(uri: uri),
|
|
target: try unwrap(
|
|
await buildSystem.inverseSources(
|
|
request: InverseSourcesRequest(textDocument: TextDocumentIdentifier(uri: uri))
|
|
).targets.only
|
|
)
|
|
)
|
|
)
|
|
|
|
XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: defaultTimeout), .completed)
|
|
}
|
|
|
|
func testBuildTargetsChanged() async throws {
|
|
let uri = DocumentURI(filePath: "/some/file/path", isDirectory: false)
|
|
let expectation = XCTestExpectation(description: "target changed")
|
|
let buildSystemDelegate = TestDelegate(targetExpectations: [
|
|
(
|
|
DidChangeBuildTargetNotification(changes: [
|
|
BuildTargetEvent(
|
|
target: BuildTargetIdentifier(uri: try! URI(string: "build://target/a")),
|
|
kind: .created,
|
|
dataKind: nil,
|
|
data: LSPAny.dictionary(["key": "value"])
|
|
)
|
|
]), expectation
|
|
)
|
|
])
|
|
defer {
|
|
// BuildSystemManager has a weak reference to delegate. Keep it alive.
|
|
_fixLifetime(buildSystemDelegate)
|
|
}
|
|
let buildSystem = try await BuildServerBuildSystem(projectRoot: root, messageHandler: buildSystemDelegate)
|
|
_ = try await buildSystem.sourceKitOptions(
|
|
request: SourceKitOptionsRequest(
|
|
textDocument: TextDocumentIdentifier(uri: uri),
|
|
target: try unwrap(
|
|
await buildSystem.inverseSources(
|
|
request: InverseSourcesRequest(textDocument: TextDocumentIdentifier(uri: uri))
|
|
).targets.only
|
|
)
|
|
)
|
|
)
|
|
|
|
try await fulfillmentOfOrThrow([expectation])
|
|
}
|
|
}
|
|
|
|
final class TestDelegate: BuiltInBuildSystemMessageHandler {
|
|
let targetExpectations: [(DidChangeBuildTargetNotification, XCTestExpectation)]
|
|
|
|
package init(targetExpectations: [(DidChangeBuildTargetNotification, XCTestExpectation)] = []) {
|
|
self.targetExpectations = targetExpectations
|
|
}
|
|
|
|
func didChangeBuildTarget(notification: DidChangeBuildTargetNotification) {
|
|
for (expectedNotification, expectation) in targetExpectations {
|
|
if expectedNotification == notification {
|
|
expectation.fulfill()
|
|
}
|
|
}
|
|
}
|
|
|
|
func sendRequestToSourceKitLSP<R: RequestType>(_ request: R) async throws -> R.Response {
|
|
throw ResponseError.methodNotFound(R.method)
|
|
}
|
|
|
|
func sendNotificationToSourceKitLSP(_ notification: some NotificationType) async {
|
|
switch notification {
|
|
case let notification as DidChangeBuildTargetNotification:
|
|
didChangeBuildTarget(notification: notification)
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
}
|