Files
sqltoolsservice/test/Microsoft.SqlTools.ServiceLayer.UnitTests/Workspace/WorkspaceTests.cs
Benjamin Russell 1166778249 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
2017-03-02 13:00:31 -08:00

201 lines
7.7 KiB
C#

//
// 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.IO;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Moq;
using Xunit;
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Workspace
{
public class WorkspaceTests
{
[Fact]
public async Task FileClosedSuccessfully()
{
// Given:
// ... A workspace that has a single file open
var workspace = new ServiceLayer.Workspace.Workspace();
var workspaceService = new WorkspaceService<SqlToolsSettings> {Workspace = workspace};
var openedFile = workspace.GetFileBuffer(TestObjects.ScriptUri, string.Empty);
Assert.NotNull(openedFile);
Assert.NotEmpty(workspace.GetOpenedFiles());
// ... And there is a callback registered for the file closed event
ScriptFile closedFile = null;
workspaceService.RegisterTextDocCloseCallback((f, c) =>
{
closedFile = f;
return Task.FromResult(true);
});
// If:
// ... An event to close the open file occurs
var eventContext = new Mock<EventContext>().Object;
var requestParams = new DidCloseTextDocumentParams
{
TextDocument = new TextDocumentItem {Uri = TestObjects.ScriptUri}
};
await workspaceService.HandleDidCloseTextDocumentNotification(requestParams, eventContext);
// Then:
// ... The file should no longer be in the open files
Assert.Empty(workspace.GetOpenedFiles());
// ... The callback should have been called
// ... The provided script file should be the one we created
Assert.NotNull(closedFile);
Assert.Equal(openedFile, closedFile);
}
[Fact]
public async Task FileClosedNotOpen()
{
// Given:
// ... A workspace that has no files open
var workspace = new ServiceLayer.Workspace.Workspace();
var workspaceService = new WorkspaceService<SqlToolsSettings> {Workspace = workspace};
Assert.Empty(workspace.GetOpenedFiles());
// ... And there is a callback registered for the file closed event
bool callbackCalled = false;
workspaceService.RegisterTextDocCloseCallback((f, c) =>
{
callbackCalled = true;
return Task.FromResult(true);
});
// If:
// ... An event to close the a file occurs
var eventContext = new Mock<EventContext>().Object;
var requestParams = new DidCloseTextDocumentParams
{
TextDocument = new TextDocumentItem {Uri = TestObjects.ScriptUri}
};
// Then:
// ... There should be a file not found exception thrown
// TODO: This logic should be changed to not create the ScriptFile
await Assert.ThrowsAnyAsync<IOException>(
() => workspaceService.HandleDidCloseTextDocumentNotification(requestParams, eventContext));
// ... There should still be no open files
// ... The callback should not have been called
Assert.Empty(workspace.GetOpenedFiles());
Assert.False(callbackCalled);
}
[Fact]
public void BufferRangeNoneNotNull()
{
Assert.NotNull(BufferRange.None);
}
[Fact]
public void BufferRangeStartGreaterThanEnd()
{
Assert.Throws<ArgumentException>(() =>
new BufferRange(new BufferPosition(2, 2), new BufferPosition(1, 1)));
}
[Fact]
public void BufferRangeEquals()
{
var range = new BufferRange(new BufferPosition(1, 1), new BufferPosition(2, 2));
Assert.False(range.Equals(null));
Assert.True(range.Equals(range));
Assert.NotNull(range.GetHashCode());
}
[Fact]
public void UnescapePath()
{
Assert.NotNull(Microsoft.SqlTools.ServiceLayer.Workspace.Workspace.UnescapePath("`/path/`"));
}
[Fact]
public void GetBaseFilePath()
{
RunIfWrapper.RunIfWindows(() =>
{
using (var workspace = new ServiceLayer.Workspace.Workspace())
{
Assert.Throws<InvalidOperationException>(() => workspace.GetBaseFilePath("path"));
Assert.NotNull(workspace.GetBaseFilePath(@"c:\path\file.sql"));
Assert.Equal(workspace.GetBaseFilePath("tsqloutput://c:/path/file.sql"), workspace.WorkspacePath);
}
});
}
[Fact]
public void ResolveRelativeScriptPath()
{
RunIfWrapper.RunIfWindows(() =>
{
var workspace = new ServiceLayer.Workspace.Workspace();
Assert.NotNull(workspace.ResolveRelativeScriptPath(null, @"c:\path\file.sql"));
Assert.NotNull(workspace.ResolveRelativeScriptPath(@"c:\path\", "file.sql"));
});
}
[Fact]
public async Task DontProcessGitFileEvents()
{
// setup test workspace
var workspace = new ServiceLayer.Workspace.Workspace();
var workspaceService = new WorkspaceService<SqlToolsSettings> {Workspace = workspace};
// send a document open event with git:/ prefix URI
string filePath = "git:/myfile.sql";
var openParams = new DidOpenTextDocumentNotification
{
TextDocument = new TextDocumentItem { Uri = filePath }
};
await workspaceService.HandleDidOpenTextDocumentNotification(openParams, eventContext: null);
// verify the file is not being tracked by workspace
Assert.False(workspaceService.Workspace.ContainsFile(filePath));
// send a close event with git:/ prefix URI
var closeParams = new DidCloseTextDocumentParams
{
TextDocument = new TextDocumentItem { Uri = filePath }
};
await workspaceService.HandleDidCloseTextDocumentNotification(closeParams, eventContext: null);
// this is not that interesting validation since the open is ignored
// the main validation is that close doesn't raise an exception
Assert.False(workspaceService.Workspace.ContainsFile(filePath));
}
[Fact]
public async Task WorkspaceContainsFile()
{
var workspace = new ServiceLayer.Workspace.Workspace();
var workspaceService = new WorkspaceService<SqlToolsSettings> {Workspace = workspace};
var openedFile = workspace.GetFileBuffer(TestObjects.ScriptUri, string.Empty);
// send a document open event
var openParams = new DidOpenTextDocumentNotification
{
TextDocument = new TextDocumentItem { Uri = TestObjects.ScriptUri }
};
await workspaceService.HandleDidOpenTextDocumentNotification(openParams, eventContext: null);
// verify the file is being tracked by workspace
Assert.True(workspaceService.Workspace.ContainsFile(TestObjects.ScriptUri));
}
}
}