From 08521cf61ca8e05ca92cdcd63d55744ca6d061f7 Mon Sep 17 00:00:00 2001 From: Benjamin Russell Date: Wed, 15 Feb 2017 13:02:22 -0800 Subject: [PATCH] Adding TestDbResultSet for Better Mocking (#231) * Replacing the awful and inflexible Dictionary[][] with a much better test data set class * Applying all changes * Removing unused RequestParamTests --- .../Connection/ConnectionServiceTests.cs | 163 ++++++++---------- .../QueryExecution/Common.cs | 78 +++------ .../Execution/DbColumnWrapperTests.cs | 11 +- .../Execution/ResultSetTests.cs | 20 +-- .../Execution/ServiceIntegrationTests.cs | 7 +- .../QueryExecution/ExecutionPlanTests.cs | 4 +- .../SaveResults/ResultSetTests.cs | 9 +- .../SaveResults/ServiceIntegrationTests.cs | 8 +- .../QueryExecution/SubsetTests.cs | 12 +- .../Utility/TestDbDataReader.cs | 123 +++++++------ .../Utility/TestDbDataSet.cs | 49 ++++++ .../Utility/TestObjects.cs | 9 +- 12 files changed, 265 insertions(+), 228 deletions(-) create mode 100644 test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestDbDataSet.cs diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs index 846fe197..9703603f 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs @@ -19,10 +19,6 @@ using Microsoft.SqlTools.Test.Utility; using Moq; using Moq.Protected; using Xunit; -using Microsoft.SqlTools.ServiceLayer.QueryExecution; -using Microsoft.SqlTools.ServiceLayer.SqlContext; -using Microsoft.SqlTools.ServiceLayer.Test.QueryExecution; -using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Test.Connection { @@ -34,7 +30,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// /// Creates a mock db command that returns a predefined result set /// - public static DbCommand CreateTestCommand(Dictionary[][] data) + public static DbCommand CreateTestCommand(TestResultSet[] data) { var commandMock = new Mock { CallBase = true }; var commandMockSetup = commandMock.Protected() @@ -48,7 +44,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// /// Creates a mock db connection that returns predefined data when queried for a result set /// - public DbConnection CreateMockDbConnection(Dictionary[][] data) + public DbConnection CreateMockDbConnection(TestResultSet[] data) { var connectionMock = new Mock { CallBase = true }; connectionMock.Protected() @@ -61,29 +57,26 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection [Fact] public void CanCancelConnectRequest() { - var testFile = "file:///my/test/file.sql"; + const string testFile = "file:///my/test/file.sql"; // Given a connection that times out and responds to cancellation var mockConnection = new Mock { CallBase = true }; CancellationToken token; bool ready = false; - mockConnection.Setup(x => x.OpenAsync(Moq.It.IsAny())) + mockConnection.Setup(x => x.OpenAsync(It.IsAny())) .Callback(t => { // Pass the token to the return handler and signal the main thread to cancel token = t; ready = true; }) - .Returns(() => + .Returns(() => { if (TestUtils.WaitFor(() => token.IsCancellationRequested)) { throw new OperationCanceledException(); } - else - { - return Task.FromResult(true); - } + return Task.FromResult(true); }); var mockFactory = new Mock(); @@ -95,15 +88,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection // Connect the connection asynchronously in a background thread var connectionDetails = TestObjects.GetTestConnectionDetails(); - var connectTask = Task.Run(async () => - { - return await connectionService - .Connect(new ConnectParams() - { - OwnerUri = testFile, - Connection = connectionDetails - }); - }); + var connectTask = Task.Run(async () => await connectionService + .Connect(new ConnectParams + { + OwnerUri = testFile, + Connection = connectionDetails + })); // Wait for the connection to call OpenAsync() Assert.True(TestUtils.WaitFor(() => ready)); @@ -128,34 +118,31 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection [Fact] public async Task CanCancelConnectRequestByConnecting() { - var testFile = "file:///my/test/file.sql"; + const string testFile = "file:///my/test/file.sql"; // Given a connection that times out and responds to cancellation var mockConnection = new Mock { CallBase = true }; CancellationToken token; bool ready = false; - mockConnection.Setup(x => x.OpenAsync(Moq.It.IsAny())) + mockConnection.Setup(x => x.OpenAsync(It.IsAny())) .Callback(t => { // Pass the token to the return handler and signal the main thread to cancel token = t; ready = true; }) - .Returns(() => + .Returns(() => { if (TestUtils.WaitFor(() => token.IsCancellationRequested)) { throw new OperationCanceledException(); } - else - { - return Task.FromResult(true); - } + return Task.FromResult(true); }); // Given a second connection that succeeds var mockConnection2 = new Mock { CallBase = true }; - mockConnection2.Setup(x => x.OpenAsync(Moq.It.IsAny())) + mockConnection2.Setup(x => x.OpenAsync(It.IsAny())) .Returns(() => Task.Run(() => {})); var mockFactory = new Mock(); @@ -168,15 +155,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection // Connect the first connection asynchronously in a background thread var connectionDetails = TestObjects.GetTestConnectionDetails(); - var connectTask = Task.Run(async () => - { - return await connectionService - .Connect(new ConnectParams() - { - OwnerUri = testFile, - Connection = connectionDetails - }); - }); + var connectTask = Task.Run(async () => await connectionService + .Connect(new ConnectParams() + { + OwnerUri = testFile, + Connection = connectionDetails + })); // Wait for the connection to call OpenAsync() Assert.True(TestUtils.WaitFor(() => ready)); @@ -202,13 +186,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection [Fact] public void CanCancelConnectRequestByDisconnecting() { - var testFile = "file:///my/test/file.sql"; + const string testFile = "file:///my/test/file.sql"; // Given a connection that times out and responds to cancellation var mockConnection = new Mock { CallBase = true }; CancellationToken token; bool ready = false; - mockConnection.Setup(x => x.OpenAsync(Moq.It.IsAny())) + mockConnection.Setup(x => x.OpenAsync(It.IsAny())) .Callback(t => { // Pass the token to the return handler and signal the main thread to cancel @@ -221,10 +205,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection { throw new OperationCanceledException(); } - else - { - return Task.FromResult(true); - } + return Task.FromResult(true); }); var mockFactory = new Mock(); @@ -236,22 +217,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection // Connect the first connection asynchronously in a background thread var connectionDetails = TestObjects.GetTestConnectionDetails(); - var connectTask = Task.Run(async () => - { - return await connectionService - .Connect(new ConnectParams() - { - OwnerUri = testFile, - Connection = connectionDetails - }); - }); + var connectTask = Task.Run(async () => await connectionService + .Connect(new ConnectParams + { + OwnerUri = testFile, + Connection = connectionDetails + })); // Wait for the connection to call OpenAsync() Assert.True(TestUtils.WaitFor(() => ready)); // Send a cancellation by trying to disconnect var disconnectResult = connectionService - .Disconnect(new DisconnectParams() + .Disconnect(new DisconnectParams { OwnerUri = testFile }); @@ -382,16 +360,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection public async Task ConnectingWithInvalidCredentialsYieldsErrorMessage() { var testConnectionDetails = TestObjects.GetTestConnectionDetails(); - var invalidConnectionDetails = new ConnectionDetails(); - invalidConnectionDetails.ServerName = testConnectionDetails.ServerName; - invalidConnectionDetails.DatabaseName = testConnectionDetails.DatabaseName; - invalidConnectionDetails.UserName = "invalidUsername"; // triggers exception when opening mock connection - invalidConnectionDetails.Password = "invalidPassword"; + var invalidConnectionDetails = new ConnectionDetails + { + ServerName = testConnectionDetails.ServerName, + DatabaseName = testConnectionDetails.DatabaseName, + UserName = "invalidUsername", + Password = "invalidPassword" + }; + // triggers exception when opening mock connection // Connect to test db with invalid credentials var connectionResult = await TestObjects.GetTestConnectionService() - .Connect(new ConnectParams() + .Connect(new ConnectParams { OwnerUri = "file://my/sample/file.sql", Connection = invalidConnectionDetails @@ -563,7 +544,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection connectionService.ServiceHost = serviceHostMock.Object; // Set up an initial connection - string ownerUri = "file://my/sample/file.sql"; + const string ownerUri = "file://my/sample/file.sql"; var connectionResult = await connectionService .Connect(new ConnectParams() @@ -578,11 +559,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection ConnectionInfo info; Assert.True(connectionService.TryFindConnection(ownerUri, out info)); - // Tell the connection manager that the database change ocurred + // Tell the connection manager that the database change occurred connectionService.ChangeConnectionDatabaseContext(ownerUri, "myOtherDb"); // Verify that the connection changed event was fired - serviceHostMock.Verify(x => x.SendEvent(ConnectionChangedNotification.Type, It.IsAny()), Times.Once()); + serviceHostMock.Verify(x => x.SendEvent(ConnectionChangedNotification.Type, It.IsAny()), Times.Once()); } /// @@ -606,7 +587,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection } /// - /// Verify that we can disconnect from an active connection succesfully + /// Verify that we can disconnect from an active connection successfully /// [Fact] public async Task DisconnectFromDatabaseTest() @@ -758,14 +739,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection public async Task ListDatabasesOnServerForCurrentConnectionReturnsDatabaseNames() { // Result set for the query of database names - Dictionary[] data = + TestDbColumn[] cols = {new TestDbColumn("name")}; + object[][] rows = { - new Dictionary { {"name", "master" } }, - new Dictionary { {"name", "model" } }, - new Dictionary { {"name", "msdb" } }, - new Dictionary { {"name", "tempdb" } }, - new Dictionary { {"name", "mydatabase" } }, + new object[] {"master"}, + new object[] {"model"}, + new object[] {"msdb"}, + new object[] {"tempdb"}, + new object[] {"mydatabase"} }; + TestResultSet data = new TestResultSet(cols, rows); // Setup mock connection factory to inject query results var mockFactory = new Mock(); @@ -787,8 +770,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection Assert.NotEmpty(connectionResult.ConnectionId); // list databases for the connection - ListDatabasesParams parameters = new ListDatabasesParams(); - parameters.OwnerUri = ownerUri; + ListDatabasesParams parameters = new ListDatabasesParams {OwnerUri = ownerUri}; var listDatabasesResult = connectionService.ListDatabases(parameters); string[] databaseNames = listDatabasesResult.DatabaseNames; @@ -818,7 +800,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection ); // connect to a database instance - var connectionResult = await connectionService.Connect(TestObjects.GetTestConnectionParams()); + await connectionService.Connect(TestObjects.GetTestConnectionParams()); // verify that a valid connection id was returned Assert.True(callbackInvoked); @@ -869,7 +851,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection // verify that a valid connection id was returned Assert.NotNull(connectionResult.ConnectionId); - Assert.NotEqual(String.Empty, connectionResult.ConnectionId); + Assert.NotEqual(string.Empty, connectionResult.ConnectionId); Assert.NotNull(new Guid(connectionResult.ConnectionId)); // verify that the (URI -> connection) mapping was created @@ -885,16 +867,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// and remove the code block specific to Linux/OSX. /// [Fact] - public void TestThatLinuxAndOSXSqlExceptionHasNoErrorCode() + public void TestThatLinuxAndOsxSqlExceptionHasNoErrorCode() { TestUtils.RunIfLinuxOrOSX(() => { try { - SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); - builder.DataSource = "bad-server-name"; - builder.UserID = "sa"; - builder.Password = "bad password"; + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder + { + DataSource = "bad-server-name", + UserID = "sa", + Password = "bad password" + }; SqlConnection connection = new SqlConnection(builder.ConnectionString); connection.Open(); // This should fail @@ -907,7 +891,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection }); } - // + /// /// Test that cancel connection with a null connection parameter /// [Fact] @@ -917,7 +901,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection Assert.False(service.CancelConnect(null)); } - // + /// /// Test that cancel connection with a null connection parameter /// [Fact] @@ -941,7 +925,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// /// Test that the connection summary comparer creates a hash code correctly - /// + /// [Theory] [InlineData(true, null, null ,null)] [InlineData(false, null, null, null)] @@ -985,9 +969,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection public void ConnectParamsAreInvalidIfConnectionIsNull() { // Given connection parameters where the connection property is null - ConnectParams parameters = new ConnectParams(); - parameters.OwnerUri = "my/sql/file.sql"; - parameters.Connection = null; + ConnectParams parameters = new ConnectParams + { + OwnerUri = "my/sql/file.sql", + Connection = null + }; string errorMessage; @@ -1044,11 +1030,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection await service.Connect(connectParamsDifferent); Assert.Equal(2, ownerToConnectionMap.Count); - // If we disconenct with the unique URI, there should be 1 connection + // If we disconnect with the unique URI, there should be 1 connection service.Disconnect(disconnectParamsDifferent); Assert.Equal(1, ownerToConnectionMap.Count); - // If we disconenct with the duplicate URI, there should be 0 connections + // If we disconnect with the duplicate URI, there should be 0 connections service.Disconnect(disconnectParamsSame); Assert.Equal(0, ownerToConnectionMap.Count); } @@ -1138,7 +1124,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection // If I connect a Default and a Query connection var service = TestObjects.GetTestConnectionService(); - Dictionary ownerToConnectionMap = service.OwnerToConnectionMap; await service.Connect(connectParamsDefault); await service.Connect(connectParamsQuery); ConnectionInfo connectionInfo = service.OwnerToConnectionMap[connectParamsDefault.OwnerUri]; diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Common.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Common.cs index 4005736e..ba4228bf 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Common.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Common.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.Connection; @@ -59,9 +60,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution #endregion - public static Dictionary[] StandardTestData + public static TestResultSet StandardTestResultSet => new TestResultSet(StandardColumns, StandardRows); + + public static TestResultSet[] StandardTestDataSet => new[] {StandardTestResultSet}; + + public static TestResultSet[] ExecutionPlanTestDataSet { - get { return GetTestData(StandardRows, StandardColumns); } + get + { + DbColumn[] columns = { new TestDbColumn("Microsoft SQL Server 2005 XML Showplan") }; + object[][] rows = { new object[] { "Execution Plan" } }; + return new[] {new TestResultSet(columns, rows)}; + } } #region Public Methods @@ -69,20 +79,20 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution public static Batch GetBasicExecutedBatch() { Batch batch = new Batch(StandardQuery, SubsectionDocument, 1, GetFileStreamFactory(new Dictionary())); - batch.Execute(CreateTestConnection(new[] {StandardTestData}, false), CancellationToken.None).Wait(); + batch.Execute(CreateTestConnection(StandardTestDataSet, false), CancellationToken.None).Wait(); return batch; } public static Batch GetExecutedBatchWithExecutionPlan() { Batch batch = new Batch(StandardQuery, SubsectionDocument, 1, GetFileStreamFactory(new Dictionary())); - batch.Execute(CreateTestConnection(new[] {GetExecutionPlanTestData()}, false), CancellationToken.None).Wait(); + batch.Execute(CreateTestConnection(ExecutionPlanTestDataSet, false), CancellationToken.None).Wait(); return batch; } public static Query GetBasicExecutedQuery() { - ConnectionInfo ci = CreateTestConnectionInfo(new[] {StandardTestData}, false); + ConnectionInfo ci = CreateTestConnectionInfo(StandardTestDataSet, false); // Query won't be able to request a new query DbConnection unless the ConnectionService has a // ConnectionInfo with the same URI as the query, so we will manually set it @@ -96,7 +106,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution public static Query GetBasicExecutedQuery(QueryExecutionSettings querySettings) { - ConnectionInfo ci = CreateTestConnectionInfo(new[] {StandardTestData}, false); + ConnectionInfo ci = CreateTestConnectionInfo(StandardTestDataSet, false); // Query won't be able to request a new query DbConnection unless the ConnectionService has a // ConnectionInfo with the same URI as the query, so we will manually set it @@ -108,43 +118,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution return query; } - public static Dictionary[] GetTestData(int columns, int rows) + public static TestResultSet[] GetTestDataSet(int dataSets) { - Dictionary[] output = new Dictionary[rows]; - for (int row = 0; row < rows; row++) - { - Dictionary rowDictionary = new Dictionary(); - for (int column = 0; column < columns; column++) - { - rowDictionary.Add(string.Format("column{0}", column), string.Format("val{0}{1}", column, row)); - } - output[row] = rowDictionary; - } - - return output; - } - - - public static Dictionary[] GetExecutionPlanTestData() - { - Dictionary[] output = new Dictionary[1]; - int col = 0; - int row = 0; - Dictionary rowDictionary = new Dictionary(); - rowDictionary.Add(string.Format("Microsoft SQL Server 2005 XML Showplan", col), string.Format("Execution Plan", col, row)); - output[row] = rowDictionary; - - return output; - } - - public static Dictionary[][] GetTestDataSet(int dataSets) - { - List[]> output = new List[]>(); - for(int dataSet = 0; dataSet < dataSets; dataSet++) - { - output.Add(StandardTestData); - } - return output.ToArray(); + return Enumerable.Repeat(StandardTestResultSet, dataSets).ToArray(); } public static async Task AwaitExecution(QueryExecutionService service, ExecuteDocumentSelectionParams qeParams, @@ -183,7 +159,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution #region DbConnection Mocking - public static DbCommand CreateTestCommand(Dictionary[][] data, bool throwOnRead) + public static DbCommand CreateTestCommand(TestResultSet[] data, bool throwOnRead) { var commandMock = new Mock { CallBase = true }; var commandMockSetup = commandMock.Protected() @@ -205,7 +181,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution return commandMock.Object; } - public static DbConnection CreateTestConnection(Dictionary[][] data, bool throwOnRead) + public static DbConnection CreateTestConnection(TestResultSet[] data, bool throwOnRead) { var connectionMock = new Mock { CallBase = true }; connectionMock.Protected() @@ -219,7 +195,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution return connectionMock.Object; } - public static ISqlConnectionFactory CreateMockFactory(Dictionary[][] data, bool throwOnRead) + public static ISqlConnectionFactory CreateMockFactory(TestResultSet[] data, bool throwOnRead) { var mockFactory = new Mock(); mockFactory.Setup(factory => factory.CreateSqlConnection(It.IsAny())) @@ -228,21 +204,21 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution return mockFactory.Object; } - public static ConnectionInfo CreateTestConnectionInfo(Dictionary[][] data, bool throwOnRead) + public static ConnectionInfo CreateTestConnectionInfo(TestResultSet[] data, bool throwOnRead) { return new ConnectionInfo(CreateMockFactory(data, throwOnRead), OwnerUri, StandardConnectionDetails); } - public static ConnectionInfo CreateConnectedConnectionInfo(Dictionary[][] data, bool throwOnRead, string type = ConnectionType.Default) + public static ConnectionInfo CreateConnectedConnectionInfo(TestResultSet[] data, bool throwOnRead, string type = ConnectionType.Default) { ConnectionService connectionService = ConnectionService.Instance; connectionService.OwnerToConnectionMap.Clear(); connectionService.ConnectionFactory = CreateMockFactory(data, throwOnRead); - ConnectParams connectParams = new ConnectParams() + ConnectParams connectParams = new ConnectParams { Connection = StandardConnectionDetails, - OwnerUri = Common.OwnerUri, + OwnerUri = OwnerUri, Type = type }; @@ -254,7 +230,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution #region Service Mocking - public static QueryExecutionService GetPrimedExecutionService(Dictionary[][] data, + public static QueryExecutionService GetPrimedExecutionService(TestResultSet[] data, bool isConnected, bool throwOnRead, WorkspaceService workspaceService, out Dictionary storage) { @@ -273,7 +249,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution return new QueryExecutionService(connectionService.Object, workspaceService) { BufferFileStreamFactory = GetFileStreamFactory(storage) }; } - public static QueryExecutionService GetPrimedExecutionService(Dictionary[][] data, bool isConnected, bool throwOnRead, WorkspaceService workspaceService) + public static QueryExecutionService GetPrimedExecutionService(TestResultSet[] data, bool isConnected, bool throwOnRead, WorkspaceService workspaceService) { Dictionary storage; return GetPrimedExecutionService(data, isConnected, throwOnRead, workspaceService, out storage); diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/DbColumnWrapperTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/DbColumnWrapperTests.cs index ca88699b..ab165105 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/DbColumnWrapperTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/DbColumnWrapperTests.cs @@ -29,6 +29,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution { this.DataTypeName = dataTypeName; } + else + { + this.DataTypeName = "int"; + this.DataType = typeof(int); + } if (columnSize.HasValue) { @@ -63,6 +68,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution // check various properties are either null or not null var column = new TestColumn(); var wrapper = new DbColumnWrapper(column); + Assert.NotNull(wrapper.DataTypeName); Assert.NotNull(wrapper.DataType); Assert.Null(wrapper.AllowDBNull); Assert.Null(wrapper.BaseCatalogName); @@ -77,12 +83,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution Assert.Null(wrapper.IsHidden); Assert.Null(wrapper.IsIdentity); Assert.Null(wrapper.IsKey); - Assert.Null(wrapper. IsReadOnly); + Assert.Null(wrapper.IsReadOnly); Assert.Null(wrapper.IsUnique); Assert.Null(wrapper.NumericPrecision); Assert.Null(wrapper.NumericScale); - Assert.Null(wrapper.UdtAssemblyQualifiedName); - Assert.Null(wrapper.DataTypeName); + Assert.Null(wrapper.UdtAssemblyQualifiedName); } /// diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ResultSetTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ResultSetTests.cs index 3aff6f13..7d813be0 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ResultSetTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ResultSetTests.cs @@ -6,11 +6,13 @@ using System; using System.Collections.Generic; using System.Data.Common; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.QueryExecution; using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; +using Microsoft.SqlTools.ServiceLayer.Test.Utility; using Xunit; namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution @@ -63,7 +65,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution // If: // ... I create a new resultset with a valid db data reader that has data // ... and I read it to the end - DbDataReader mockReader = GetReader(new [] {Common.StandardTestData}, false, Common.StandardQuery); + DbDataReader mockReader = GetReader(Common.StandardTestDataSet, false, Common.StandardQuery); var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary()); ResultSet resultSet = new ResultSet(mockReader, Common.Ordinal, Common.Ordinal, fileStreamFactory); resultSet.ResultCompletion += callback; @@ -92,13 +94,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution { // Setup: // ... Build a FOR XML or FOR JSON data set - string columnName = string.Format("{0}_F52E2B61-18A1-11d1-B105-00805F49916B", forType); - List> data = new List>(); - for(int i = 0; i < Common.StandardRows; i++) - { - data.Add(new Dictionary { { columnName, "test data"} }); - } - Dictionary[][] dataSets = {data.ToArray()}; + DbColumn[] columns = {new TestDbColumn(string.Format("{0}_F52E2B61-18A1-11d1-B105-00805F49916B", forType))}; + object[][] rows = Enumerable.Repeat(new object[] {"test data"}, Common.StandardRows).ToArray(); + TestResultSet[] dataSets = {new TestResultSet(columns, rows) }; // ... Create a callback for resultset completion ResultSetSummary resultSummary = null; @@ -158,7 +156,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution // If: // ... I create a new result set with a valid db data reader // ... And execute the result - DbDataReader mockReader = GetReader(new[] {Common.StandardTestData}, false, Common.StandardQuery); + DbDataReader mockReader = GetReader(Common.StandardTestDataSet, false, Common.StandardQuery); var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary()); ResultSet resultSet = new ResultSet(mockReader, Common.Ordinal, Common.Ordinal, fileStreamFactory); await resultSet.ReadResultToEnd(CancellationToken.None); @@ -179,7 +177,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution // If: // ... I create a new result set with a valid db data reader // ... And execute the result set - DbDataReader mockReader = GetReader(new[] { Common.StandardTestData }, false, Common.StandardQuery); + DbDataReader mockReader = GetReader(Common.StandardTestDataSet, false, Common.StandardQuery); var fileStreamFactory = Common.GetFileStreamFactory(new Dictionary()); ResultSet resultSet = new ResultSet(mockReader, Common.Ordinal, Common.Ordinal, fileStreamFactory); await resultSet.ReadResultToEnd(CancellationToken.None); @@ -197,7 +195,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution Assert.Equal(resultSet.Columns.Length, subset.Rows[0].Length); } - private static DbDataReader GetReader(Dictionary[][] dataSet, bool throwOnRead, string query) + private static DbDataReader GetReader(TestResultSet[] dataSet, bool throwOnRead, string query) { var info = Common.CreateTestConnectionInfo(dataSet, throwOnRead); var connection = info.Factory.CreateSqlConnection(ConnectionService.BuildConnectionString(info.ConnectionDetails)); diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ServiceIntegrationTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ServiceIntegrationTests.cs index 6eee53f0..5610513a 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ServiceIntegrationTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/Execution/ServiceIntegrationTests.cs @@ -217,7 +217,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution // If: // ... I request to execute a valid query with results var workspaceService = GetDefaultWorkspaceService(Common.StandardQuery); - var queryService = Common.GetPrimedExecutionService(new[] {Common.StandardTestData}, true, false, + var queryService = Common.GetPrimedExecutionService(Common.StandardTestDataSet, true, false, workspaceService); var queryParams = new ExecuteDocumentSelectionParams { OwnerUri = Common.OwnerUri, QuerySelection = Common.WholeDocument}; @@ -245,7 +245,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution // If: // ... I request to execute a valid query with one batch and multiple result sets var workspaceService = GetDefaultWorkspaceService(Common.StandardQuery); - var dataset = new[] {Common.StandardTestData, Common.StandardTestData}; + var dataset = new[] {Common.StandardTestResultSet, Common.StandardTestResultSet}; var queryService = Common.GetPrimedExecutionService(dataset, true, false, workspaceService); var queryParams = new ExecuteDocumentSelectionParams { OwnerUri = Common.OwnerUri, QuerySelection = Common.WholeDocument}; @@ -273,8 +273,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.Execution // If: // ... I request a to execute a valid query with multiple batches var workspaceService = GetDefaultWorkspaceService(string.Format("{0}\r\nGO\r\n{0}", Common.StandardQuery)); - var dataSet = new[] {Common.StandardTestData}; - var queryService = Common.GetPrimedExecutionService(dataSet, true, false, workspaceService); + var queryService = Common.GetPrimedExecutionService(Common.StandardTestDataSet, true, false, workspaceService); var queryParams = new ExecuteDocumentSelectionParams { OwnerUri = Common.OwnerUri, QuerySelection = Common.WholeDocument}; var efv = new EventFlowValidator() diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/ExecutionPlanTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/ExecutionPlanTests.cs index 1d01a50e..3110e941 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/ExecutionPlanTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/ExecutionPlanTests.cs @@ -137,7 +137,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution // If: // ... I have a query that has results in the form of an execution plan var workspaceService = Common.GetPrimedWorkspaceService(Common.StandardQuery); - var queryService = Common.GetPrimedExecutionService(new[] {Common.GetExecutionPlanTestData()}, true, false, workspaceService); + var queryService = Common.GetPrimedExecutionService(Common.ExecutionPlanTestDataSet, true, false, workspaceService); var executeParams = new ExecuteDocumentSelectionParams { QuerySelection = null, @@ -185,7 +185,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution // If: // ... I have a query that hasn't finished executing (doesn't matter what) var workspaceService = Common.GetPrimedWorkspaceService(Common.StandardQuery); - var queryService = Common.GetPrimedExecutionService(new[] { Common.GetExecutionPlanTestData() }, true, false, workspaceService); + var queryService = Common.GetPrimedExecutionService(Common.ExecutionPlanTestDataSet, true, false, workspaceService); var executeParams = new ExecuteDocumentSelectionParams { QuerySelection = null, diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ResultSetTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ResultSetTests.cs index a97e69f4..c7373112 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ResultSetTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ResultSetTests.cs @@ -12,6 +12,7 @@ using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.QueryExecution; using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts; using Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage; +using Microsoft.SqlTools.ServiceLayer.Test.Utility; using Moq; using Xunit; @@ -66,7 +67,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults // Setup: // ... Create a result set that has been executed ResultSet rs = new ResultSet( - GetReader(new[] { Common.StandardTestData }, false, Common.StandardQuery), + GetReader(Common.StandardTestDataSet, false, Common.StandardQuery), Common.Ordinal, Common.Ordinal, Common.GetFileStreamFactory(new Dictionary())); @@ -93,7 +94,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults // ... Create a result set with dummy data and read to the end ResultSet rs = new ResultSet( - GetReader(new[] {Common.StandardTestData}, false, Common.StandardQuery), + GetReader(Common.StandardTestDataSet, false, Common.StandardQuery), Common.Ordinal, Common.Ordinal, resultFactory); await rs.ReadResultToEnd(CancellationToken.None); @@ -129,7 +130,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults // ... Create a result set with dummy data and read to the end ResultSet rs = new ResultSet( - GetReader(new[] { Common.StandardTestData }, false, Common.StandardQuery), + GetReader(Common.StandardTestDataSet, false, Common.StandardQuery), Common.Ordinal, Common.Ordinal, resultFactory); await rs.ReadResultToEnd(CancellationToken.None); @@ -178,7 +179,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults return mockFactory.Object; } - private static DbDataReader GetReader(Dictionary[][] dataSet, bool throwOnRead, string query) + private static DbDataReader GetReader(TestResultSet[] dataSet, bool throwOnRead, string query) { var info = Common.CreateTestConnectionInfo(dataSet, throwOnRead); var connection = info.Factory.CreateSqlConnection(ConnectionService.BuildConnectionString(info.ConnectionDetails)); diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs index 131011fd..05b0393e 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SaveResults/ServiceIntegrationTests.cs @@ -57,7 +57,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults // ... A working query and workspace service WorkspaceService ws = Common.GetPrimedWorkspaceService(Common.StandardQuery); Dictionary storage; - QueryExecutionService qes = Common.GetPrimedExecutionService(new[] {Common.StandardTestData}, true, false, ws, out storage); + QueryExecutionService qes = Common.GetPrimedExecutionService(Common.ExecutionPlanTestDataSet, true, false, ws, out storage); // ... The query execution service has executed a query with results var executeParams = new ExecuteDocumentSelectionParams { QuerySelection = null, OwnerUri = Common.OwnerUri }; @@ -103,7 +103,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults // ... A working query and workspace service WorkspaceService ws = Common.GetPrimedWorkspaceService(Common.StandardQuery); Dictionary storage; - QueryExecutionService qes = Common.GetPrimedExecutionService(new[] {Common.StandardTestData}, true, false, ws, out storage); + QueryExecutionService qes = Common.GetPrimedExecutionService(Common.ExecutionPlanTestDataSet, true, false, ws, out storage); // ... The query execution service has executed a query with results var executeParams = new ExecuteDocumentSelectionParams {QuerySelection = null, OwnerUri = Common.OwnerUri}; @@ -174,7 +174,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults // ... A working query and workspace service WorkspaceService ws = Common.GetPrimedWorkspaceService(Common.StandardQuery); Dictionary storage; - QueryExecutionService qes = Common.GetPrimedExecutionService(new[] { Common.StandardTestData }, true, false, ws, out storage); + QueryExecutionService qes = Common.GetPrimedExecutionService(Common.StandardTestDataSet, true, false, ws, out storage); // ... The query execution service has executed a query with results var executeParams = new ExecuteDocumentSelectionParams { QuerySelection = null, OwnerUri = Common.OwnerUri }; @@ -220,7 +220,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.SaveResults // ... A working query and workspace service WorkspaceService ws = Common.GetPrimedWorkspaceService(Common.StandardQuery); Dictionary storage; - QueryExecutionService qes = Common.GetPrimedExecutionService(new[] { Common.StandardTestData }, true, false, ws, out storage); + QueryExecutionService qes = Common.GetPrimedExecutionService(Common.StandardTestDataSet, true, false, ws, out storage); // ... The query execution service has executed a query with results var executeParams = new ExecuteDocumentSelectionParams { QuerySelection = null, OwnerUri = Common.OwnerUri }; diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SubsetTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SubsetTests.cs index 28f12d74..39268507 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SubsetTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/SubsetTests.cs @@ -36,8 +36,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution // Then: // ... I should get the requested number of rows back - Assert.Equal(Math.Min(rowCount, Common.StandardTestData.Length), subset.RowCount); - Assert.Equal(Math.Min(rowCount, Common.StandardTestData.Length), subset.Rows.Length); + Assert.Equal(Math.Min(rowCount, Common.StandardTestResultSet.Count()), subset.RowCount); + Assert.Equal(Math.Min(rowCount, Common.StandardTestResultSet.Count()), subset.Rows.Length); } [Theory] @@ -85,8 +85,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution // Then: // I should get the requested number of rows - Assert.Equal(Math.Min(rowCount, Common.StandardTestData.Length), subset.RowCount); - Assert.Equal(Math.Min(rowCount, Common.StandardTestData.Length), subset.Rows.Length); + Assert.Equal(Math.Min(rowCount, Common.StandardTestResultSet.Count()), subset.RowCount); + Assert.Equal(Math.Min(rowCount, Common.StandardTestResultSet.Count()), subset.Rows.Length); } [Theory] @@ -131,7 +131,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution // If: // ... I have a query that has results (doesn't matter what) var workspaceService = Common.GetPrimedWorkspaceService(Common.StandardQuery); - var queryService = Common.GetPrimedExecutionService(new[] {Common.StandardTestData}, true, false, workspaceService); + var queryService = Common.GetPrimedExecutionService(Common.ExecutionPlanTestDataSet, true, false, workspaceService); var executeParams = new ExecuteDocumentSelectionParams {QuerySelection = null, OwnerUri = Common.OwnerUri}; var executeRequest = RequestContextMocks.Create(null); await queryService.HandleExecuteRequest(executeParams, executeRequest.Object); @@ -175,7 +175,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution // If: // ... I have a query that hasn't finished executing (doesn't matter what) var workspaceService = Common.GetPrimedWorkspaceService(Common.StandardQuery); - var queryService = Common.GetPrimedExecutionService(new[] { Common.StandardTestData }, true, false, workspaceService); + var queryService = Common.GetPrimedExecutionService(Common.StandardTestDataSet, true, false, workspaceService); var executeParams = new ExecuteDocumentSelectionParams { QuerySelection = null, OwnerUri = Common.OwnerUri }; var executeRequest = RequestContextMocks.Create(null); await queryService.HandleExecuteRequest(executeParams, executeRequest.Object); diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestDbDataReader.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestDbDataReader.cs index a9233d0b..fb331a88 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestDbDataReader.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestDbDataReader.cs @@ -16,100 +16,116 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Utility #region Test Specific Implementations - private Dictionary[][] Data { get; set; } + private IEnumerable Data { get; } - public IEnumerator[]> ResultSet { get; private set; } + public IEnumerator ResultSetEnumerator { get; } - private IEnumerator> Rows { get; set; } + private IEnumerator RowEnumerator { get; set; } - public TestDbDataReader(Dictionary[][] data) + public TestDbDataReader(IEnumerable data) { Data = data; if (Data != null) { - ResultSet = ((IEnumerable[]>) Data).GetEnumerator(); - ResultSet.MoveNext(); + ResultSetEnumerator = Data.GetEnumerator(); + ResultSetEnumerator.MoveNext(); } } #endregion - public override bool HasRows - { - get { return ResultSet != null && ResultSet.Current.Length > 0; } - } + #region Properties + public override int FieldCount => ResultSetEnumerator?.Current.Columns.Count ?? 0; + + public override bool HasRows => ResultSetEnumerator?.Current.Rows.Count > 0; + + /// + /// Mimicks the behavior of SqlDbDataReader + /// + public override int RecordsAffected => RowEnumerator != null ? -1 : 1; + + public override object this[int ordinal] => RowEnumerator.Current[ordinal]; + + #endregion + + #region Implemented Methods + + /// + /// If the row enumerator hasn't been initialized for the current result set, the + /// enumerator for the current result set is defined. Increments the enumerator + /// + /// True if tere were more rows, false otherwise public override bool Read() { - if (Rows == null) + if (RowEnumerator == null) { - Rows = ((IEnumerable>) ResultSet.Current).GetEnumerator(); + RowEnumerator = ResultSetEnumerator.Current.GetEnumerator(); } - return Rows.MoveNext(); + return RowEnumerator.MoveNext(); } + /// + /// Increments the result set enumerator and initializes the row enumerator + /// + /// public override bool NextResult() { - if (Data == null || !ResultSet.MoveNext()) + if (Data == null || !ResultSetEnumerator.MoveNext()) { return false; } - Rows = ((IEnumerable>)ResultSet.Current).GetEnumerator(); + RowEnumerator = ResultSetEnumerator.Current.GetEnumerator(); return true; } + /// + /// Retrieves the value for the cell of the current row in the given column + /// + /// Ordinal of the column + /// The object in the cell public override object GetValue(int ordinal) { return this[ordinal]; } + /// + /// Stores the values of all cells in this row in the given object array + /// + /// Destination for all cell values + /// Number of cells in the current row public override int GetValues(object[] values) { - for(int i = 0; i < Rows.Current.Count; i++) + for (int i = 0; i < RowEnumerator.Current.Count(); i++) { values[i] = this[i]; } - return Rows.Current.Count; - } - - public override object this[string name] - { - get { return Rows.Current[name]; } - } - - public override object this[int ordinal] - { - get { return Rows.Current[Rows.Current.Keys.AsEnumerable().ToArray()[ordinal]]; } - } - - public ReadOnlyCollection GetColumnSchema() - { - if (ResultSet?.Current == null || ResultSet.Current.Length <= 0) - { - return new ReadOnlyCollection(new List()); - } - - List columns = new List(); - for (int i = 0; i < ResultSet.Current[0].Count; i++) - { - columns.Add(new TestDbColumn(ResultSet.Current[0].Keys.ToArray()[i])); - } - return new ReadOnlyCollection(columns); + return RowEnumerator.Current.Count(); } + /// + /// Whether or not a given cell in the current row is null + /// + /// Ordinal of the column + /// True if the cell is null, false otherwise public override bool IsDBNull(int ordinal) { return this[ordinal] == null; } - public override int FieldCount { get { return Rows?.Current.Count ?? 0; } } - - public override int RecordsAffected + /// Collection of test columns in the current result set + public ReadOnlyCollection GetColumnSchema() { - // Mimics the behavior of SqlDataReader - get { return Rows != null ? -1 : 1; } + if (ResultSetEnumerator?.Current == null || ResultSetEnumerator.Current.Rows.Count <= 0) + { + return new ReadOnlyCollection(new List()); + } + + return new ReadOnlyCollection(ResultSetEnumerator.Current.Columns); } + #endregion + #region Not Implemented public override bool GetBoolean(int ordinal) @@ -207,8 +223,17 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Utility throw new NotImplementedException(); } - public override int Depth { get; } - public override bool IsClosed { get; } + public override object this[string name] + { + get + { + throw new NotImplementedException(); + } + } + + public override int Depth { get { throw new NotImplementedException(); } } + + public override bool IsClosed { get { throw new NotImplementedException(); } } #endregion } diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestDbDataSet.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestDbDataSet.cs new file mode 100644 index 00000000..a012eb8d --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestDbDataSet.cs @@ -0,0 +1,49 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System.Collections; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; + +namespace Microsoft.SqlTools.ServiceLayer.Test.Utility +{ + public class TestResultSet : IEnumerable + { + public List Columns; + public List Rows; + + public TestResultSet(int columns, int rows) + { + Columns = Enumerable.Range(0, columns).Select(i => new TestDbColumn($"Col{i}")).Cast().ToList(); + Rows = new List(rows); + for (int i = 0; i < rows; i++) + { + var row = Enumerable.Range(0, columns).Select(j => $"Cell{i}.{j}").Cast().ToArray(); + Rows.Add(row); + } + } + + public TestResultSet(IEnumerable columns, IEnumerable rows) + { + Columns = new List(columns); + Rows = new List(rows); + } + + #region IEnumerable Impementation + + public IEnumerator GetEnumerator() + { + return (IEnumerator) Rows.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + #endregion + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs index 82b1f9c0..f2e0a06b 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Utility/TestObjects.cs @@ -4,7 +4,6 @@ // using System; -using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.SqlClient; @@ -199,12 +198,12 @@ namespace Microsoft.SqlTools.Test.Utility /// public class TestSqlCommand : DbCommand { - internal TestSqlCommand(Dictionary[][] data) + internal TestSqlCommand(TestResultSet[] data) { Data = data; } - internal Dictionary[][] Data { get; set; } + internal TestResultSet[] Data { get; set; } public override void Cancel() { @@ -251,12 +250,12 @@ namespace Microsoft.SqlTools.Test.Utility /// public class TestSqlConnection : DbConnection { - internal TestSqlConnection(Dictionary[][] data) + internal TestSqlConnection(TestResultSet[] data) { Data = data; } - internal Dictionary[][] Data { get; set; } + internal TestResultSet[] Data { get; set; } protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel) {