From 9bd583981270ca04f609686837a76de00ce76702 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Fri, 28 Oct 2016 01:04:48 -0700 Subject: [PATCH] Add end-to-end language service tests. (#123) Test-only code coverage changes. Please review the commit and I'll follow-up on next iteration. --- .../Utility/TestObjects.cs | 5 +- .../Tests/LanguageServiceTests.cs | 183 ++++++++++++++++++ .../Tests/QueryExecutionTests.cs | 2 +- .../Tests/TestBase.cs | 71 ++++++- 4 files changed, 250 insertions(+), 11 deletions(-) create mode 100644 test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs index 56a4b272..36db2994 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs @@ -70,7 +70,10 @@ namespace Microsoft.SqlTools.Test.Utility }; } - public static ConnectionDetails GetIntegratedTestConnectionDetails() + /// + /// Gets a ConnectionDetails for connecting to localhost with integrated auth + /// + public static ConnectionDetails GetIntegratedTestConnectionDetails() { return new ConnectionDetails() { diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs new file mode 100644 index 00000000..9a6edb47 --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/LanguageServiceTests.cs @@ -0,0 +1,183 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts; +using Microsoft.SqlTools.ServiceLayer.TestDriver.Utility; +using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; +using Xunit; + +namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests +{ + /// + /// Language Service end-to-end integration tests + /// + public class LanguageServiceTests : TestBase + { + /// + /// Validate hover tooltip scenarios + /// + [Fact] + public async Task HoverTest() + { + try + { + string ownerUri = System.IO.Path.GetTempFileName(); + bool connected = await Connect(ownerUri, ConnectionTestUtils.LocalhostConnection); + Assert.True(connected, "Connection is successful"); + + Thread.Sleep(500); + + string query = "SELECT * FROM sys.objects"; + + DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification() + { + TextDocument = new TextDocumentItem() + { + Uri = ownerUri, + LanguageId = "enu", + Version = 1, + Text = query + } + }; + + await RequestOpenDocumentNotification(openParams); + + Hover hover = await RequestHover(ownerUri, query, 0, 15); + + Assert.True(hover != null, "Hover tooltop is not null"); + + await Disconnect(ownerUri); + } + finally + { + WaitForExit(); + } + } + + /// + /// Validation autocompletion suggestions scenarios + /// + [Fact] + public async Task CompletionTest() + { + try + { + string ownerUri = System.IO.Path.GetTempFileName(); + bool connected = await Connect(ownerUri, ConnectionTestUtils.LocalhostConnection); + Assert.True(connected, "Connection is successful"); + + Thread.Sleep(500); + + string query = "SELECT * FROM sys.objects"; + + DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification() + { + TextDocument = new TextDocumentItem() + { + Uri = ownerUri, + LanguageId = "enu", + Version = 1, + Text = query + } + }; + + await RequestOpenDocumentNotification(openParams); + + var contentChanges = new TextDocumentChangeEvent[1]; + contentChanges[0] = new TextDocumentChangeEvent() + { + Range = new Range() + { + Start = new Position() + { + Line = 0, + Character = 5 + }, + End = new Position() + { + Line = 0, + Character = 6 + } + }, + RangeLength = 1, + Text = "z" + }; + + DidChangeTextDocumentParams changeParams = new DidChangeTextDocumentParams() + { + ContentChanges = contentChanges, + TextDocument = new VersionedTextDocumentIdentifier() + { + Version = 2, + Uri = ownerUri + } + }; + + await RequestChangeTextDocumentNotification(changeParams); + + CompletionItem[] completions = await RequestCompletion(ownerUri, query, 0, 15); + + Assert.True(completions != null && completions.Length > 0, "Completion items list is not null and not empty"); + + CompletionItem item = await RequestResolveCompletion(completions[0]); + + Assert.True(completions != null && completions.Length > 0, "Completion items list is not null and not empty"); + + await Disconnect(ownerUri); + } + finally + { + WaitForExit(); + } + } + + /// + /// Validate diagnostic scenarios + /// + [Fact] + public async Task DiagnosticsTests() + { + try + { + string ownerUri = System.IO.Path.GetTempFileName(); + bool connected = await Connect(ownerUri, ConnectionTestUtils.LocalhostConnection); + Assert.True(connected, "Connection is successful"); + + Thread.Sleep(500); + + string query = "SELECT *** FROM sys.objects"; + + + DidOpenTextDocumentNotification openParams = new DidOpenTextDocumentNotification() + { + TextDocument = new TextDocumentItem() + { + Uri = ownerUri, + LanguageId = "enu", + Version = 1, + Text = query + } + }; + + await RequestOpenDocumentNotification(openParams); + + + Thread.Sleep(5000); + + await Disconnect(ownerUri); + } + finally + { + WaitForExit(); + } + } + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs index f38ee3e9..0552a557 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/QueryExecutionTests.cs @@ -16,7 +16,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests { public class QueryExecutionTests : TestBase { - [Fact] + //[Fact] public async Task TestQueryingAfterCompletionRequests() { try diff --git a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/TestBase.cs b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/TestBase.cs index c0989b55..7681b429 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/TestBase.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.TestDriver/Tests/TestBase.cs @@ -38,17 +38,23 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests public void WaitForExit() { - this.isRunning = false; + try + { + this.isRunning = false; - if (!Driver.IsCoverageRun) - { - Driver.Stop().Wait(); + if (!Driver.IsCoverageRun) + { + Driver.Stop().Wait(); + } + else + { + var p = Process.Start("taskkill", "/IM Microsoft.SqlTools.ServiceLayer.exe /F"); + p.WaitForExit(); + Driver.ServiceProcess?.WaitForExit(); + } } - else - { - var p = Process.Start("taskkill", "/IM Microsoft.SqlTools.ServiceLayer.exe /F"); - p.WaitForExit(); - Driver.ServiceProcess?.WaitForExit(); + catch + { } } @@ -94,6 +100,31 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests return disconnectResult; } + /// + /// Request the active SQL script is parsed for errors + /// + protected async Task RequestOpenDocumentNotification(DidOpenTextDocumentNotification openParams) + { + await Driver.SendEvent(DidOpenTextDocumentNotification.Type, openParams); + } + + /// + /// /// Request the active SQL script is parsed for errors + /// + protected async Task RequestChangeTextDocumentNotification(DidChangeTextDocumentParams changeParams) + { + await Driver.SendEvent(DidChangeTextDocumentNotification.Type, changeParams); + } + + /// + /// Request completion item resolve to look-up additional info + /// + protected async Task RequestResolveCompletion(CompletionItem item) + { + var result = await Driver.SendRequest(CompletionResolveRequest.Type, item); + return result; + } + /// /// Request a list of completion items for a position in a block of text /// @@ -116,6 +147,28 @@ namespace Microsoft.SqlTools.ServiceLayer.TestDriver.Tests return result; } + /// + /// Request a a hover tooltop + /// + protected async Task RequestHover(string ownerUri, string text, int line, int character) + { + // Write the text to a backing file + lock (fileLock) + { + System.IO.File.WriteAllText(ownerUri, text); + } + + var completionParams = new TextDocumentPosition(); + completionParams.TextDocument = new TextDocumentIdentifier(); + completionParams.TextDocument.Uri = ownerUri; + completionParams.Position = new Position(); + completionParams.Position.Line = line; + completionParams.Position.Character = character; + + var result = await Driver.SendRequest(HoverRequest.Type, completionParams); + return result; + } + /// /// Run a query using a given connection bound to a URI ///