diff --git a/src/ServiceHost/Workspace/ScriptFile.cs b/src/ServiceHost/Workspace/ScriptFile.cs
index 90d66244..166b50ea 100644
--- a/src/ServiceHost/Workspace/ScriptFile.cs
+++ b/src/ServiceHost/Workspace/ScriptFile.cs
@@ -106,6 +106,13 @@ namespace Microsoft.SqlTools.EditorServices
#region Constructors
+ ///
+ /// Add a default constructor for testing
+ ///
+ public ScriptFile()
+ {
+ }
+
///
/// Creates a new ScriptFile instance by reading file contents from
/// the given TextReader.
@@ -433,11 +440,11 @@ namespace Microsoft.SqlTools.EditorServices
return new BufferRange(startPosition, endPosition);
}
- #endregion
-
- #region Private Methods
-
- private void SetFileContents(string fileContents)
+ ///
+ /// Set the script files contents
+ ///
+ ///
+ public void SetFileContents(string fileContents)
{
// Split the file contents into lines and trim
// any carriage returns from the strings.
@@ -451,6 +458,10 @@ namespace Microsoft.SqlTools.EditorServices
this.ParseFileContents();
}
+ #endregion
+
+ #region Private Methods
+
///
/// Parses the current file contents to get the AST, tokens,
/// and parse errors.
diff --git a/test/ServiceHost.Test/LanguageServer/LanguageServiceTests.cs b/test/ServiceHost.Test/LanguageServer/LanguageServiceTests.cs
new file mode 100644
index 00000000..70fd2acd
--- /dev/null
+++ b/test/ServiceHost.Test/LanguageServer/LanguageServiceTests.cs
@@ -0,0 +1,116 @@
+//
+// 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.EditorServices;
+using Microsoft.SqlTools.EditorServices.Session;
+using Microsoft.SqlTools.LanguageSupport;
+using Xunit;
+
+namespace Microsoft.SqlTools.Test.LanguageServer
+{
+ ///
+ /// Tests for the ServiceHost Language Service tests
+ ///
+ public class LanguageServiceTests
+ {
+ ///
+ /// Create a test language service instance
+ ///
+ ///
+ private LanguageService CreateTestService()
+ {
+ return new LanguageService(new SqlToolsContext(null, null));
+ }
+
+ #region "Diagnostics tests"
+
+ ///
+ /// Verify that the SQL parser correctly detects errors in text
+ ///
+ [Fact]
+ public void ParseSelectStatementWithoutErrors()
+ {
+ // sql statement with no errors
+ const string sqlWithErrors = "SELECT * FROM sys.objects";
+
+ // get the test service
+ LanguageService service = CreateTestService();
+
+ // parse the sql statement
+ var scriptFile = new ScriptFile();
+ scriptFile.SetFileContents(sqlWithErrors);
+ ScriptFileMarker[] fileMarkers = service.GetSemanticMarkers(scriptFile);
+
+ // verify there are no errors
+ Assert.Equal(0, fileMarkers.Length);
+ }
+
+ ///
+ /// Verify that the SQL parser correctly detects errors in text
+ ///
+ [Fact]
+ public void ParseSelectStatementWithError()
+ {
+ // sql statement with errors
+ const string sqlWithErrors = "SELECT *** FROM sys.objects";
+
+ // get test service
+ LanguageService service = CreateTestService();
+
+ // parse sql statement
+ var scriptFile = new ScriptFile();
+ scriptFile.SetFileContents(sqlWithErrors);
+ ScriptFileMarker[] fileMarkers = service.GetSemanticMarkers(scriptFile);
+
+ // verify there is one error
+ Assert.Equal(1, fileMarkers.Length);
+
+ // verify the position of the error
+ Assert.Equal(9, fileMarkers[0].ScriptRegion.StartColumnNumber);
+ Assert.Equal(1, fileMarkers[0].ScriptRegion.StartLineNumber);
+ Assert.Equal(10, fileMarkers[0].ScriptRegion.EndColumnNumber);
+ Assert.Equal(1, fileMarkers[0].ScriptRegion.EndLineNumber);
+ }
+
+ ///
+ /// Verify that the SQL parser correctly detects errors in text
+ ///
+ [Fact]
+ public void ParseMultilineSqlWithErrors()
+ {
+ // multiline sql with errors
+ const string sqlWithErrors =
+ "SELECT *** FROM sys.objects;\n" +
+ "GO\n" +
+ "SELECT *** FROM sys.objects;\n";
+
+ // get test service
+ LanguageService service = CreateTestService();
+
+ // parse sql
+ var scriptFile = new ScriptFile();
+ scriptFile.SetFileContents(sqlWithErrors);
+ ScriptFileMarker[] fileMarkers = service.GetSemanticMarkers(scriptFile);
+
+ // verify there are two errors
+ Assert.Equal(2, fileMarkers.Length);
+
+ // check position of first error
+ Assert.Equal(9, fileMarkers[0].ScriptRegion.StartColumnNumber);
+ Assert.Equal(1, fileMarkers[0].ScriptRegion.StartLineNumber);
+ Assert.Equal(10, fileMarkers[0].ScriptRegion.EndColumnNumber);
+ Assert.Equal(1, fileMarkers[0].ScriptRegion.EndLineNumber);
+
+ // check position of second error
+ Assert.Equal(9, fileMarkers[1].ScriptRegion.StartColumnNumber);
+ Assert.Equal(3, fileMarkers[1].ScriptRegion.StartLineNumber);
+ Assert.Equal(10, fileMarkers[1].ScriptRegion.EndColumnNumber);
+ Assert.Equal(3, fileMarkers[1].ScriptRegion.EndLineNumber);
+ }
+
+ #endregion
+ }
+}
+