Files
jdescopingtool/NEW/tests/JdeScoping.DataSync.Tests/Services/ExpressionParserTests.cs
T
Joseph Doherty 26ff8d9b4f Initial commit: JDE Scoping Tool migration project
Set up repository with legacy .NET Framework 4.8 source (OLD/),
new .NET 10 Blazor solution (NEW/), OpenSpec specifications,
documentation, and project configuration.
2026-01-02 07:43:29 -05:00

195 lines
5.5 KiB
C#

using System.Linq.Expressions;
using JdeScoping.DataSync.Services;
namespace JdeScoping.DataSync.Tests.Services;
public class ExpressionParserTests
{
private class TestEntity
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public DateTime? LastUpdateDt { get; set; }
public decimal Amount { get; set; }
}
#region GetColumnNames Tests
[Fact]
public void GetColumnNames_SingleProperty_ReturnsSingleColumn()
{
// Arrange
Expression<Func<TestEntity, object>> expr = x => x.Id;
// Act
var columns = ExpressionParser.GetColumnNames(expr);
// Assert
Assert.Single(columns);
Assert.Equal("Id", columns[0]);
}
[Fact]
public void GetColumnNames_SingleStringProperty_ReturnsSingleColumn()
{
// Arrange
Expression<Func<TestEntity, object>> expr = x => x.Name;
// Act
var columns = ExpressionParser.GetColumnNames(expr);
// Assert
Assert.Single(columns);
Assert.Equal("Name", columns[0]);
}
[Fact]
public void GetColumnNames_AnonymousType_ReturnsAllColumns()
{
// Arrange
Expression<Func<TestEntity, object>> expr = x => new { x.Id, x.Name };
// Act
var columns = ExpressionParser.GetColumnNames(expr);
// Assert
Assert.Equal(2, columns.Count);
Assert.Equal("Id", columns[0]);
Assert.Equal("Name", columns[1]);
}
[Fact]
public void GetColumnNames_AnonymousTypeWithMultipleProperties_ReturnsAllColumns()
{
// Arrange
Expression<Func<TestEntity, object>> expr = x => new { x.Id, x.Name, x.Amount, x.LastUpdateDt };
// Act
var columns = ExpressionParser.GetColumnNames(expr);
// Assert
Assert.Equal(4, columns.Count);
Assert.Equal("Id", columns[0]);
Assert.Equal("Name", columns[1]);
Assert.Equal("Amount", columns[2]);
Assert.Equal("LastUpdateDt", columns[3]);
}
[Fact]
public void GetColumnNames_NullExpression_ThrowsArgumentNullException()
{
// Act & Assert
Assert.Throws<ArgumentNullException>(() =>
ExpressionParser.GetColumnNames<TestEntity>(null!));
}
#endregion
#region BuildUpdateWhenSql Tests
[Fact]
public void BuildUpdateWhenSql_NullExpression_ReturnsNull()
{
// Act
var result = ExpressionParser.BuildUpdateWhenSql<TestEntity>(null);
// Assert
Assert.Null(result);
}
[Fact]
public void BuildUpdateWhenSql_GreaterThan_ReturnsSqlCondition()
{
// Arrange
Expression<Func<TestEntity, TestEntity, bool>> expr = (src, tgt) => src.LastUpdateDt > tgt.LastUpdateDt;
// Act
var result = ExpressionParser.BuildUpdateWhenSql(expr);
// Assert
Assert.Equal("source.[LastUpdateDt] > target.[LastUpdateDt]", result);
}
[Fact]
public void BuildUpdateWhenSql_GreaterThanOrEqual_ReturnsSqlCondition()
{
// Arrange
Expression<Func<TestEntity, TestEntity, bool>> expr = (src, tgt) => src.Id >= tgt.Id;
// Act
var result = ExpressionParser.BuildUpdateWhenSql(expr);
// Assert
Assert.Equal("source.[Id] >= target.[Id]", result);
}
[Fact]
public void BuildUpdateWhenSql_Equal_ReturnsSqlCondition()
{
// Arrange
Expression<Func<TestEntity, TestEntity, bool>> expr = (src, tgt) => src.Name == tgt.Name;
// Act
var result = ExpressionParser.BuildUpdateWhenSql(expr);
// Assert
Assert.Equal("source.[Name] = target.[Name]", result);
}
[Fact]
public void BuildUpdateWhenSql_NotEqual_ReturnsSqlCondition()
{
// Arrange
Expression<Func<TestEntity, TestEntity, bool>> expr = (src, tgt) => src.Amount != tgt.Amount;
// Act
var result = ExpressionParser.BuildUpdateWhenSql(expr);
// Assert
Assert.Equal("source.[Amount] <> target.[Amount]", result);
}
[Fact]
public void BuildUpdateWhenSql_AndCondition_ReturnsSqlCondition()
{
// Arrange
Expression<Func<TestEntity, TestEntity, bool>> expr =
(src, tgt) => src.LastUpdateDt > tgt.LastUpdateDt && src.Id == tgt.Id;
// Act
var result = ExpressionParser.BuildUpdateWhenSql(expr);
// Assert
Assert.Equal("(source.[LastUpdateDt] > target.[LastUpdateDt] AND source.[Id] = target.[Id])", result);
}
[Fact]
public void BuildUpdateWhenSql_OrCondition_ReturnsSqlCondition()
{
// Arrange
Expression<Func<TestEntity, TestEntity, bool>> expr =
(src, tgt) => src.LastUpdateDt > tgt.LastUpdateDt || src.Amount > tgt.Amount;
// Act
var result = ExpressionParser.BuildUpdateWhenSql(expr);
// Assert
Assert.Equal("(source.[LastUpdateDt] > target.[LastUpdateDt] OR source.[Amount] > target.[Amount])", result);
}
[Fact]
public void BuildUpdateWhenSql_CustomAliases_UsesProvidedAliases()
{
// Arrange
Expression<Func<TestEntity, TestEntity, bool>> expr = (src, tgt) => src.Id > tgt.Id;
// Act
var result = ExpressionParser.BuildUpdateWhenSql(expr, "s", "t");
// Assert
Assert.Equal("s.[Id] > t.[Id]", result);
}
#endregion
}