//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.LanguageServer
{
///
/// Tests for the ServiceHost Language Service tests
///
public class LanguageServiceTests
{
private LiveConnectionHelper.TestConnectionResult GetLiveAutoCompleteTestObjects()
{
var textDocument = new TextDocumentPosition
{
TextDocument = new TextDocumentIdentifier { Uri = Constants.OwnerUri },
Position = new Position
{
Line = 0,
Character = 0
}
};
var result = LiveConnectionHelper.InitLiveConnectionInfo();
result.TextDocumentPosition = textDocument;
return result;
}
///
/// Test the service initialization code path and verify nothing throws
///
[Fact]
public void ServiceInitialization()
{
try
{
TestServiceProvider serviceProvider = TestServiceProvider.Instance;
Assert.NotNull(serviceProvider);
}
catch (System.ArgumentException)
{
}
Assert.True(LanguageService.Instance.Context != null);
Assert.True(LanguageService.Instance.ConnectionServiceInstance != null);
Assert.True(LanguageService.Instance.CurrentWorkspaceSettings != null);
Assert.True(LanguageService.Instance.CurrentWorkspace != null);
}
///
/// Test the service initialization code path and verify nothing throws
///
[Fact]
public void PrepopulateCommonMetadata()
{
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
{
var result = LiveConnectionHelper.InitLiveConnectionInfo("master", queryTempFile.FilePath);
var connInfo = result.ConnectionInfo;
ScriptParseInfo scriptInfo = new ScriptParseInfo { IsConnected = true };
LanguageService.Instance.PrepopulateCommonMetadata(connInfo, scriptInfo, null);
}
}
// This test currently requires a live database connection to initialize
// SMO connected metadata provider. Since we don't want a live DB dependency
// in the CI unit tests this scenario is currently disabled.
[Fact]
public void AutoCompleteFindCompletions()
{
var result = GetLiveAutoCompleteTestObjects();
result.TextDocumentPosition.Position.Character = 7;
result.ScriptFile.Contents = "select ";
var autoCompleteService = LanguageService.Instance;
var completions = autoCompleteService.GetCompletionItems(
result.TextDocumentPosition,
result.ScriptFile,
result.ConnectionInfo);
Assert.True(completions.Length > 0);
}
///
/// Verify that GetSignatureHelp returns not null when the provided TextDocumentPosition
/// has an associated ScriptParseInfo and the provided query has a function that should
/// provide signature help.
///
[Fact]
public async Task GetSignatureHelpReturnsNotNullIfParseInfoInitialized()
{
// When we make a connection to a live database
Hosting.ServiceHost.SendEventIgnoreExceptions = true;
var result = LiveConnectionHelper.InitLiveConnectionInfo();
// And we place the cursor after a function that should prompt for signature help
string queryWithFunction = "EXEC sys.fn_isrolemember ";
result.ScriptFile.Contents = queryWithFunction;
TextDocumentPosition textDocument = new TextDocumentPosition
{
TextDocument = new TextDocumentIdentifier
{
Uri = result.ScriptFile.ClientFilePath
},
Position = new Position
{
Line = 0,
Character = queryWithFunction.Length
}
};
// If the SQL has already been parsed
var service = LanguageService.Instance;
await service.UpdateLanguageServiceOnConnection(result.ConnectionInfo);
Thread.Sleep(2000);
// We should get back a non-null ScriptParseInfo
ScriptParseInfo parseInfo = service.GetScriptParseInfo(result.ScriptFile.ClientFilePath);
Assert.NotNull(parseInfo);
// And we should get back a non-null SignatureHelp
SignatureHelp signatureHelp = service.GetSignatureHelp(textDocument, result.ScriptFile);
Assert.NotNull(signatureHelp);
}
///
/// Test overwriting the binding queue context
///
[Fact]
public void OverwriteBindingContext()
{
var result = LiveConnectionHelper.InitLiveConnectionInfo();
// add a new connection context
var connectionKey = LanguageService.Instance.BindingQueue.AddConnectionContext(result.ConnectionInfo, overwrite: true);
Assert.True(LanguageService.Instance.BindingQueue.BindingContextMap.ContainsKey(connectionKey));
// cache the server connection
var orgServerConnection = LanguageService.Instance.BindingQueue.BindingContextMap[connectionKey].ServerConnection;
Assert.NotNull(orgServerConnection);
// add a new connection context
connectionKey = LanguageService.Instance.BindingQueue.AddConnectionContext(result.ConnectionInfo, overwrite: true);
Assert.True(LanguageService.Instance.BindingQueue.BindingContextMap.ContainsKey(connectionKey));
Assert.False(object.ReferenceEquals(LanguageService.Instance.BindingQueue.BindingContextMap[connectionKey].ServerConnection, orgServerConnection));
}
}
}