using Strata.SqlTools.SqlBreakdown.Classes; using Strata.SqlTools.SqlBreakdown.Expressions; using Strata.SqlTools.SqlBreakdown.Expressions.Conditional; using Strata.SqlTools.SqlBreakdown.Expressions.Conditional.Comparisons; using Strata.SqlTools.SqlBreakdown.Expressions.Conditional.Logical; namespace Strata.SqlTools.SqlBreakdown.Tests.ExpressionTests; [TestFixture] public class BooleanExpressionTests : ExpressionTestsBase { [Test] public void BooleanExpression_AndOperator_ChainsCorrectly() { // Arrange var greaterThan250Exp = new GreaterThanExpression(_costColumnExp, 250); BooleanExpression original = BooleanExpression.False; // Act original &= greaterThan250Exp; var firstResult = original; original &= greaterThan250Exp; var secondResult = original; // Assert Assert.That(firstResult, Is.Not.SameAs(BooleanExpression.False)); Assert.That(firstResult, Is.AssignableTo()); Assert.That(secondResult, Is.Not.SameAs(BooleanExpression.False)); Assert.That(secondResult, Is.TypeOf()); } [Test] public void BooleanExpression_ComplexWithOperators_CreatesExpression() { // Arrange var paramFoobar = new ParameterExpression("FOOBAR"); // Act #pragma warning disable S2178 // Short-circuit logic should be used in boolean contexts var andComp = _revenueColumnExp > 100 & _costColumnExp >= 250 | _nameColumnExp == paramFoobar; #pragma warning restore S2178 // Assert Assert.That(andComp, Is.Not.Null); Assert.That(andComp, Is.AssignableTo()); } private static IEnumerable BooleanExpressionTestCases() { var testCases = new[] { new ExpressionTestCase { Name = "GreaterThan_{m}", Arrange = new Dictionary { ["revenue"] = new RegisteredTableColumnExpression(2, "NET_REVENUE", new RegisteredTableSource(101, "CLIENT_DSS", "DEPT", "PES")) }, Act = (columns, visitor) => { var revenue = columns["revenue"]; var greaterThan100Exp = new GreaterThanExpression(revenue, 100); return greaterThan100Exp; }, Assertions = result => { var expression = (BooleanExpression)result; Assert.That(expression, Is.Not.Null); Assert.That(expression, Is.TypeOf()); return true; } }, new ExpressionTestCase { Name = "And_{m}", Arrange = new Dictionary { ["revenue"] = new RegisteredTableColumnExpression(2, "NET_REVENUE", new RegisteredTableSource(101, "CLIENT_DSS", "DEPT", "PES")), ["cost"] = new RegisteredTableColumnExpression(3, "COST", new RegisteredTableSource(101, "CLIENT_DSS", "DEPT", "PES")) }, Act = (columns, visitor) => { var revenue = columns["revenue"]; var cost = columns["cost"]; var greaterThan100Exp = new GreaterThanExpression(revenue, 100); var greaterThan250Exp = new GreaterThanExpression(cost, 250); var andExp1 = new AndExpression(greaterThan100Exp, greaterThan250Exp); return andExp1; }, Assertions = result => { var expression = (BooleanExpression)result; Assert.That(expression, Is.Not.Null); Assert.That(expression, Is.TypeOf()); return true; } }, new ExpressionTestCase { Name = "Or_{m}", Arrange = new Dictionary { ["revenue"] = new RegisteredTableColumnExpression(2, "NET_REVENUE", new RegisteredTableSource(101, "CLIENT_DSS", "DEPT", "PES")), ["cost"] = new RegisteredTableColumnExpression(3, "COST", new RegisteredTableSource(101, "CLIENT_DSS", "DEPT", "PES")) }, Act = (columns, visitor) => { var revenue = columns["revenue"]; var cost = columns["cost"]; #pragma warning disable S2178 // Short-circuit logic should be used in boolean contexts var orComp = revenue > 100 | cost >= 250; #pragma warning restore S2178 return orComp; }, Assertions = result => { var expression = (BooleanExpression)result; Assert.That(expression, Is.Not.Null); Assert.That(expression, Is.AssignableTo()); return true; } } }; foreach (var testCase in testCases) { yield return new TestCaseData(testCase).SetName(testCase.Name); } } [TestCaseSource(nameof(BooleanExpressionTestCases))] public void BooleanExpression_GeneratesCorrectExpression(ExpressionTestCase testCase) => ExecuteExpressionTest(testCase); }