using System.Data; using JdeScoping.DataSync.Etl.Transformers; using NSubstitute; namespace JdeScoping.DataSync.Tests.Etl.Transformers; public class TransformingDataReaderTests { [Fact] public void Read_DelegatesToSourceReader() { var source = Substitute.For(); source.Read().Returns(true, true, false); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.True(reader.Read()); Assert.True(reader.Read()); Assert.False(reader.Read()); } [Fact] public void FieldCount_DelegatesToTransformer() { var source = Substitute.For(); source.FieldCount.Returns(5); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.Equal(5, reader.FieldCount); } [Fact] public void GetName_DelegatesToTransformer() { var source = Substitute.For(); source.GetName(0).Returns("OriginalName"); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.Equal("OriginalName", reader.GetName(0)); } [Fact] public void GetValue_DelegatesToTransformer() { var source = Substitute.For(); source.GetValue(0).Returns("TestValue"); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.Equal("TestValue", reader.GetValue(0)); } [Fact] public void GetOrdinal_DelegatesToTransformer() { var source = Substitute.For(); source.GetOrdinal("TestField").Returns(3); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.Equal(3, reader.GetOrdinal("TestField")); } [Fact] public void GetFieldType_DelegatesToTransformer() { var source = Substitute.For(); source.GetFieldType(0).Returns(typeof(string)); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.Equal(typeof(string), reader.GetFieldType(0)); } [Fact] public void IsDBNull_DelegatesToTransformer() { var source = Substitute.For(); source.IsDBNull(0).Returns(true); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.True(reader.IsDBNull(0)); } [Fact] public void Indexer_ByOrdinal_UsesGetValue() { var source = Substitute.For(); source.GetValue(1).Returns("IndexedValue"); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.Equal("IndexedValue", reader[1]); } [Fact] public void Indexer_ByName_UsesGetOrdinalAndGetValue() { var source = Substitute.For(); source.GetOrdinal("TestColumn").Returns(2); source.GetValue(2).Returns("NamedValue"); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.Equal("NamedValue", reader["TestColumn"]); } [Fact] public void GetValues_PopulatesArrayWithTransformedValues() { var source = Substitute.For(); source.FieldCount.Returns(3); source.GetValue(0).Returns("Value0"); source.GetValue(1).Returns("Value1"); source.GetValue(2).Returns("Value2"); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); var values = new object[3]; var count = reader.GetValues(values); Assert.Equal(3, count); Assert.Equal("Value0", values[0]); Assert.Equal("Value1", values[1]); Assert.Equal("Value2", values[2]); } [Fact] public void Dispose_DisposesSourceReader() { var source = Substitute.For(); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); reader.Dispose(); source.Received(1).Dispose(); } [Fact] public void Close_ClosesSourceReader() { var source = Substitute.For(); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); reader.Close(); source.Received(1).Close(); } [Fact] public void NextResult_DelegatesToSourceReader() { var source = Substitute.For(); source.NextResult().Returns(true); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.True(reader.NextResult()); } [Fact] public void Depth_DelegatesToSourceReader() { var source = Substitute.For(); source.Depth.Returns(2); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.Equal(2, reader.Depth); } [Fact] public void IsClosed_DelegatesToSourceReader() { var source = Substitute.For(); source.IsClosed.Returns(true); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.True(reader.IsClosed); } [Fact] public void RecordsAffected_DelegatesToSourceReader() { var source = Substitute.For(); source.RecordsAffected.Returns(42); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); Assert.Equal(42, reader.RecordsAffected); } [Fact] public void Transform_ThrowsOnNullSource() { var transformer = new PassThroughTransformer(); Assert.Throws(() => transformer.Transform(null!)); } [Fact] public void TransformerName_ReturnsExpectedName() { var transformer = new PassThroughTransformer(); Assert.Equal("PassThrough", transformer.TransformerName); } [Fact] public void GetBytes_ComputedColumn_ThrowsNotSupportedException() { // Arrange - transformer that returns -1 for ordinal 0 (computed) var source = Substitute.For(); source.FieldCount.Returns(2); source.GetName(0).Returns("Computed"); source.GetName(1).Returns("B"); var transformer = new ComputedColumnTransformer(); var reader = transformer.Transform(source); // Act & Assert Assert.Throws(() => reader.GetBytes(0, 0, null, 0, 0)); } [Fact] public void GetChars_ComputedColumn_ThrowsNotSupportedException() { // Arrange - transformer that returns -1 for ordinal 0 (computed) var source = Substitute.For(); source.FieldCount.Returns(2); source.GetName(0).Returns("Computed"); source.GetName(1).Returns("B"); var transformer = new ComputedColumnTransformer(); var reader = transformer.Transform(source); // Act & Assert Assert.Throws(() => reader.GetChars(0, 0, null, 0, 0)); } [Fact] public void GetData_ComputedColumn_ThrowsNotSupportedException() { // Arrange - transformer that returns -1 for ordinal 0 (computed) var source = Substitute.For(); source.FieldCount.Returns(2); source.GetName(0).Returns("Computed"); source.GetName(1).Returns("B"); var transformer = new ComputedColumnTransformer(); var reader = transformer.Transform(source); // Act & Assert Assert.Throws(() => reader.GetData(0)); } [Fact] public void GetDataTypeName_ComputedColumn_ThrowsNotSupportedException() { // Arrange - transformer that returns -1 for ordinal 0 (computed) var source = Substitute.For(); source.FieldCount.Returns(2); source.GetName(0).Returns("Computed"); source.GetName(1).Returns("B"); var transformer = new ComputedColumnTransformer(); var reader = transformer.Transform(source); // Act & Assert Assert.Throws(() => reader.GetDataTypeName(0)); } [Fact] public void GetBytes_NonComputedColumn_DelegatesToSource() { // Arrange var source = Substitute.For(); source.FieldCount.Returns(2); source.GetName(0).Returns("A"); source.GetName(1).Returns("B"); var expectedBytes = new byte[] { 1, 2, 3 }; source.GetBytes(1, 0, Arg.Any(), 0, 3).Returns(3L); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); // Act var buffer = new byte[3]; var result = reader.GetBytes(1, 0, buffer, 0, 3); // Assert Assert.Equal(3L, result); source.Received(1).GetBytes(1, 0, buffer, 0, 3); } [Fact] public void GetChars_NonComputedColumn_DelegatesToSource() { // Arrange var source = Substitute.For(); source.FieldCount.Returns(2); source.GetName(0).Returns("A"); source.GetName(1).Returns("B"); source.GetChars(1, 0, Arg.Any(), 0, 3).Returns(3L); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); // Act var buffer = new char[3]; var result = reader.GetChars(1, 0, buffer, 0, 3); // Assert Assert.Equal(3L, result); source.Received(1).GetChars(1, 0, buffer, 0, 3); } [Fact] public void GetData_NonComputedColumn_DelegatesToSource() { // Arrange var source = Substitute.For(); source.FieldCount.Returns(2); source.GetName(0).Returns("A"); source.GetName(1).Returns("B"); var nestedReader = Substitute.For(); source.GetData(1).Returns(nestedReader); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); // Act var result = reader.GetData(1); // Assert Assert.Same(nestedReader, result); source.Received(1).GetData(1); } [Fact] public void GetDataTypeName_NonComputedColumn_DelegatesToSource() { // Arrange var source = Substitute.For(); source.FieldCount.Returns(2); source.GetName(0).Returns("A"); source.GetName(1).Returns("B"); source.GetDataTypeName(1).Returns("nvarchar"); var transformer = new PassThroughTransformer(); var reader = transformer.Transform(source); // Act var result = reader.GetDataTypeName(1); // Assert Assert.Equal("nvarchar", result); source.Received(1).GetDataTypeName(1); } private class PassThroughTransformer : DataTransformerBase { public override string TransformerName => "PassThrough"; } private class ComputedColumnTransformer : DataTransformerBase { public override string TransformerName => "Computed"; public override int MapOrdinal(int ordinal, IDataReader source) => ordinal == 0 ? -1 : ordinal; } }