mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
* Support for clangd's go-to-definition for header files - By forwarding the request to clangd when it fails to give symbol information, we are able to use its built in go-to-definition support for headers (jump to header file) * Add static tibs test for clangd go-to-#include * Move #include test to SourceKitTests and regenerate linux main * Fix improper escaping of %40 in file URLs * Add URL escaping test * Another attempt to fix broken BuildServerBuildSystemTests test on Linux - URL's `standardizedFileURL` removes trailing slashes from file URLs, but only on Linux
218 lines
9.8 KiB
Swift
218 lines
9.8 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 Foundation
|
|
import LanguageServerProtocol
|
|
import SKCore
|
|
import SKTestSupport
|
|
import TSCBasic
|
|
import XCTest
|
|
|
|
final class BuildServerBuildSystemTests: XCTestCase {
|
|
|
|
func testServerInitialize() throws {
|
|
let root = AbsolutePath(
|
|
inputsDirectory().appendingPathComponent(testDirectoryName, isDirectory: true).path)
|
|
let buildFolder = AbsolutePath(NSTemporaryDirectory())
|
|
|
|
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
|
|
|
|
XCTAssertEqual(buildSystem.indexDatabasePath, AbsolutePath("some/index/db/path", relativeTo: root))
|
|
XCTAssertEqual(buildSystem.indexStorePath, AbsolutePath("some/index/store/path", relativeTo: root))
|
|
}
|
|
|
|
func testSettings() throws {
|
|
let root = AbsolutePath(
|
|
inputsDirectory().appendingPathComponent(testDirectoryName, isDirectory: true).path)
|
|
let buildFolder = AbsolutePath(NSTemporaryDirectory())
|
|
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
|
|
|
|
// test settings with a response
|
|
let fileURL = URL(fileURLWithPath: "/path/to/some/file.swift")
|
|
let settings = buildSystem.settings(for: DocumentURI(fileURL), Language.swift)
|
|
XCTAssertNotNil(settings)
|
|
XCTAssertEqual(settings?.compilerArguments, ["-a", "-b"])
|
|
XCTAssertEqual(settings?.workingDirectory, fileURL.deletingLastPathComponent().path)
|
|
|
|
// test error
|
|
let missingFileURL = URL(fileURLWithPath: "/path/to/some/missingfile.missing")
|
|
XCTAssertNil(buildSystem.settings(for: DocumentURI(missingFileURL), Language.swift))
|
|
}
|
|
|
|
func testFileRegistration() throws {
|
|
let root = AbsolutePath(
|
|
inputsDirectory().appendingPathComponent(testDirectoryName, isDirectory: true).path)
|
|
let buildFolder = AbsolutePath(NSTemporaryDirectory())
|
|
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
|
|
|
|
let fileUrl = URL(fileURLWithPath: "/some/file/path")
|
|
let expectation = XCTestExpectation(description: "\(fileUrl) settings updated")
|
|
let buildSystemDelegate = TestDelegate(settingsExpectations: [DocumentURI(fileUrl): expectation])
|
|
buildSystem.delegate = buildSystemDelegate
|
|
buildSystem.registerForChangeNotifications(for: DocumentURI(fileUrl), language: .swift)
|
|
|
|
XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: 15), .completed)
|
|
}
|
|
|
|
func testBuildTargets() throws {
|
|
let root = AbsolutePath(
|
|
inputsDirectory().appendingPathComponent(testDirectoryName, isDirectory: true).path)
|
|
let buildFolder = AbsolutePath(NSTemporaryDirectory())
|
|
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
|
|
|
|
let expectation = XCTestExpectation(description: "build target expectation")
|
|
|
|
buildSystem.buildTargets(reply: { response in
|
|
switch(response) {
|
|
case .success(let targets):
|
|
XCTAssertEqual(targets, [
|
|
BuildTarget(id: BuildTargetIdentifier(uri: DocumentURI(string: "target:first_target")),
|
|
displayName: "First Target",
|
|
baseDirectory: DocumentURI(URL(fileURLWithPath: "/some/dir")),
|
|
tags: [BuildTargetTag.library, BuildTargetTag.test],
|
|
capabilities: BuildTargetCapabilities(canCompile: true, canTest: true, canRun: false),
|
|
languageIds: [Language.objective_c, Language.swift],
|
|
dependencies: []),
|
|
BuildTarget(id: BuildTargetIdentifier(uri: DocumentURI(string: "target:second_target")),
|
|
displayName: "Second Target",
|
|
baseDirectory: DocumentURI(URL(fileURLWithPath: "/some/dir")),
|
|
tags: [BuildTargetTag.library, BuildTargetTag.test],
|
|
capabilities: BuildTargetCapabilities(canCompile: true, canTest: false, canRun: false),
|
|
languageIds: [Language.objective_c, Language.swift],
|
|
dependencies: [BuildTargetIdentifier(uri: DocumentURI(string: "target:first_target"))]),
|
|
])
|
|
expectation.fulfill()
|
|
case .failure(let error):
|
|
XCTFail(error.message)
|
|
}
|
|
})
|
|
XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: 15), .completed)
|
|
}
|
|
|
|
func testBuildTargetSources() throws {
|
|
let root = AbsolutePath(
|
|
inputsDirectory().appendingPathComponent(testDirectoryName, isDirectory: true).path)
|
|
let buildFolder = AbsolutePath(NSTemporaryDirectory())
|
|
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
|
|
|
|
let expectation = XCTestExpectation(description: "build target sources expectation")
|
|
let targets = [
|
|
BuildTargetIdentifier(uri: DocumentURI(string: "build://target/a")),
|
|
BuildTargetIdentifier(uri: DocumentURI(string: "build://target/b")),
|
|
]
|
|
buildSystem.buildTargetSources(targets: targets, reply: { response in
|
|
switch(response) {
|
|
case .success(let items):
|
|
XCTAssertNotNil(items)
|
|
XCTAssertEqual(items[0].target.uri, targets[0].uri)
|
|
XCTAssertEqual(items[1].target.uri, targets[1].uri)
|
|
XCTAssertEqual(items[0].sources[0].uri, DocumentURI(URL(fileURLWithPath: "/path/to/a/file")))
|
|
XCTAssertEqual(items[0].sources[0].kind, SourceItemKind.file)
|
|
XCTAssertEqual(items[0].sources[1].uri, DocumentURI(URL(fileURLWithPath: "/path/to/a/folder", isDirectory: true)))
|
|
XCTAssertEqual(items[0].sources[1].kind, SourceItemKind.directory)
|
|
XCTAssertEqual(items[1].sources[0].uri, DocumentURI(URL(fileURLWithPath: "/path/to/b/file")))
|
|
XCTAssertEqual(items[1].sources[0].kind, SourceItemKind.file)
|
|
XCTAssertEqual(items[1].sources[1].uri, DocumentURI(URL(fileURLWithPath: "/path/to/b/folder", isDirectory: true)))
|
|
XCTAssertEqual(items[1].sources[1].kind, SourceItemKind.directory)
|
|
expectation.fulfill()
|
|
case .failure(let error):
|
|
XCTFail(error.message)
|
|
}
|
|
})
|
|
XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: 15), .completed)
|
|
}
|
|
|
|
func testBuildTargetOutputs() throws {
|
|
let root = AbsolutePath(
|
|
inputsDirectory().appendingPathComponent(testDirectoryName, isDirectory: true).path)
|
|
let buildFolder = AbsolutePath(NSTemporaryDirectory())
|
|
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
|
|
|
|
let expectation = XCTestExpectation(description: "build target output expectation")
|
|
let targets = [
|
|
BuildTargetIdentifier(uri: DocumentURI(string: "build://target/a")),
|
|
]
|
|
buildSystem.buildTargetOutputPaths(targets: targets, reply: { response in
|
|
switch(response) {
|
|
case .success(let items):
|
|
XCTAssertNotNil(items)
|
|
XCTAssertEqual(items[0].target.uri, targets[0].uri)
|
|
XCTAssertEqual(items[0].outputPaths, [
|
|
DocumentURI(URL(fileURLWithPath: "/path/to/a/file")),
|
|
DocumentURI(URL(fileURLWithPath: "/path/to/a/file2")),
|
|
])
|
|
expectation.fulfill()
|
|
case .failure(let error):
|
|
XCTFail(error.message)
|
|
}
|
|
})
|
|
XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: 15), .completed)
|
|
}
|
|
|
|
func testBuildTargetsChanged() throws {
|
|
let root = AbsolutePath(
|
|
inputsDirectory().appendingPathComponent(testDirectoryName, isDirectory: true).path)
|
|
let buildFolder = AbsolutePath(NSTemporaryDirectory())
|
|
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
|
|
|
|
let fileUrl = URL(fileURLWithPath: "/some/file/path")
|
|
let expectation = XCTestExpectation(description: "target changed")
|
|
let targetIdentifier = BuildTargetIdentifier(uri: DocumentURI(string: "build://target/a"))
|
|
let buildSystemDelegate = TestDelegate(targetExpectations: [
|
|
BuildTargetEvent(target: targetIdentifier,
|
|
kind: .created,
|
|
data: .dictionary(["key": "value"])): expectation,
|
|
])
|
|
buildSystem.delegate = buildSystemDelegate
|
|
buildSystem.registerForChangeNotifications(for: DocumentURI(fileUrl), language: .swift)
|
|
|
|
let result = XCTWaiter.wait(for: [expectation], timeout: 15)
|
|
if result != .completed {
|
|
fatalError("error \(result) waiting for targets changed notification")
|
|
}
|
|
}
|
|
}
|
|
|
|
final class TestDelegate: BuildSystemDelegate {
|
|
|
|
let settingsExpectations: [DocumentURI:XCTestExpectation]
|
|
let targetExpectations: [BuildTargetEvent:XCTestExpectation]
|
|
let dependenciesUpdatedExpectations: [DocumentURI:XCTestExpectation]
|
|
|
|
public init(settingsExpectations: [DocumentURI:XCTestExpectation] = [:],
|
|
targetExpectations: [BuildTargetEvent:XCTestExpectation] = [:],
|
|
dependenciesUpdatedExpectations: [DocumentURI:XCTestExpectation] = [:]) {
|
|
self.settingsExpectations = settingsExpectations
|
|
self.targetExpectations = targetExpectations
|
|
self.dependenciesUpdatedExpectations = dependenciesUpdatedExpectations
|
|
}
|
|
|
|
func buildTargetsChanged(_ changes: [BuildTargetEvent]) {
|
|
for event in changes {
|
|
targetExpectations[event]?.fulfill()
|
|
}
|
|
}
|
|
|
|
func fileBuildSettingsChanged(_ changedFiles: Set<DocumentURI>) {
|
|
for uri in changedFiles {
|
|
settingsExpectations[uri]?.fulfill()
|
|
}
|
|
}
|
|
|
|
public func filesDependenciesUpdated(_ changedFiles: Set<DocumentURI>) {
|
|
for uri in changedFiles {
|
|
dependenciesUpdatedExpectations[uri]?.fulfill()
|
|
}
|
|
}
|
|
}
|