mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
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
248 lines
7.2 KiB
C#
248 lines
7.2 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.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Data.Common;
|
|
using System.Linq;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Utility
|
|
{
|
|
public class TestDbDataReader : DbDataReader, IDbColumnSchemaGenerator
|
|
{
|
|
|
|
#region Test Specific Implementations
|
|
|
|
private IEnumerable<TestResultSet> Data { get; }
|
|
|
|
public IEnumerator<TestResultSet> ResultSetEnumerator { get; }
|
|
|
|
private IEnumerator<object[]> RowEnumerator { get; set; }
|
|
|
|
public TestDbDataReader(IEnumerable<TestResultSet> data)
|
|
{
|
|
Data = data;
|
|
if (Data != null)
|
|
{
|
|
ResultSetEnumerator = Data.GetEnumerator();
|
|
ResultSetEnumerator.MoveNext();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
public override int FieldCount => ResultSetEnumerator?.Current.Columns.Count ?? 0;
|
|
|
|
public override bool HasRows => ResultSetEnumerator?.Current.Rows.Count > 0;
|
|
|
|
/// <summary>
|
|
/// Mimicks the behavior of SqlDbDataReader
|
|
/// </summary>
|
|
public override int RecordsAffected => RowEnumerator != null ? -1 : 1;
|
|
|
|
public override object this[int ordinal] => RowEnumerator.Current[ordinal];
|
|
|
|
#endregion
|
|
|
|
#region Implemented Methods
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
/// <returns>True if tere were more rows, false otherwise</returns>
|
|
public override bool Read()
|
|
{
|
|
if (RowEnumerator == null)
|
|
{
|
|
RowEnumerator = ResultSetEnumerator.Current.GetEnumerator();
|
|
}
|
|
return RowEnumerator.MoveNext();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Increments the result set enumerator and initializes the row enumerator
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override bool NextResult()
|
|
{
|
|
if (Data == null || !ResultSetEnumerator.MoveNext())
|
|
{
|
|
return false;
|
|
}
|
|
RowEnumerator = ResultSetEnumerator.Current.GetEnumerator();
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves the value for the cell of the current row in the given column
|
|
/// </summary>
|
|
/// <param name="ordinal">Ordinal of the column</param>
|
|
/// <returns>The object in the cell</returns>
|
|
public override object GetValue(int ordinal)
|
|
{
|
|
return this[ordinal];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stores the values of all cells in this row in the given object array
|
|
/// </summary>
|
|
/// <param name="values">Destination for all cell values</param>
|
|
/// <returns>Number of cells in the current row</returns>
|
|
public override int GetValues(object[] values)
|
|
{
|
|
for (int i = 0; i < RowEnumerator.Current.Count(); i++)
|
|
{
|
|
values[i] = this[i];
|
|
}
|
|
return RowEnumerator.Current.Count();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Whether or not a given cell in the current row is null
|
|
/// </summary>
|
|
/// <param name="ordinal">Ordinal of the column</param>
|
|
/// <returns>True if the cell is null, false otherwise</returns>
|
|
public override bool IsDBNull(int ordinal)
|
|
{
|
|
return this[ordinal] == null;
|
|
}
|
|
|
|
/// <returns>Collection of test columns in the current result set</returns>
|
|
public ReadOnlyCollection<DbColumn> GetColumnSchema()
|
|
{
|
|
if (ResultSetEnumerator?.Current == null || ResultSetEnumerator.Current.Rows.Count <= 0)
|
|
{
|
|
return new ReadOnlyCollection<DbColumn>(new List<DbColumn>());
|
|
}
|
|
|
|
return new ReadOnlyCollection<DbColumn>(ResultSetEnumerator.Current.Columns);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Not Implemented
|
|
|
|
public override bool GetBoolean(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override byte GetByte(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override char GetChar(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)
|
|
{
|
|
char[] allChars = ((string) RowEnumerator.Current[ordinal]).ToCharArray();
|
|
int outLength = allChars.Length;
|
|
if (buffer != null)
|
|
{
|
|
Array.Copy(allChars, (int) dataOffset, buffer, bufferOffset, outLength);
|
|
}
|
|
return outLength;
|
|
}
|
|
|
|
public override string GetDataTypeName(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override DateTime GetDateTime(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override decimal GetDecimal(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override double GetDouble(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override int GetOrdinal(string name)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override string GetName(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override long GetInt64(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override int GetInt32(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override short GetInt16(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override Guid GetGuid(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override float GetFloat(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override Type GetFieldType(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override string GetString(int ordinal)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override IEnumerator GetEnumerator()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|