mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 09:35:43 -05:00
* Make nullable warnings a per file opt-in * Remove unneeded compiler directives * Remove compiler directive for User Data
260 lines
10 KiB
C#
260 lines
10 KiB
C#
//
|
|
// Copyright (c) Microsoft. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
//
|
|
|
|
#nullable disable
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.SqlTools.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 NUnit.Framework;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Workspace
|
|
{
|
|
public class WorkspaceTests
|
|
{
|
|
[Test]
|
|
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.That(workspace.GetOpenedFiles(), Is.Not.Empty);
|
|
|
|
// ... And there is a callback registered for the file closed event
|
|
ScriptFile closedFile = null;
|
|
string closedUri = null;
|
|
workspaceService.RegisterTextDocCloseCallback((u, f, c) =>
|
|
{
|
|
closedUri = u;
|
|
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.That(workspace.GetOpenedFiles(), Is.Empty);
|
|
|
|
// ... The callback should have been called
|
|
// ... The provided script file should be the one we created
|
|
Assert.NotNull(closedFile);
|
|
Assert.AreEqual(openedFile, closedFile);
|
|
Assert.AreEqual(TestObjects.ScriptUri, closedUri);
|
|
}
|
|
|
|
[Test]
|
|
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.That(workspace.GetOpenedFiles(), Is.Empty);
|
|
|
|
// ... And there is a callback registered for the file closed event
|
|
bool callbackCalled = false;
|
|
workspaceService.RegisterTextDocCloseCallback((u, 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:
|
|
await workspaceService.HandleDidCloseTextDocumentNotification(requestParams, eventContext);
|
|
|
|
// ... There should still be no open files
|
|
// ... The callback should not have been called
|
|
Assert.That(workspace.GetOpenedFiles(), Is.Empty);
|
|
Assert.False(callbackCalled);
|
|
}
|
|
|
|
[Test]
|
|
public void BufferRangeNoneNotNull()
|
|
{
|
|
Assert.NotNull(BufferRange.None);
|
|
}
|
|
|
|
[Test]
|
|
public void BufferRangeStartGreaterThanEnd()
|
|
{
|
|
Assert.Throws<ArgumentException>(() =>
|
|
new BufferRange(new BufferPosition(2, 2), new BufferPosition(1, 1)));
|
|
}
|
|
|
|
[Test]
|
|
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());
|
|
}
|
|
|
|
[Test]
|
|
public void UnescapePath()
|
|
{
|
|
Assert.NotNull(Microsoft.SqlTools.ServiceLayer.Workspace.Workspace.UnescapePath("`/path/`"));
|
|
}
|
|
|
|
[Test]
|
|
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.AreEqual(workspace.GetBaseFilePath("tsqloutput://c:/path/file.sql"), workspace.WorkspacePath);
|
|
}
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
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"));
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public async Task DontProcessGitFileEvents()
|
|
{
|
|
await VerifyFileIsNotAddedOnDocOpened("git:/myfile.sql");
|
|
}
|
|
|
|
[Test]
|
|
public async Task DontProcessPerforceFileEvents()
|
|
{
|
|
await VerifyFileIsNotAddedOnDocOpened("perforce:/myfile.sql");
|
|
}
|
|
|
|
private async Task VerifyFileIsNotAddedOnDocOpened(string filePath)
|
|
{
|
|
// 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
|
|
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));
|
|
}
|
|
|
|
[Test]
|
|
public void GetFileReturnsNullForPerforceFile()
|
|
{
|
|
// when I ask for a non-file object in the workspace, it should return null
|
|
var workspace = new ServiceLayer.Workspace.Workspace();
|
|
ScriptFile file = workspace.GetFile("perforce:myfile.sql");
|
|
Assert.Null(file);
|
|
}
|
|
|
|
[Test]
|
|
[TestCase(TestObjects.ScriptUri)]
|
|
[TestCase("file://some/path%20with%20encoded%20spaces/file.sql")]
|
|
[TestCase("file://some/path with spaces/file.sql")]
|
|
[TestCase("file://some/fileWith#.sql")]
|
|
[TestCase("file://some/fileUriWithQuery.sql?var=foo")]
|
|
[TestCase("file://some/fileUriWithFragment.sql#foo")]
|
|
public async Task WorkspaceContainsFile(string uri)
|
|
{
|
|
var workspace = new ServiceLayer.Workspace.Workspace();
|
|
var workspaceService = new WorkspaceService<SqlToolsSettings> {Workspace = workspace};
|
|
workspace.GetFileBuffer(uri, string.Empty);
|
|
|
|
// send a document open event
|
|
var openParams = new DidOpenTextDocumentNotification
|
|
{
|
|
TextDocument = new TextDocumentItem { Uri = uri }
|
|
};
|
|
|
|
await workspaceService.HandleDidOpenTextDocumentNotification(openParams, eventContext: null);
|
|
|
|
// verify the file is being tracked by workspace
|
|
Assert.True(workspaceService.Workspace.ContainsFile(uri));
|
|
}
|
|
|
|
[Test]
|
|
public void DontBindToObjectExplorerConnectEvents()
|
|
{
|
|
// when I ask for a non-file object in the workspace, it should return null
|
|
var workspace = new ServiceLayer.Workspace.Workspace();
|
|
ScriptFile file = workspace.GetFile("objectexplorer://server;database=database;user=user");
|
|
Assert.Null(file);
|
|
|
|
// when I ask for a file, it should return the file
|
|
string tempFile = Path.GetTempFileName();
|
|
string fileContents = "hello world";
|
|
File.WriteAllText(tempFile, fileContents);
|
|
|
|
file = workspace.GetFile(tempFile);
|
|
Assert.AreEqual(fileContents, file.Contents);
|
|
|
|
if (tempFile.StartsWith("/"))
|
|
{
|
|
tempFile = tempFile.Substring(1);
|
|
}
|
|
file = workspace.GetFile("file://" + tempFile);
|
|
Assert.AreEqual(fileContents, file.Contents);
|
|
|
|
file = workspace.GetFileBuffer("untitled://"+ tempFile, fileContents);
|
|
Assert.AreEqual(fileContents, file.Contents);
|
|
|
|
// For windows files, just check scheme is null since it's hard to mock file contents in these
|
|
Assert.Null(ServiceLayer.Workspace.Workspace.GetScheme(@"C:\myfile.sql"));
|
|
Assert.Null(ServiceLayer.Workspace.Workspace.GetScheme(@"\\myfile.sql"));
|
|
}
|
|
|
|
}
|
|
}
|