Isolate Shared Test Code (#252)

The goal of this make sure that test code is correctly organized to ensure that test suites aren't dependent on each other.
* UnitTests get their own project now (renaming Microsoft.SqlTools.ServiceLayer.Test to Microsoft.SqlTools.ServiceLayer.UnitTests) which is about 90% of the changes to the files.
* IntegrationTests no longer depends on UnitTests, only Test.Common
* Any shared components from TestObjects that spins up a "live" connection has been moved to IntegrationTests Utility/LiveConnectionHelper.cs
* The dictionary-based mock file stream factory has been moved to Test.Common since it is used by UnitTests and IntegrationTests
    * Added a overload that doesn't take a dictionary for when we don't care about monitoring the storage (about 90% of the time)
* The RunIf* wrapper methods have been moved to Test.Common
* OwnerUri and StandardQuery constants have been moved to Test.Common Constants file

* Updating to latest SDK version available at https://www.microsoft.com/net/core#windowscmd

* Moving unit tests to unit test folder

* Changing namespaces to UnitTests

* Moving some constants and shared functionality into common project, making the UnitTests reference it

* Unit tests are working!

* Integration tests are working

* Updating automated test runs

* Fixing one last broken unit test

* Exposing internals for other projects

* Moving edit data tests to UnitTest project

* Applying refactor fixes to unit tests

* Fixing flaky test that wasn't awaiting completion
This commit is contained in:
Benjamin Russell
2017-03-02 13:00:31 -08:00
committed by GitHub
parent f9abe5f0bd
commit 1166778249
110 changed files with 700 additions and 764 deletions

View File

@@ -0,0 +1,57 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class BinaryQueryExpressionFormatterTests : FormatterUnitTestsBase
{
[Fact]
public void BQE_IndentOperands()
{
FormatOptions options = new FormatOptions();
//options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("BQE_IndentOperands", GetInputFile("BQE_IndentOperands.sql"),
GetBaselineFile("BQE_IndentOperands.sql"), options, true);
}
[Fact]
public void BQE_KeywordCasing_UpperCase()
{
FormatOptions options = new FormatOptions();
options.KeywordCasing = CasingOptions.Uppercase;
LoadAndFormatAndCompare("BQE_KeywordCasing_UpperCase", GetInputFile("BQE_KeywordCasing.sql"),
GetBaselineFile("BQE_KeywordCasing_UpperCase.sql"), options, true);
}
[Fact]
public void BQE_KeywordCasing_LowerCase()
{
FormatOptions options = new FormatOptions();
options.KeywordCasing = CasingOptions.Lowercase;
LoadAndFormatAndCompare("BQE_KeywordCasing_LowerCase", GetInputFile("BQE_KeywordCasing.sql"),
GetBaselineFile("BQE_KeywordCasing_LowerCase.sql"), options, true);
}
[Fact]
public void BQE_KeywordCasing_NoFormat()
{
FormatOptions options = new FormatOptions();
options.KeywordCasing = CasingOptions.None;
LoadAndFormatAndCompare("BQE_KeywordCasing_NoFormat", GetInputFile("BQE_KeywordCasing.sql"),
GetBaselineFile("BQE_KeywordCasing_NoFormat.sql"), options, true);
}
[Fact]
public void BQE_OperatorsOnNewLine()
{
FormatOptions options = new FormatOptions();
LoadAndFormatAndCompare("BQE_OperatorsOnNewLine", GetInputFile("BQE_OperatorsOnNewLine.sql"),
GetBaselineFile("BQE_OperatorsOnNewLine.sql"), options, true);
}
}
}

View File

@@ -0,0 +1,110 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class CommonTableExpressionFormatterTests : FormatterUnitTestsBase
{
[Fact]
public void CTE()
{
LoadAndFormatAndCompare("CTE", GetInputFile("CTE.sql"),
GetBaselineFile("CTE.sql"), new FormatOptions(), true);
}
[Fact]
public void CTE_OneColumn()
{
LoadAndFormatAndCompare("CTE_OneColumn", GetInputFile("CTE_OneColumn.sql"),
GetBaselineFile("CTE_OneColumn.sql"), new FormatOptions(), true);
}
[Fact]
public void CTE_MultipleExpressions()
{
LoadAndFormatAndCompare("CTE_MultipleExpressions", GetInputFile("CTE_MultipleExpressions.sql"),
GetBaselineFile("CTE_MultipleExpressions.sql"), new FormatOptions(), true);
}
[Fact]
public void CTE_CommasBeforeDefinition()
{
FormatOptions options = new FormatOptions();
options.PlaceCommasBeforeNextStatement = true;
// TODO: fix verify to account for commma placement - this can
LoadAndFormatAndCompare("CTE_CommasBeforeDefinition", GetInputFile("CTE.sql"),
GetBaselineFile("CTE_CommasBeforeDefinition.sql"), options, false);
}
[Fact]
public void CTE_EachReferenceOnNewLine()
{
FormatOptions options = new FormatOptions();
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("CTE_EachReferenceOnNewLine", GetInputFile("CTE.sql"),
GetBaselineFile("CTE_EachReferenceOnNewLine.sql"), options, true);
}
[Fact]
public void CTE_EachReferenceOnNewLine_CommasBeforeDefinition()
{
FormatOptions options = new FormatOptions();
options.PlaceCommasBeforeNextStatement = true;
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
// TODO: fix verify to account for commma placement - this can
LoadAndFormatAndCompare("CTE_EachReferenceOnNewLine_CommasBeforeDefinition", GetInputFile("CTE.sql"),
GetBaselineFile("CTE_EachReferenceOnNewLine_CommasBeforeDefinition.sql"), options, false);
}
[Fact]
public void CTE_UseTabs()
{
FormatOptions options = new FormatOptions();
options.UseTabs = true;
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("CTE_UseTabs", GetInputFile("CTE.sql"),
GetBaselineFile("CTE_UseTabs.sql"), options, true);
}
[Fact]
public void CTE_20Spaces()
{
FormatOptions options = new FormatOptions();
options.SpacesPerIndent = 20;
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("CTE_20Spaces", GetInputFile("CTE.sql"),
GetBaselineFile("CTE_20Spaces.sql"), options, true);
}
[Fact]
public void CTE_UpperCaseKeywords()
{
FormatOptions options = new FormatOptions();
options.KeywordCasing = CasingOptions.Uppercase;
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("CTE_UpperCaseKeywords", GetInputFile("CTE.sql"),
GetBaselineFile("CTE_UpperCaseKeywords.sql"), options, true);
}
[Fact]
public void CTE_LowerCaseKeywords()
{
FormatOptions options = new FormatOptions();
options.KeywordCasing = CasingOptions.Lowercase;
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("CTE_LowerCaseKeywords", GetInputFile("CTE.sql"),
GetBaselineFile("CTE_LowerCaseKeywords.sql"), options, true);
}
}
}

View File

@@ -0,0 +1,157 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class CreateProcedureFormatterTests : FormatterUnitTestsBase
{
[Fact]
public void CreateProcedure_BackwardsCompatible()
{
LoadAndFormatAndCompare("CreateProcedure_BackwardsCompatible", GetInputFile("CreateProcedure_BackwardsCompatible.sql"),
GetBaselineFile("CreateProcedure_BackwardsCompatible.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_BeginEnd()
{
LoadAndFormatAndCompare("CreateProcedure_BeginEnd", GetInputFile("CreateProcedure_BeginEnd.sql"),
GetBaselineFile("CreateProcedure_BeginEnd.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_Minimal()
{
LoadAndFormatAndCompare("CreateProcedure_Minimal", GetInputFile("CreateProcedure_Minimal.sql"),
GetBaselineFile("CreateProcedure_Minimal.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_MultipleBatches()
{
LoadAndFormatAndCompare("CreateProcedure_MultipleBatches", GetInputFile("CreateProcedure_MultipleBatches.sql"),
GetBaselineFile("CreateProcedure_MultipleBatches.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_MultipleParams()
{
LoadAndFormatAndCompare("CreateProcedure_MultipleParams", GetInputFile("CreateProcedure_MultipleParams.sql"),
GetBaselineFile("CreateProcedure_MultipleParams.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_OneParam()
{
LoadAndFormatAndCompare("CreateProcedure_OneParam", GetInputFile("CreateProcedure_OneParam.sql"),
GetBaselineFile("CreateProcedure_OneParam.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_ParamsRecompileReturn()
{
LoadAndFormatAndCompare("CreateProcedure_ParamsRecompileReturn", GetInputFile("CreateProcedure_ParamsRecompileReturn.sql"),
GetBaselineFile("CreateProcedure_ParamsRecompileReturn.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_Select()
{
LoadAndFormatAndCompare("CreateProcedure_Select", GetInputFile("CreateProcedure_Select.sql"),
GetBaselineFile("CreateProcedure_Select.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_CommaBeforeNextColumn()
{
// Verifies that commas are placed before the next column instead of after the current one,
// when PlaceCommasBeforeNextStatement = true
LoadAndFormatAndCompare("CreateProcedure_CommaBeforeNextColumn",
GetInputFile("CreateProcedure_CommaHandling1.sql"),
GetBaselineFile("CreateProcedure_CommaBeforeNext.sql"),
new FormatOptions()
{
DatatypeCasing = CasingOptions.Lowercase,
KeywordCasing = CasingOptions.Uppercase,
PlaceCommasBeforeNextStatement = true,
PlaceEachReferenceOnNewLineInQueryStatements = true
}, true);
}
[Fact]
public void CreateProcedure_CommaBeforeNextColumnRepeated()
{
// Verifies that formatting isn't changed for text that's already been formatted
// as having the comma placed before the next column instead of after the prevous one
LoadAndFormatAndCompare("CreateProcedure_CommaBeforeNextColumnRepeated",
GetInputFile("CreateProcedure_CommaHandling2.sql"),
GetBaselineFile("CreateProcedure_CommaBeforeNext.sql"),
new FormatOptions()
{
DatatypeCasing = CasingOptions.Lowercase,
KeywordCasing = CasingOptions.Uppercase,
PlaceCommasBeforeNextStatement = true,
PlaceEachReferenceOnNewLineInQueryStatements = true
},
true);
}
[Fact]
public void CreateProcedure_CommaBeforeNextColumnNoNewline()
{
// Verifies that commas are placed before the next column instead of after the current one,
// when PlaceCommasBeforeNextStatement = true
// And that whitespace is used instead of newline if PlaceEachReferenceOnNewLineInQueryStatements = false
LoadAndFormatAndCompare("CreateProcedure_CommaBeforeNextColumnNoNewline",
GetInputFile("CreateProcedure_CommaHandling1.sql"),
GetBaselineFile("CreateProcedure_CommaSpaced.sql"),
new FormatOptions()
{
DatatypeCasing = CasingOptions.Lowercase,
KeywordCasing = CasingOptions.Uppercase,
PlaceCommasBeforeNextStatement = true,
PlaceEachReferenceOnNewLineInQueryStatements = false
}, true);
}
[Fact]
public void CreateProcedure_TwoPartName()
{
LoadAndFormatAndCompare("CreateProcedure_TwoPartName", GetInputFile("CreateProcedure_TwoPartName.sql"),
GetBaselineFile("CreateProcedure_TwoPartName.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_WithCTE()
{
LoadAndFormatAndCompare("CreateProcedure_WithCTE", GetInputFile("CreateProcedure_WithCTE.sql"),
GetBaselineFile("CreateProcedure_WithCTE.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_WithEncryptionModule()
{
LoadAndFormatAndCompare("CreateProcedure_WithEncryptionModule", GetInputFile("CreateProcedure_WithEncryptionModule.sql"),
GetBaselineFile("CreateProcedure_WithEncryptionModule.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_WithExecuteAsModule()
{
LoadAndFormatAndCompare("CreateProcedure_WithExecuteAsModule", GetInputFile("CreateProcedure_WithExecuteAsModule.sql"),
GetBaselineFile("CreateProcedure_WithExecuteAsModule.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateProcedure_WithThreeModules()
{
LoadAndFormatAndCompare("CreateProcedure_WithThreeModules", GetInputFile("CreateProcedure_WithThreeModules.sql"),
GetBaselineFile("CreateProcedure_WithThreeModules.sql"), new FormatOptions(), true);
}
}
}

View File

@@ -0,0 +1,146 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class CreateTableFormatterTests : FormatterUnitTestsBase
{
[Fact]
public void CreateTable()
{
LoadAndFormatAndCompare("CreateTable", GetInputFile("CreateTable.sql"), GetBaselineFile("CreateTable.sql"), new FormatOptions(), true);
}
/**
* The test contains a timestamp column, which is the shortest (1 token) possible length for a column item.
*/
[Fact]
public void CreateTable_Timestamp()
{
FormatOptions options = new FormatOptions();
options.AlignColumnDefinitionsInColumns = true;
LoadAndFormatAndCompare("CreateTable_Timestamp", GetInputFile("CreateTable_Timestamp.sql"), GetBaselineFile("CreateTable_Timestamp.sql"), options, true);
}
[Fact]
public void CreateTable_CommasBeforeDefinition()
{
FormatOptions options = new FormatOptions();
options.PlaceCommasBeforeNextStatement = true;
// TODO: fix verify to account for commma placement - this can
LoadAndFormatAndCompare("CreateTable_CommasBeforeDefinition", GetInputFile("CreateTable.sql"), GetBaselineFile("CreateTable_CommasBeforeDefinition.sql"), options, false);
}
[Fact]
public void CreateTable_UseTabs()
{
FormatOptions options = new FormatOptions();
options.UseTabs = true;
LoadAndFormatAndCompare("CreateTable_UseTabs", GetInputFile("CreateTable.sql"), GetBaselineFile("CreateTable_UseTabs.sql"), options, true);
}
[Fact]
public void CreateTable_20Spaces()
{
FormatOptions options = new FormatOptions();
options.SpacesPerIndent = 20;
LoadAndFormatAndCompare("CreateTable_20Spaces", GetInputFile("CreateTable.sql"), GetBaselineFile("CreateTable_20Spaces.sql"), options, true);
}
[Fact]
public void CreateTable_UpperCaseKeywords()
{
FormatOptions options = new FormatOptions();
options.KeywordCasing = CasingOptions.Uppercase;
LoadAndFormatAndCompare("CreateTable_UpperCaseKeywords", GetInputFile("CreateTable.sql"), GetBaselineFile("CreateTable_UpperCaseKeywords.sql"), options, true);
}
[Fact]
public void CreateTable_LowerCaseKeywords()
{
FormatOptions options = new FormatOptions();
options.KeywordCasing = CasingOptions.Lowercase;
LoadAndFormatAndCompare("CreateTable_LowerCaseKeywords", GetInputFile("CreateTable.sql"), GetBaselineFile("CreateTable_LowerCaseKeywords.sql"), options, true);
}
[Fact]
public void CreateTable_UpperCaseDataTypes()
{
FormatOptions options = new FormatOptions();
options.DatatypeCasing = CasingOptions.Uppercase;
LoadAndFormatAndCompare("CreateTable_UpperCaseDataTypes", GetInputFile("CreateTable.sql"), GetBaselineFile("CreateTable_UpperCaseDataTypes.sql"), options, true);
}
[Fact]
public void CreateTable_LowerCaseDataTypes()
{
FormatOptions options = new FormatOptions();
options.DatatypeCasing = CasingOptions.Lowercase;
LoadAndFormatAndCompare("CreateTable_LowerCaseDataTypes", GetInputFile("CreateTable.sql"), GetBaselineFile("CreateTable_LowerCaseDataTypes.sql"), options, true);
}
[Fact]
public void CreateTable_AlignInColumns()
{
FormatOptions options = new FormatOptions() { AlignColumnDefinitionsInColumns = true };
LoadAndFormatAndCompare("CreateTable_AlignInColumns", GetInputFile("CreateTable.sql"), GetBaselineFile("CreateTable_AlignInColumns.sql"), options, true);
}
[Fact]
public void CreateTable_AlignInColumnsUseTabs()
{
FormatOptions options = new FormatOptions();
options.UseTabs = true;
options.AlignColumnDefinitionsInColumns = true;
LoadAndFormatAndCompare("CreateTable_AlignInColumnsUseTabs", GetInputFile("CreateTable.sql"), GetBaselineFile("CreateTable_AlignInColumnsUseTabs.sql"), options, true);
}
[Fact]
public void CreateTable_On()
{
LoadAndFormatAndCompare("CreateTableOn", GetInputFile("CreateTableFull.sql"), GetBaselineFile("CreateTableOn.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateTable_Formatted()
{
LoadAndFormatAndCompare("CreateTable_Formatted", GetInputFile("CreateTable_Formatted.sql"), GetBaselineFile("CreateTable_Formatted.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateTable_CommentsBeforeComma()
{
FormatOptions options = new FormatOptions();
options.UseTabs = false;
options.AlignColumnDefinitionsInColumns = true;
options.PlaceCommasBeforeNextStatement = true;
LoadAndFormatAndCompare("CreateTable_CommentsBeforeComma", GetInputFile("CreateTable_CommentBeforeComma.sql"), GetBaselineFile("CreateTable_CommentBeforeComma.sql"), options, true);
}
[Fact]
public void CreateTableAddress_AlignInColumns()
{
FormatOptions options = new FormatOptions();
options.AlignColumnDefinitionsInColumns = true;
LoadAndFormatAndCompare("CreateTableAddress_AlignInColumns", GetInputFile("Address.sql"), GetBaselineFile("CreateTableAddress_AlignInColumns.sql"), options, true);
}
[Fact]
public void CreateTableAddress_AlignInColumnsUseTabs()
{
FormatOptions options = new FormatOptions();
options.UseTabs = true;
options.AlignColumnDefinitionsInColumns = true;
LoadAndFormatAndCompare("CreateTableAddress_AlignInColumnsUseTabs", GetInputFile("Address.sql"), GetBaselineFile("CreateTableAddress_AlignInColumnsUseTabs.sql"), options, true);
}
}
}

View File

@@ -0,0 +1,70 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class CreateViewFormatterTests : FormatterUnitTestsBase
{
[Fact]
public void CreateView_Full()
{
LoadAndFormatAndCompare("CreateView_Full", GetInputFile("CreateView_Full.sql"),
GetBaselineFile("CreateView_Full.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateView_FullWithComments()
{
LoadAndFormatAndCompare("CreateView_FullWithComments", GetInputFile("CreateView_FullWithComments.sql"), GetBaselineFile("CreateView_FullWithComments.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateView_MultipleColumns()
{
LoadAndFormatAndCompare("CreateView_MultipleColumns", GetInputFile("CreateView_MultipleColumns.sql"),
GetBaselineFile("CreateView_MultipleColumns.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateView_MultipleOptions()
{
LoadAndFormatAndCompare("CreateView_MultipleOptions", GetInputFile("CreateView_MultipleOptions.sql"),
GetBaselineFile("CreateView_MultipleOptions.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateView_OneColumn()
{
LoadAndFormatAndCompare("CreateView_OneColumn", GetInputFile("CreateView_OneColumn.sql"),
GetBaselineFile("CreateView_OneColumn.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateView_OneColumnOneOption()
{
LoadAndFormatAndCompare("CreateView_OneColumnOneOption", GetInputFile("CreateView_OneColumnOneOption.sql"),
GetBaselineFile("CreateView_OneColumnOneOption.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateView_OneOption()
{
LoadAndFormatAndCompare("CreateView_OneOption", GetInputFile("CreateView_OneOption.sql"),
GetBaselineFile("CreateView_OneOption.sql"), new FormatOptions(), true);
}
[Fact]
public void CreateView_Simple()
{
LoadAndFormatAndCompare("CreateView_Simple", GetInputFile("CreateView_Simple.sql"),
GetBaselineFile("CreateView_Simple.sql"), new FormatOptions(), true);
}
}
}

View File

@@ -0,0 +1,141 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Microsoft.SqlTools.ServiceLayer.Formatter.Contracts;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Newtonsoft.Json.Linq;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class FormatterSettingsTests
{
[Fact]
public void ValidateFormatterServiceDefaults()
{
var sqlToolsSettings = new SqlToolsSettings();
Assert.Null(sqlToolsSettings.SqlTools.Format.AlignColumnDefinitionsInColumns);
Assert.Equal(CasingOptions.None, sqlToolsSettings.SqlTools.Format.DatatypeCasing);
Assert.Equal(CasingOptions.None, sqlToolsSettings.SqlTools.Format.KeywordCasing);
Assert.Null(sqlToolsSettings.SqlTools.Format.PlaceCommasBeforeNextStatement);
Assert.Null(sqlToolsSettings.SqlTools.Format.PlaceSelectStatementReferencesOnNewLine);
Assert.Null(sqlToolsSettings.SqlTools.Format.UseBracketForIdentifiers);
}
[Fact]
public void ValidateFormatSettingsParsedFromJson()
{
const string settingsJson = @"
{
""params"": {
""mssql"": {
""format"": {
useBracketForIdentifiers: true,
placeCommasBeforeNextStatement: true,
placeSelectStatementReferencesOnNewLine: true,
keywordCasing: ""uppercase"",
datatypeCasing: ""lowercase"",
alignColumnDefinitionsInColumns: true
}
}
}
}";
JObject message = JObject.Parse(settingsJson);
JToken messageParams = null;
message.TryGetValue("params", out messageParams);
SqlToolsSettings sqlToolsSettings = messageParams.ToObject<SqlToolsSettings>();
Assert.True(sqlToolsSettings.SqlTools.Format.AlignColumnDefinitionsInColumns);
Assert.Equal(CasingOptions.Lowercase, sqlToolsSettings.SqlTools.Format.DatatypeCasing);
Assert.Equal(CasingOptions.Uppercase, sqlToolsSettings.SqlTools.Format.KeywordCasing);
Assert.True(sqlToolsSettings.SqlTools.Format.PlaceCommasBeforeNextStatement);
Assert.True(sqlToolsSettings.SqlTools.Format.PlaceSelectStatementReferencesOnNewLine);
Assert.True(sqlToolsSettings.SqlTools.Format.UseBracketForIdentifiers);
}
[Fact]
public void FormatOptionsMatchDefaultSettings()
{
var options = new FormatOptions();
AssertOptionsHaveDefaultValues(options);
}
private static void AssertOptionsHaveDefaultValues(FormatOptions options)
{
Assert.False(options.AlignColumnDefinitionsInColumns);
Assert.Equal(CasingOptions.None, options.DatatypeCasing);
Assert.Equal(CasingOptions.None, options.KeywordCasing);
Assert.False(options.PlaceCommasBeforeNextStatement);
Assert.False(options.PlaceEachReferenceOnNewLineInQueryStatements);
Assert.False(options.EncloseIdentifiersInSquareBrackets);
}
[Fact]
public void CanCopyDefaultFormatSettingsToOptions()
{
var sqlToolsSettings = new SqlToolsSettings();
FormatOptions options = new FormatOptions();
TSqlFormatterService.UpdateFormatOptionsFromSettings(options, sqlToolsSettings.SqlTools.Format);
AssertOptionsHaveDefaultValues(options);
}
[Fact]
public void CanCopyAlteredFormatSettingsToOptions()
{
SqlToolsSettings sqlToolsSettings = CreateNonDefaultFormatSettings();
FormatOptions options = new FormatOptions();
TSqlFormatterService.UpdateFormatOptionsFromSettings(options, sqlToolsSettings.SqlTools.Format);
AssertOptionsHaveExpectedNonDefaultValues(options);
}
private static SqlToolsSettings CreateNonDefaultFormatSettings()
{
var sqlToolsSettings = new SqlToolsSettings();
sqlToolsSettings.SqlTools.Format.AlignColumnDefinitionsInColumns = true;
sqlToolsSettings.SqlTools.Format.DatatypeCasing = CasingOptions.Lowercase;
sqlToolsSettings.SqlTools.Format.KeywordCasing = CasingOptions.Uppercase;
sqlToolsSettings.SqlTools.Format.PlaceCommasBeforeNextStatement = true;
sqlToolsSettings.SqlTools.Format.PlaceSelectStatementReferencesOnNewLine = true;
sqlToolsSettings.SqlTools.Format.UseBracketForIdentifiers = true;
return sqlToolsSettings;
}
private static void AssertOptionsHaveExpectedNonDefaultValues(FormatOptions options)
{
Assert.True(options.AlignColumnDefinitionsInColumns);
Assert.Equal(CasingOptions.Lowercase, options.DatatypeCasing);
Assert.Equal(CasingOptions.Uppercase, options.KeywordCasing);
Assert.True(options.PlaceCommasBeforeNextStatement);
Assert.True(options.PlaceEachReferenceOnNewLineInQueryStatements);
Assert.True(options.EncloseIdentifiersInSquareBrackets);
Assert.False(options.UppercaseDataTypes);
Assert.True(options.UppercaseKeywords);
Assert.True(options.LowercaseDataTypes);
Assert.False(options.LowercaseKeywords);
Assert.False(options.DoNotFormatDataTypes);
Assert.False(options.DoNotFormatKeywords);
}
[Fact]
public void CanMergeRequestOptionsAndSettings()
{
var sqlToolsSettings = CreateNonDefaultFormatSettings();
FormatOptions options = TSqlFormatterService.MergeFormatOptions(
new FormattingOptions { InsertSpaces = true, TabSize = 2 },
sqlToolsSettings.SqlTools.Format);
AssertOptionsHaveExpectedNonDefaultValues(options);
Assert.False(options.UseTabs);
Assert.True(options.UseSpaces);
Assert.Equal(2, options.SpacesPerIndent);
}
}
}

View File

@@ -0,0 +1,89 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System.IO;
using System.Reflection;
using Microsoft.SqlTools.ServiceLayer.Extensibility;
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Moq;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class FormatterUnitTestsBase
{
public FormatterUnitTestsBase()
{
HostMock = new Mock<IProtocolEndpoint>();
WorkspaceServiceMock = new Mock<WorkspaceService<SqlToolsSettings>>();
ServiceProvider = ExtensionServiceProvider.CreateDefaultServiceProvider();
ServiceProvider.RegisterSingleService(WorkspaceServiceMock.Object);
HostLoader.InitializeHostedServices(ServiceProvider, HostMock.Object);
FormatterService = ServiceProvider.GetService<TSqlFormatterService>();
}
protected ExtensionServiceProvider ServiceProvider { get; private set; }
protected Mock<IProtocolEndpoint> HostMock { get; private set; }
protected Mock<WorkspaceService<SqlToolsSettings>> WorkspaceServiceMock { get; private set; }
protected TSqlFormatterService FormatterService { get; private set; }
protected void LoadAndFormatAndCompare(string testName, FileInfo inputFile, FileInfo baselineFile, FormatOptions options, bool verifyFormat)
{
string inputSql = TestUtilities.ReadTextAndNormalizeLineEndings(inputFile.FullName);
string formattedSql = string.Empty;
formattedSql = FormatterService.Format(inputSql, options, verifyFormat);
formattedSql = TestUtilities.NormalizeLineEndings(formattedSql);
string assemblyPath = GetType().GetTypeInfo().Assembly.Location;
string directory = Path.Combine(Path.GetDirectoryName(assemblyPath), "FormatterTests");
Directory.CreateDirectory(directory);
FileInfo outputFile = new FileInfo(Path.Combine(directory, testName + ".out"));
File.WriteAllText(outputFile.FullName, formattedSql);
TestUtilities.CompareTestFiles(baselineFile, outputFile);
}
public FileInfo GetInputFile(string fileName)
{
return new FileInfo(Path.Combine(InputFileDirectory.FullName, fileName));
}
public FileInfo GetBaselineFile(string fileName)
{
return new FileInfo(Path.Combine(BaselineDirectory.FullName, fileName));
}
public DirectoryInfo BaselineDirectory
{
get
{
string d = Path.Combine(TestLocationDirectory, "BaselineFiles");
return new DirectoryInfo(d);
}
}
public DirectoryInfo InputFileDirectory
{
get
{
string d = Path.Combine(TestLocationDirectory, "TestFiles");
return new DirectoryInfo(d);
}
}
private static string TestLocationDirectory
{
get
{
return Path.Combine(RunEnvironmentInfo.GetTestDataLocation(), "TSqlFormatter");
}
}
}
}

View File

@@ -0,0 +1,53 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class GeneralFormatterTests : FormatterUnitTestsBase
{
[Fact]
public void KeywordCaseConversionUppercase()
{
LoadAndFormatAndCompare("KeywordCaseConversion",
GetInputFile("KeywordCaseConversion.sql"),
GetBaselineFile("KeywordCaseConversion_Uppercase.sql"),
new FormatOptions() { KeywordCasing = CasingOptions.Uppercase },
verifyFormat: true);
}
[Fact]
public void KeywordCaseConversionLowercase()
{
LoadAndFormatAndCompare("KeywordCaseConversion",
GetInputFile("KeywordCaseConversion.sql"),
GetBaselineFile("KeywordCaseConversion_Lowercase.sql"),
new FormatOptions() { KeywordCasing = CasingOptions.Lowercase },
verifyFormat: true);
}
[Fact]
public void SelectWithOrderByShouldCorrectlyIndent()
{
LoadAndFormatAndCompare("SelectWithOrderByShouldCorrectlyIndent",
GetInputFile("SelectWithOrderBy.sql"),
GetBaselineFile("SelectWithOrderBy_CorrectIndents.sql"),
new FormatOptions(),
verifyFormat: true);
}
[Fact]
public void SelectStatementShouldCorrectlyIndent()
{
LoadAndFormatAndCompare("SelectStatementShouldCorrectlyIndent",
GetInputFile("CreateProcedure.sql"),
GetBaselineFile("CreateProcedure_CorrectIndents.sql"),
new FormatOptions(),
verifyFormat: true);
}
}
}

View File

@@ -0,0 +1,82 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class InsertFormatterTests : FormatterUnitTestsBase
{
[Fact]
public void Insert_DefaultValues()
{
LoadAndFormatAndCompare("Insert_DefaultValues", GetInputFile("Insert_DefaultValues.sql"),
GetBaselineFile("Insert_DefaultValues.sql"), new FormatOptions(), true);
}
[Fact]
public void Insert_OpenQuery()
{
LoadAndFormatAndCompare("Insert_OpenQuery", GetInputFile("Insert_OpenQuery.sql"),
GetBaselineFile("Insert_OpenQuery.sql"), new FormatOptions(), true);
}
[Fact]
public void Insert_OutputInto()
{
LoadAndFormatAndCompare("Insert_OutputInto", GetInputFile("Insert_OutputInto.sql"),
GetBaselineFile("Insert_OutputInto.sql"), new FormatOptions(), true);
}
[Fact]
public void Insert_OutputStatement()
{
LoadAndFormatAndCompare("Insert_OutputStatement", GetInputFile("Insert_OutputStatement.sql"),
GetBaselineFile("Insert_OutputStatement.sql"), new FormatOptions(), true);
}
[Fact]
public void Insert_Select()
{
FormatOptions options = new FormatOptions();
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("Insert_Select", GetInputFile("Insert_Select.sql"),
GetBaselineFile("Insert_Select.sql"), options, true);
}
[Fact]
public void Insert_SelectSource()
{
FormatOptions options = new FormatOptions();
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("Insert_SelectSource", GetInputFile("Insert_SelectSource.sql"),
GetBaselineFile("Insert_SelectSource.sql"), options, true);
}
[Fact]
public void Insert_TopSpecification()
{
LoadAndFormatAndCompare("Insert_TopSpecification", GetInputFile("Insert_TopSpecification.sql"),
GetBaselineFile("Insert_TopSpecification.sql"), new FormatOptions(), true);
}
[Fact]
public void Insert_TopWithComments()
{
LoadAndFormatAndCompare("Insert_TopWithComments", GetInputFile("Insert_TopWithComments.sql"),
GetBaselineFile("Insert_TopWithComments.sql"), new FormatOptions(), true);
}
[Fact]
public void Insert_Full()
{
LoadAndFormatAndCompare("Insert_Full", GetInputFile("Insert_Full.sql"),
GetBaselineFile("Insert_Full.sql"), new FormatOptions(), true);
}
}
}

View File

@@ -0,0 +1,108 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Formatter;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class SqlSelectStatementFormatterTests : FormatterUnitTestsBase
{
[Fact]
public void SimpleQuery()
{
LoadAndFormatAndCompare("SimpleQuery", GetInputFile("SimpleQuery.sql"),
GetBaselineFile("SimpleQuery.sql"), new FormatOptions(), true);
}
[Fact]
public void SimpleQuery_CommasBeforeDefinition()
{
FormatOptions options = new FormatOptions();
options.PlaceCommasBeforeNextStatement = true;
// TODO: fix verify to account for commma placement - this can
LoadAndFormatAndCompare("SimpleQuery_CommasBeforeDefinition", GetInputFile("SimpleQuery.sql"),
GetBaselineFile("SimpleQuery_CommasBeforeDefinition.sql"), options, false);
}
[Fact]
public void SimpleQuery_EachReferenceOnNewLine()
{
FormatOptions options = new FormatOptions();
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("SimpleQuery_EachReferenceOnNewLine", GetInputFile("SimpleQuery.sql"),
GetBaselineFile("SimpleQuery_EachReferenceOnNewLine.sql"), options, true);
}
[Fact]
public void SimpleQuery_EachReferenceOnNewLine_CommasBeforeDefinition()
{
FormatOptions options = new FormatOptions();
options.PlaceCommasBeforeNextStatement = true;
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
// TODO: fix verify to account for commma placement - this can
LoadAndFormatAndCompare("SimpleQuery_EachReferenceOnNewLine_CommasBeforeDefinition",
GetInputFile("SimpleQuery.sql"), GetBaselineFile("SimpleQuery_EachReferenceOnNewLine_CommasBeforeDefinition.sql"), options, false);
}
[Fact]
public void SimpleQuery_UseTabs()
{
FormatOptions options = new FormatOptions();
options.UseTabs = true;
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("SimpleQuery_UseTabs", GetInputFile("SimpleQuery.sql"),
GetBaselineFile("SimpleQuery_UseTabs.sql"), options, true);
}
[Fact]
public void SimpleQuery_20Spaces()
{
FormatOptions options = new FormatOptions();
options.SpacesPerIndent = 20;
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("SimpleQuery_20Spaces", GetInputFile("SimpleQuery.sql"),
GetBaselineFile("SimpleQuery_20Spaces.sql"), options, true);
}
[Fact]
public void SimpleQuery_UpperCaseKeywords()
{
FormatOptions options = new FormatOptions();
options.KeywordCasing = CasingOptions.Uppercase;
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("SimpleQuery_UpperCaseKeywords", GetInputFile("SimpleQuery.sql"),
GetBaselineFile("SimpleQuery_UpperCaseKeywords.sql"), options, true);
}
[Fact]
public void SimpleQuery_LowerCaseKeywords()
{
FormatOptions options = new FormatOptions();
options.KeywordCasing = CasingOptions.Lowercase;
options.PlaceEachReferenceOnNewLineInQueryStatements = true;
LoadAndFormatAndCompare("SimpleQuery_LowerCaseKeywords", GetInputFile("SimpleQuery.sql"),
GetBaselineFile("SimpleQuery_LowerCaseKeywords.sql"), options, true);
}
[Fact]
public void SimpleQuery_ForBrowseClause()
{
LoadAndFormatAndCompare("SimpleQuery_ForBrowseClause", GetInputFile("SimpleQuery_ForBrowseClause.sql"),
GetBaselineFile("SimpleQuery_ForBrowseClause.sql"), new FormatOptions(), true);
}
[Fact]
public void SimpleQuery_ForXmlClause()
{
LoadAndFormatAndCompare("SimpleQuery_ForXmlClause", GetInputFile("SimpleQuery_ForXmlClause.sql"),
GetBaselineFile("SimpleQuery_ForXmlClause.sql"), new FormatOptions(), true);
}
}
}

View File

@@ -0,0 +1,193 @@
//
// 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.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Formatter.Contracts;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Moq;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Formatter
{
public class TSqlFormatterServiceTests : FormatterUnitTestsBase
{
private Mock<ServiceLayer.Workspace.Workspace> workspaceMock = new Mock<ServiceLayer.Workspace.Workspace>();
private TextDocumentIdentifier textDocument;
DocumentFormattingParams docFormatParams;
DocumentRangeFormattingParams rangeFormatParams;
public TSqlFormatterServiceTests()
{
textDocument = new TextDocumentIdentifier
{
Uri = "script file"
};
docFormatParams = new DocumentFormattingParams()
{
TextDocument = textDocument,
Options = new FormattingOptions() { InsertSpaces = true, TabSize = 4 }
};
rangeFormatParams = new DocumentRangeFormattingParams()
{
TextDocument = textDocument,
Options = new FormattingOptions() { InsertSpaces = true, TabSize = 4 },
Range = new ServiceLayer.Workspace.Contracts.Range()
{
// From first "(" to last ")"
Start = new Position { Line = 0, Character = 16 },
End = new Position { Line = 0, Character = 56 }
}
};
}
private string defaultSqlContents = TestUtilities.NormalizeLineEndings(@"create TABLE T1 ( C1 int NOT NULL, C2 nvarchar(50) NULL)");
// TODO fix bug where '\r' is appended
private string formattedSqlContents = TestUtilities.NormalizeLineEndings(@"create TABLE T1
(
C1 int NOT NULL,
C2 nvarchar(50) NULL
)");
[Fact]
public async Task FormatDocumentShouldReturnSingleEdit()
{
// Given a document that we want to format
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(1, edits.Length);
AssertFormattingEqual(formattedSqlContents, edits[0].NewText);
}));
}
[Fact]
public async Task FormatDocumentTelemetryShouldIncludeFormatTypeProperty()
{
await RunAndVerifyTelemetryTest(
// Given a document that we want to format
preRunSetup: () => SetupScriptFile(defaultSqlContents),
// When format document is called
test: (requestContext) => FormatterService.HandleDocFormatRequest(docFormatParams, requestContext),
verify: (result, actualParams) =>
{
// Then expect a telemetry event to have been sent with the right format definition
Assert.NotNull(actualParams);
Assert.Equal(TelemetryEventNames.FormatCode, actualParams.Params.EventName);
Assert.Equal(TelemetryPropertyNames.DocumentFormatType, actualParams.Params.Properties[TelemetryPropertyNames.FormatType]);
});
}
[Fact]
public async Task FormatRangeTelemetryShouldIncludeFormatTypeProperty()
{
await RunAndVerifyTelemetryTest(
// Given a document that we want to format
preRunSetup: () => SetupScriptFile(defaultSqlContents),
// When format range is called
test: (requestContext) => FormatterService.HandleDocRangeFormatRequest(rangeFormatParams, requestContext),
verify: (result, actualParams) =>
{
// Then expect a telemetry event to have been sent with the right format definition
Assert.NotNull(actualParams);
Assert.Equal(TelemetryEventNames.FormatCode, actualParams.Params.EventName);
Assert.Equal(TelemetryPropertyNames.RangeFormatType, actualParams.Params.Properties[TelemetryPropertyNames.FormatType]);
// And expect range to have been correctly formatted
Assert.Equal(1, result.Length);
AssertFormattingEqual(formattedSqlContents, result[0].NewText);
});
}
private async Task RunAndVerifyTelemetryTest(
Action preRunSetup,
Func<RequestContext<TextEdit[]>, Task> test,
Action<TextEdit[], TelemetryParams> verify)
{
SemaphoreSlim semaphore = new SemaphoreSlim(0, 1);
TelemetryParams actualParams = null;
TextEdit[] result = null;
var contextMock = RequestContextMocks.Create<TextEdit[]>(r =>
{
result = r;
})
.AddErrorHandling(null)
.AddEventHandling(TelemetryNotification.Type, (e, p) =>
{
actualParams = p;
semaphore.Release();
});
// Given a document that we want to format
SetupScriptFile(defaultSqlContents);
// When format document is called
await RunAndVerify<TextEdit[]>(
test: test,
contextMock: contextMock,
verify: () =>
{
// Wait for the telemetry notification to be processed on a background thread
semaphore.Wait(TimeSpan.FromSeconds(10));
verify(result, actualParams);
});
}
public static async Task RunAndVerify<T>(Func<RequestContext<T>, Task> test, Mock<RequestContext<T>> contextMock, Action verify)
{
await test(contextMock.Object);
VerifyResult(contextMock, verify);
}
public static void VerifyResult<T>(Mock<RequestContext<T>> contextMock, Action verify)
{
contextMock.Verify(c => c.SendResult(It.IsAny<T>()), Times.Once);
contextMock.Verify(c => c.SendError(It.IsAny<string>()), Times.Never);
verify();
}
private static void AssertFormattingEqual(string expected, string actual)
{
if (string.Compare(expected, actual) != 0)
{
StringBuilder error = new StringBuilder();
error.AppendLine("======================");
error.AppendLine("Comparison failed:");
error.AppendLine("==Expected==");
error.AppendLine(expected);
error.AppendLine("==Actual==");
error.AppendLine(actual);
Assert.False(false, error.ToString());
}
}
private void SetupScriptFile(string fileContents)
{
WorkspaceServiceMock.SetupGet(service => service.Workspace).Returns(workspaceMock.Object);
workspaceMock.Setup(w => w.GetFile(It.IsAny<string>())).Returns(CreateScriptFile(fileContents));
}
private ScriptFile CreateScriptFile(string content)
{
ScriptFile scriptFile = new ScriptFile()
{
Contents = content
};
return scriptFile;
}
}
}