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> 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> 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> 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> 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(() => ExpressionParser.GetColumnNames(null!)); } #endregion #region BuildUpdateWhenSql Tests [Fact] public void BuildUpdateWhenSql_NullExpression_ReturnsNull() { // Act var result = ExpressionParser.BuildUpdateWhenSql(null); // Assert Assert.Null(result); } [Fact] public void BuildUpdateWhenSql_GreaterThan_ReturnsSqlCondition() { // Arrange Expression> 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> 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> 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> 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> 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> 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> expr = (src, tgt) => src.Id > tgt.Id; // Act var result = ExpressionParser.BuildUpdateWhenSql(expr, "s", "t"); // Assert Assert.Equal("s.[Id] > t.[Id]", result); } #endregion }