Fix Intellisense not working for saved files (#867)

* Fix tools service to store the corrected file path

* Use ClientFilePath for key

* Further fixes

* Undo spacing changes

* Fix tests

* Trigger CI rebuild
This commit is contained in:
Charles Gagnon
2019-09-19 11:28:40 -07:00
committed by GitHub
parent 9d140b53f3
commit de1bab9f1e
13 changed files with 168 additions and 116 deletions

View File

@@ -42,7 +42,7 @@ namespace Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.Utility
{
ownerUri = GetTestSqlFile();
scriptFile = TestServiceProvider.Instance.WorkspaceService.Workspace.GetFile(ownerUri);
ownerUri = scriptFile.ClientFilePath;
ownerUri = scriptFile.ClientUri;
}
var connectionService = GetLiveTestConnectionService();
var connectionResult =
@@ -68,7 +68,7 @@ namespace Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.Utility
{
ownerUri = GetTestSqlFile();
scriptFile = TestServiceProvider.Instance.WorkspaceService.Workspace.GetFile(ownerUri);
ownerUri = scriptFile.ClientFilePath;
ownerUri = scriptFile.ClientUri;
}
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);

View File

@@ -231,7 +231,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
{
TextDocument = new TextDocumentIdentifier
{
Uri = result.ScriptFile.ClientFilePath
Uri = result.ScriptFile.ClientUri
},
Position = new Position
{
@@ -246,7 +246,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
Thread.Sleep(2000);
// We should get back a non-null ScriptParseInfo
ScriptParseInfo parseInfo = service.GetScriptParseInfo(result.ScriptFile.ClientFilePath);
ScriptParseInfo parseInfo = service.GetScriptParseInfo(result.ScriptFile.ClientUri);
Assert.NotNull(parseInfo);
// And we should get back a non-null SignatureHelp
@@ -298,7 +298,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
{
TextDocument = new TextDocumentIdentifier
{
Uri = connectionInfoResult.ScriptFile.ClientFilePath
Uri = connectionInfoResult.ScriptFile.ClientUri
},
Position = new Position
{
@@ -318,7 +318,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
// And refresh the cache
await langService.HandleRebuildIntelliSenseNotification(
new RebuildIntelliSenseParams() { OwnerUri = connectionInfoResult.ScriptFile.ClientFilePath },
new RebuildIntelliSenseParams() { OwnerUri = connectionInfoResult.ScriptFile.ClientUri },
new TestEventContext());
// Now we should expect to see the item show up in the completion list
@@ -342,24 +342,24 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
public async Task HandleRequestToChangeToSqlcmdFile()
{
var scriptFile = new ScriptFile() { ClientFilePath = "HandleRequestToChangeToSqlcmdFile_" + DateTime.Now.ToLongDateString() + "_.sql" };
var scriptFile = new ScriptFile() { ClientUri = "HandleRequestToChangeToSqlcmdFile_" + DateTime.Now.ToLongDateString() + "_.sql" };
try
{
// Prepare a script file
scriptFile.SetFileContents("koko wants a bananas");
File.WriteAllText(scriptFile.ClientFilePath, scriptFile.Contents);
File.WriteAllText(scriptFile.ClientUri, scriptFile.Contents);
// Create a workspace and add file to it so that its found for intellense building
var workspace = new ServiceLayer.Workspace.Workspace();
var workspaceService = new WorkspaceService<SqlToolsSettings> { Workspace = workspace };
var langService = new LanguageService() { WorkspaceServiceInstance = workspaceService };
langService.CurrentWorkspace.GetFile(scriptFile.ClientFilePath);
langService.CurrentWorkspace.GetFile(scriptFile.ClientUri);
langService.CurrentWorkspaceSettings.SqlTools.IntelliSense.EnableIntellisense = true;
// Add a connection to ensure the intellisense building works
ConnectionInfo connectionInfo = GetLiveAutoCompleteTestObjects().ConnectionInfo;
langService.ConnectionServiceInstance.OwnerToConnectionMap.Add(scriptFile.ClientFilePath, connectionInfo);
langService.ConnectionServiceInstance.OwnerToConnectionMap.Add(scriptFile.ClientUri, connectionInfo);
// Test SQL
int countOfValidationCalls = 0;
@@ -367,7 +367,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
eventContextSql.Setup(x => x.SendEvent(PublishDiagnosticsNotification.Type, It.Is<PublishDiagnosticsNotification>((notif) => ValidateNotification(notif, 2, ref countOfValidationCalls)))).Returns(Task.FromResult(new object()));
await langService.HandleDidChangeLanguageFlavorNotification(new LanguageFlavorChangeParams
{
Uri = scriptFile.ClientFilePath,
Uri = scriptFile.ClientUri,
Language = LanguageService.SQL_LANG.ToLower(),
Flavor = "MSSQL"
}, eventContextSql.Object);
@@ -378,7 +378,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
eventContextSqlCmd.Setup(x => x.SendEvent(PublishDiagnosticsNotification.Type, It.Is<PublishDiagnosticsNotification>((notif) => ValidateNotification(notif, 0, ref countOfValidationCalls)))).Returns(Task.FromResult(new object()));
await langService.HandleDidChangeLanguageFlavorNotification(new LanguageFlavorChangeParams
{
Uri = scriptFile.ClientFilePath,
Uri = scriptFile.ClientUri,
Language = LanguageService.SQL_CMD_LANG.ToLower(),
Flavor = "MSSQL"
}, eventContextSqlCmd.Object);
@@ -388,9 +388,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
}
finally
{
if (File.Exists(scriptFile.ClientFilePath))
if (File.Exists(scriptFile.ClientUri))
{
File.Delete(scriptFile.ClientFilePath);
File.Delete(scriptFile.ClientUri);
}
}
}

View File

@@ -235,7 +235,11 @@ GO";
.Callback<string, Func<IBindingContext, CancellationToken, object>, Func<IBindingContext, object>, Func<Exception, object>, int?, int?>(
(key, bindOperation, timeoutOperation, errHandler, t1, t2) =>
{
timeoutResult = (DefinitionResult)timeoutOperation((IBindingContext)null);
if(timeoutOperation != null)
{
timeoutResult = (DefinitionResult)timeoutOperation(null);
}
itemMock.Object.Result = timeoutResult;
})
.Returns(() => itemMock.Object);
@@ -251,14 +255,14 @@ GO";
};
LiveConnectionHelper.TestConnectionResult connectionResult = LiveConnectionHelper.InitLiveConnectionInfo();
ScriptFile scriptFile = connectionResult.ScriptFile;
ConnectionInfo connInfo = connectionResult.ConnectionInfo;
scriptFile.Contents = "select * from dbo.func ()";
ScriptParseInfo scriptInfo = new ScriptParseInfo { IsConnected = true };
languageService.ScriptParseInfoMap.Add(OwnerUri, scriptInfo);
languageService.ScriptParseInfoMap.Add(scriptFile.ClientUri, scriptInfo);
// When I call the language service
var result = languageService.GetDefinition(textDocument, scriptFile, connInfo);
// Pass in null connection info to force doing a local parse since that hits the BindingQueue timeout
// before we want it to (this is testing the timeout trying to fetch the definitions after the parse)
var result = languageService.GetDefinition(textDocument, scriptFile, null);
// Then I expect null locations and an error to be reported
Assert.NotNull(result);

View File

@@ -44,7 +44,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility
{
ownerUri = GetTestSqlFile();
scriptFile = TestServiceProvider.Instance.WorkspaceService.Workspace.GetFile(ownerUri);
ownerUri = scriptFile.ClientFilePath;
ownerUri = scriptFile.ClientUri;
}
var connectionService = GetLiveTestConnectionService();
var connectionResult =
@@ -70,7 +70,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility
{
ownerUri = GetTestSqlFile();
scriptFile = TestServiceProvider.Instance.WorkspaceService.Workspace.GetFile(ownerUri);
ownerUri = scriptFile.ClientFilePath;
ownerUri = scriptFile.ClientUri;
}
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, databaseName);

View File

@@ -3,23 +3,16 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.SqlServer.Management.SqlParser.Binder;
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
using Microsoft.SqlServer.Management.SqlParser.Parser;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using GlobalCommon = Microsoft.SqlTools.ServiceLayer.Test.Common;
using Moq;
using Xunit;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.LanguageServer
{
@@ -91,11 +84,24 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.LanguageServer
}
[Fact]
public void GetDefinitionInvalidTextDocument()
public async void HandleDefinitionRequest_InvalidTextDocument_SendsEmptyListResponse()
{
InitializeTestObjects();
textDocument.TextDocument.Uri = "invaliduri";
Assert.Null(langService.GetDefinition(textDocument, null, null));
// setup the mock for SendResult
var definitionRequestContext = new Mock<RequestContext<Location[]>>();
Location[] result = null;
definitionRequestContext.Setup(rc => rc.SendResult(It.IsAny<Location[]>()))
.Returns<Location[]>((resultDetails) => {
result = resultDetails;
return Task.FromResult(0);
});
await langService.HandleDefinitionRequest(textDocument, definitionRequestContext.Object);
// Should get an empty array when passed
Assert.NotNull(result);
Assert.True(result.Length == 0, $"Unexpected values passed to SendResult : [{ string.Join(",", (object[])result)}]");
}
[Fact]
@@ -113,11 +119,21 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.LanguageServer
}
[Fact]
public void GetCompletionItemsInvalidTextDocument()
public async void HandleCompletionRequest_InvalidTextDocument_SendsNullResult()
{
InitializeTestObjects();
// setup the mock for SendResult to capture the items
CompletionItem[] completionItems = null;
requestContext.Setup(x => x.SendResult(It.IsAny<CompletionItem[]>()))
.Returns<CompletionItem[]>((resultDetails) => {
completionItems = resultDetails;
return Task.FromResult(0);
});
textDocument.TextDocument.Uri = "somethinggoeshere";
Assert.True(langService.GetCompletionItems(textDocument, scriptFile.Object, null).Result.Length > 0);
await langService.HandleCompletionRequest(textDocument, requestContext.Object);
requestContext.Verify(m => m.SendResult(It.IsAny<CompletionItem[]>()), Times.Once());
Assert.Null(completionItems);
}
[Fact]

View File

@@ -69,12 +69,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.LanguageServer
// set up file for returning the query
scriptFile = new Mock<ScriptFile>();
scriptFile.SetupGet(file => file.Contents).Returns(GlobalCommon.Constants.StandardQuery);
scriptFile.SetupGet(file => file.ClientFilePath).Returns(this.testScriptUri);
scriptFile.SetupGet(file => file.ClientUri).Returns(this.testScriptUri);
// set up workspace mock
workspaceService = new Mock<WorkspaceService<SqlToolsSettings>>();
workspaceService.Setup(service => service.Workspace.GetFile(It.IsAny<string>()))
.Returns(scriptFile.Object);
.Returns((string filePath) => { return filePath == this.testScriptUri ? scriptFile.Object : null; });
// setup binding queue mock
bindingQueue = new Mock<ConnectedBindingQueue>();