Skip formatting if the language flavor shows this is not an MSSQL doc (#445)

This commit is contained in:
Kevin Cunnane
2017-08-28 17:38:14 -07:00
committed by GitHub
parent 5ab995d78f
commit 774a777db2
4 changed files with 104 additions and 5 deletions

View File

@@ -53,6 +53,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Formatter
get { return ServiceProvider.GetService<WorkspaceService<SqlToolsSettings>>(); }
}
/// <summary>
/// Gets the language service. Note: should handle case where this is null in cases where unit tests do not set this up
/// </summary>
private LanguageService LanguageService
{
get { return ServiceProvider.GetService<LanguageService>(); }
}
/// <summary>
/// Ensure formatter settings are always up to date
@@ -105,6 +112,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Formatter
{
return await Task.Factory.StartNew(() =>
{
if (ShouldSkipFormatting(docFormatParams))
{
return Array.Empty<TextEdit>();
}
var range = docFormatParams.Range;
ScriptFile scriptFile = GetFile(docFormatParams);
if (scriptFile == null)
@@ -117,10 +129,26 @@ namespace Microsoft.SqlTools.ServiceLayer.Formatter
});
}
private async Task<TextEdit[]> FormatAndReturnEdits(DocumentFormattingParams docFormatParams)
private bool ShouldSkipFormatting(DocumentFormattingParams docFormatParams)
{
if (docFormatParams == null
|| docFormatParams.TextDocument == null
|| docFormatParams.TextDocument.Uri == null)
{
return true;
}
return (LanguageService != null && LanguageService.ShouldSkipNonMssqlFile(docFormatParams.TextDocument.Uri));
}
private async Task<TextEdit[]> FormatAndReturnEdits(DocumentFormattingParams docFormatParams)
{
return await Task.Factory.StartNew(() =>
{
if (ShouldSkipFormatting(docFormatParams))
{
return Array.Empty<TextEdit>();
}
var scriptFile = GetFile(docFormatParams);
if (scriptFile == null
|| scriptFile.FileLines.Count == 0)

View File

@@ -36,7 +36,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
/// Main class for Language Service functionality including anything that requires knowledge of
/// the language to perform, such as definitions, intellisense, etc.
/// </summary>
public sealed class LanguageService: IDisposable
public class LanguageService: IDisposable
{
#region Singleton Instance Implementation
@@ -960,7 +960,11 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
return ShouldSkipNonMssqlFile(scriptFile.ClientFilePath);
}
private bool ShouldSkipNonMssqlFile(string uri)
/// <summary>
/// Checks if a given URI is not an MSSQL file. Only files explicitly excluded by a language flavor change
/// notification will be treated as skippable
/// </summary>
public virtual bool ShouldSkipNonMssqlFile(string uri)
{
bool isNonMssql = false;
nonMssqlUriMap.TryGetValue(uri, out isNonMssql);

View File

@@ -8,6 +8,7 @@ using System.Reflection;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.Extensibility;
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.Workspace;
@@ -21,8 +22,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
HostMock = new Mock<IProtocolEndpoint>();
WorkspaceServiceMock = new Mock<WorkspaceService<SqlToolsSettings>>();
LanguageServiceMock = new Mock<LanguageService>();
ServiceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider();
ServiceProvider.RegisterSingleService(WorkspaceServiceMock.Object);
ServiceProvider.RegisterSingleService(LanguageServiceMock.Object);
HostLoader.InitializeHostedServices(ServiceProvider, HostMock.Object);
FormatterService = ServiceProvider.GetService<TSqlFormatterService>();
}
@@ -30,6 +33,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
protected ExtensionServiceProvider ServiceProvider { get; private set; }
protected Mock<IProtocolEndpoint> HostMock { get; private set; }
protected Mock<WorkspaceService<SqlToolsSettings>> WorkspaceServiceMock { get; private set; }
protected Mock<LanguageService> LanguageServiceMock { get; private set; }
protected TSqlFormatterService FormatterService { get; private set; }

View File

@@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.Formatter.Contracts;
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
@@ -57,10 +58,16 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
C2 nvarchar(50) NULL
)");
private void SetupLanguageService(bool skipFile = false)
{
LanguageServiceMock.Setup(x => x.ShouldSkipNonMssqlFile(It.IsAny<string>())).Returns(skipFile);
}
[Fact]
public async Task FormatDocumentShouldReturnSingleEdit()
{
// Given a document that we want to format
SetupLanguageService();
SetupScriptFile(defaultSqlContents);
// When format document is called
await TestUtils.RunAndVerify<TextEdit[]>(
@@ -73,12 +80,64 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
}));
}
[Fact]
public async Task FormatDocumentShouldSkipNonMssqlFile()
{
// Given a non-MSSQL document
SetupLanguageService(skipFile: true);
SetupScriptFile(defaultSqlContents);
// When format document is called
await TestUtils.RunAndVerify<TextEdit[]>(
test: (requestContext) => FormatterService.HandleDocFormatRequest(docFormatParams, requestContext),
verify: (edits =>
{
// Then expect a single edit to be returned and for it to match the standard formatting
Assert.Equal(0, edits.Length);
LanguageServiceMock.Verify(x => x.ShouldSkipNonMssqlFile(docFormatParams.TextDocument.Uri), Times.Once);
}));
}
[Fact]
public async Task FormatRangeShouldReturnSingleEdit()
{
// Given a document that we want to format
SetupLanguageService();
SetupScriptFile(defaultSqlContents);
// When format document is called
await TestUtils.RunAndVerify<TextEdit[]>(
test: (requestContext) => FormatterService.HandleDocRangeFormatRequest(rangeFormatParams, requestContext),
verify: (edits =>
{
// Then expect a single edit to be returned and for it to match the standard formatting
Assert.Equal(1, edits.Length);
AssertFormattingEqual(formattedSqlContents, edits[0].NewText);
}));
}
[Fact]
public async Task FormatRangeShouldSkipNonMssqlFile()
{
// Given a non-MSSQL document
SetupLanguageService(skipFile: true);
SetupScriptFile(defaultSqlContents);
// When format document is called
await TestUtils.RunAndVerify<TextEdit[]>(
test: (requestContext) => FormatterService.HandleDocRangeFormatRequest(rangeFormatParams, requestContext),
verify: (edits =>
{
// Then expect a single edit to be returned and for it to match the standard formatting
Assert.Equal(0, edits.Length);
LanguageServiceMock.Verify(x => x.ShouldSkipNonMssqlFile(docFormatParams.TextDocument.Uri), Times.Once);
}));
}
[Fact]
public async Task FormatDocumentTelemetryShouldIncludeFormatTypeProperty()
{
await RunAndVerifyTelemetryTest(
// Given a document that we want to format
preRunSetup: () => SetupScriptFile(defaultSqlContents),
preRunSetup: () => SetupLanguageService(),
// When format document is called
test: (requestContext) => FormatterService.HandleDocFormatRequest(docFormatParams, requestContext),
verify: (result, actualParams) =>
@@ -95,7 +154,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
await RunAndVerifyTelemetryTest(
// Given a document that we want to format
preRunSetup: () => SetupScriptFile(defaultSqlContents),
preRunSetup: () => SetupLanguageService(),
// When format range is called
test: (requestContext) => FormatterService.HandleDocRangeFormatRequest(rangeFormatParams, requestContext),
verify: (result, actualParams) =>
@@ -131,6 +190,10 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
});
// Given a document that we want to format
if (preRunSetup != null)
{
preRunSetup();
}
SetupScriptFile(defaultSqlContents);
// When format document is called