Files
jdescopingtool/NEW/tests/JdeScoping.DataSync.Tests/Etl/Transformers/RegexTransformerTests.cs
T
Joseph Doherty 8734c57c9b test(datasync): add edge case tests for RegexTransformer
Tests cover:
- Capture group substitution in replacement
- Case-insensitive matching
- Null/DBNull passthrough
- Non-target columns unchanged
- Invalid regex pattern handling
- Column not found handling
2026-01-22 07:16:25 -05:00

266 lines
7.7 KiB
C#

using System.Data;
using System.Text.RegularExpressions;
using JdeScoping.DataSync.Etl.Transformers;
using NSubstitute;
namespace JdeScoping.DataSync.Tests.Etl.Transformers;
public class RegexTransformerTests
{
[Fact]
public void FindReplace_RemovesPrefix()
{
// Arrange
var source = CreateMockReader(
columns: new[] { "BatchID", "Name" },
values: new object[] { "IIS_12345", "Test" });
var transformer = new RegexTransformer(
columnName: "BatchID",
pattern: "^IIS_",
replacement: "");
// Act
var reader = transformer.Transform(source);
source.Read().Returns(true);
reader.Read();
// Assert
Assert.Equal("12345", reader.GetValue(0));
Assert.Equal("Test", reader.GetValue(1)); // Other column unchanged
}
[Fact]
public void MatchExtract_ExtractsFirstCaptureGroup()
{
// Arrange
var source = CreateMockReader(
columns: new[] { "Code" },
values: new object[] { "ID_12345" });
var transformer = new RegexTransformer(
columnName: "Code",
pattern: @"ID_(\d+)",
replacement: null); // null = Match & Extract mode
// Act
var reader = transformer.Transform(source);
source.Read().Returns(true);
reader.Read();
// Assert
Assert.Equal("12345", reader.GetValue(0));
}
[Fact]
public void MatchExtract_NoMatch_KeepOriginal()
{
// Arrange
var source = CreateMockReader(
columns: new[] { "Code" },
values: new object[] { "UNKNOWN" });
var transformer = new RegexTransformer(
columnName: "Code",
pattern: @"ID_(\d+)",
replacement: null,
nonMatchBehavior: NonMatchBehavior.KeepOriginal);
// Act
var reader = transformer.Transform(source);
source.Read().Returns(true);
reader.Read();
// Assert
Assert.Equal("UNKNOWN", reader.GetValue(0));
}
[Fact]
public void MatchExtract_NoMatch_ReturnNull()
{
// Arrange
var source = CreateMockReader(
columns: new[] { "Code" },
values: new object[] { "UNKNOWN" });
var transformer = new RegexTransformer(
columnName: "Code",
pattern: @"ID_(\d+)",
replacement: null,
nonMatchBehavior: NonMatchBehavior.ReturnNull);
// Act
var reader = transformer.Transform(source);
source.Read().Returns(true);
reader.Read();
// Assert
Assert.Equal(DBNull.Value, reader.GetValue(0));
}
[Fact]
public void MatchExtract_NoMatch_ReturnEmpty()
{
// Arrange
var source = CreateMockReader(
columns: new[] { "Code" },
values: new object[] { "UNKNOWN" });
var transformer = new RegexTransformer(
columnName: "Code",
pattern: @"ID_(\d+)",
replacement: null,
nonMatchBehavior: NonMatchBehavior.ReturnEmpty);
// Act
var reader = transformer.Transform(source);
source.Read().Returns(true);
reader.Read();
// Assert
Assert.Equal(string.Empty, reader.GetValue(0));
}
[Fact]
public void FindReplace_UseCaptureGroups()
{
// Arrange - swap two numbers
var source = CreateMockReader(
columns: new[] { "Value" },
values: new object[] { "123-456" });
var transformer = new RegexTransformer(
columnName: "Value",
pattern: @"(\d+)-(\d+)",
replacement: "$2-$1");
// Act
var reader = transformer.Transform(source);
source.Read().Returns(true);
reader.Read();
// Assert
Assert.Equal("456-123", reader.GetValue(0));
}
[Fact]
public void IgnoreCase_MatchesDifferentCase()
{
// Arrange
var source = CreateMockReader(
columns: new[] { "BatchID" },
values: new object[] { "IIS_12345" });
var transformer = new RegexTransformer(
columnName: "BatchID",
pattern: "^iis_", // lowercase pattern
replacement: "",
ignoreCase: true);
// Act
var reader = transformer.Transform(source);
source.Read().Returns(true);
reader.Read();
// Assert
Assert.Equal("12345", reader.GetValue(0));
}
[Fact]
public void NullValue_PassesThrough()
{
// Arrange
var source = CreateMockReader(
columns: new[] { "BatchID" },
values: new object[] { DBNull.Value });
var transformer = new RegexTransformer(
columnName: "BatchID",
pattern: "^IIS_",
replacement: "");
// Act
var reader = transformer.Transform(source);
source.Read().Returns(true);
reader.Read();
// Assert
Assert.Equal(DBNull.Value, reader.GetValue(0));
}
[Fact]
public void NonTargetColumn_Unchanged()
{
// Arrange
var source = CreateMockReader(
columns: new[] { "BatchID", "OtherColumn" },
values: new object[] { "IIS_12345", "IIS_Should_Not_Change" });
var transformer = new RegexTransformer(
columnName: "BatchID",
pattern: "^IIS_",
replacement: "");
// Act
var reader = transformer.Transform(source);
source.Read().Returns(true);
reader.Read();
// Assert
Assert.Equal("12345", reader.GetValue(0));
Assert.Equal("IIS_Should_Not_Change", reader.GetValue(1));
}
[Fact]
public void InvalidRegex_ThrowsOnTransform()
{
// Arrange
var source = CreateMockReader(
columns: new[] { "Value" },
values: new object[] { "test" });
var transformer = new RegexTransformer(
columnName: "Value",
pattern: "[invalid(regex",
replacement: "");
// Act & Assert
var ex = Assert.Throws<RegexParseException>(() => transformer.Transform(source));
Assert.Contains("Invalid", ex.Message, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void ColumnNotFound_ThrowsOnTransform()
{
// Arrange
var source = CreateMockReader(
columns: new[] { "Value" },
values: new object[] { "test" });
source.GetOrdinal("NonExistent").Returns(_ => throw new IndexOutOfRangeException("Column not found"));
var transformer = new RegexTransformer(
columnName: "NonExistent",
pattern: "test",
replacement: "");
// Act & Assert
Assert.Throws<IndexOutOfRangeException>(() => transformer.Transform(source));
}
private static IDataReader CreateMockReader(string[] columns, object[] values)
{
var reader = Substitute.For<IDataReader>();
reader.FieldCount.Returns(columns.Length);
for (int i = 0; i < columns.Length; i++)
{
var index = i;
reader.GetName(index).Returns(columns[index]);
reader.GetOrdinal(columns[index]).Returns(index);
reader.GetFieldType(index).Returns(values[index]?.GetType() ?? typeof(object));
reader.GetValue(index).Returns(values[index]);
reader.IsDBNull(index).Returns(values[index] == null || values[index] == DBNull.Value);
}
return reader;
}
}