204 lines
9.4 KiB
C#
204 lines
9.4 KiB
C#
using Strata.SqlTools.SqlBreakdown.Expressions;
|
|
using Strata.SqlTools.SqlBreakdown.Expressions.Literals;
|
|
|
|
namespace Strata.SqlTools.SqlBreakdown.Tests.ExpressionTests;
|
|
|
|
[TestFixture]
|
|
public class GenericColumnExpressionTests : ExpressionTestsBase
|
|
{
|
|
private static IEnumerable<TestCaseData> GenericColumnExpressionTestCases()
|
|
{
|
|
var testCases = new[]
|
|
{
|
|
new ExpressionTestCase
|
|
{
|
|
Name = "WithArithmeticOperatorsAndLiterals_{m}",
|
|
Arrange = new Dictionary<string, Expression>
|
|
{
|
|
["price"] = new GenericColumnExpression("Price", "Products"),
|
|
["quantity"] = new GenericColumnExpression("Quantity", "Products")
|
|
},
|
|
Act = (columns, visitor) =>
|
|
{
|
|
var price = columns["price"];
|
|
var quantity = columns["quantity"];
|
|
var priceWithTax = price * new NumberLiteralExpression(1.1m);
|
|
var priceWithFee = price + new NumberLiteralExpression(10);
|
|
var revenue = quantity * price;
|
|
return new Dictionary<string, string>
|
|
{
|
|
["priceWithTax"] = priceWithTax.Accept(visitor),
|
|
["priceWithFee"] = priceWithFee.Accept(visitor),
|
|
["revenue"] = revenue.Accept(visitor)
|
|
};
|
|
},
|
|
Assertions = result =>
|
|
{
|
|
var results = (Dictionary<string, string>)result;
|
|
Assert.That(results["priceWithTax"], Does.Contain("Price"));
|
|
Assert.That(results["priceWithTax"], Does.Contain("1.1"));
|
|
Assert.That(results["priceWithFee"], Does.Contain("Price"));
|
|
Assert.That(results["priceWithFee"], Does.Contain("10"));
|
|
Assert.That(results["revenue"], Does.Contain("Quantity"));
|
|
Assert.That(results["revenue"], Does.Contain("Price"));
|
|
return true;
|
|
}
|
|
},
|
|
new ExpressionTestCase
|
|
{
|
|
Name = "WithComparisonOperators_{m}",
|
|
Arrange = new Dictionary<string, Expression>
|
|
{
|
|
["price"] = new GenericColumnExpression("Price", "Products"),
|
|
["category"] = new GenericColumnExpression("Category", "Products")
|
|
},
|
|
Act = (columns, visitor) =>
|
|
{
|
|
var price = columns["price"];
|
|
var category = columns["category"];
|
|
var priceCondition = price > 100;
|
|
var categoryCondition = category == "Electronics";
|
|
return new Dictionary<string, string>
|
|
{
|
|
["priceCondition"] = priceCondition.Accept(visitor),
|
|
["categoryCondition"] = categoryCondition.Accept(visitor)
|
|
};
|
|
},
|
|
Assertions = result =>
|
|
{
|
|
var results = (Dictionary<string, string>)result;
|
|
Assert.That(results["priceCondition"], Does.Contain("Price"));
|
|
Assert.That(results["priceCondition"], Does.Contain("100"));
|
|
Assert.That(results["categoryCondition"], Does.Contain("Category"));
|
|
Assert.That(results["categoryCondition"], Does.Contain("Electronics"));
|
|
return true;
|
|
}
|
|
},
|
|
new ExpressionTestCase
|
|
{
|
|
Name = "InQueryBreakdown_{m}",
|
|
Arrange = new Dictionary<string, Expression>
|
|
{
|
|
["productId"] = new GenericColumnExpression("ProductID", "Products"),
|
|
["price"] = new GenericColumnExpression("Price", "Products"),
|
|
["category"] = new GenericColumnExpression("Category", "Products")
|
|
},
|
|
Act = (columns, visitor) =>
|
|
{
|
|
var query = new Breakdowns.SqlServer.QueryBreakdown();
|
|
query.FromClause.Clause = "Products";
|
|
var productId = columns["productId"];
|
|
var price = columns["price"];
|
|
var category = columns["category"];
|
|
query.AddSelectExpression(productId, "ID");
|
|
query.AddSelectExpression(price * new NumberLiteralExpression(1.1m), "PriceWithTax");
|
|
query.AddSelectExpression(price + new NumberLiteralExpression(10), "PriceWithFee");
|
|
query.AddWhereExpression(price > 100);
|
|
query.AddWhereExpression(category == "Electronics", null, "AND");
|
|
return query.GetSql();
|
|
},
|
|
Assertions = result =>
|
|
{
|
|
var sql = (string)result;
|
|
Assert.That(sql, Does.Contain("ProductID"));
|
|
Assert.That(sql, Does.Contain("Price"));
|
|
Assert.That(sql, Does.Contain("Category"));
|
|
Assert.That(sql, Does.Contain("Products"));
|
|
return true;
|
|
}
|
|
},
|
|
new ExpressionTestCase
|
|
{
|
|
Name = "ComplexArithmetic_{m}",
|
|
Arrange = new Dictionary<string, Expression>
|
|
{
|
|
["quantity"] = new GenericColumnExpression("Quantity", "OrderDetails"),
|
|
["unitPrice"] = new GenericColumnExpression("UnitPrice", "OrderDetails"),
|
|
["discount"] = new GenericColumnExpression("Discount", "OrderDetails")
|
|
},
|
|
Act = (columns, visitor) =>
|
|
{
|
|
var quantity = columns["quantity"];
|
|
var unitPrice = columns["unitPrice"];
|
|
var discount = columns["discount"];
|
|
var totalRevenue = (quantity * unitPrice) * (new NumberLiteralExpression(1) - discount);
|
|
return totalRevenue.Accept(visitor);
|
|
},
|
|
Assertions = result =>
|
|
{
|
|
var sql = (string)result;
|
|
Assert.That(sql, Does.Contain("Quantity"));
|
|
Assert.That(sql, Does.Contain("UnitPrice"));
|
|
Assert.That(sql, Does.Contain("Discount"));
|
|
return true;
|
|
}
|
|
},
|
|
new ExpressionTestCase
|
|
{
|
|
Name = "WithSchema_{m}",
|
|
Arrange = new Dictionary<string, Expression>
|
|
{
|
|
["customerId"] = new GenericColumnExpression("CustomerID", "dbo", "Customers"),
|
|
["orderDate"] = new GenericColumnExpression("OrderDate", "dbo", "Orders")
|
|
},
|
|
Act = (columns, visitor) =>
|
|
{
|
|
return new Dictionary<string, string>
|
|
{
|
|
["customerResult"] = columns["customerId"].Accept(visitor),
|
|
["orderResult"] = columns["orderDate"].Accept(visitor)
|
|
};
|
|
},
|
|
Assertions = result =>
|
|
{
|
|
var results = (Dictionary<string, string>)result;
|
|
Assert.That(results["customerResult"], Does.Contain("CustomerID"));
|
|
Assert.That(results["orderResult"], Does.Contain("OrderDate"));
|
|
return true;
|
|
}
|
|
},
|
|
new ExpressionTestCase
|
|
{
|
|
Name = "MultipleComparisonOperators_{m}",
|
|
Arrange = new Dictionary<string, Expression>
|
|
{
|
|
["unitPrice"] = new GenericColumnExpression("UnitPrice", "Products"),
|
|
["minPrice"] = new GenericColumnExpression("MinPrice", "PriceRanges"),
|
|
["maxPrice"] = new GenericColumnExpression("MaxPrice", "PriceRanges")
|
|
},
|
|
Act = (columns, visitor) =>
|
|
{
|
|
var unitPrice = columns["unitPrice"];
|
|
var minPrice = columns["minPrice"];
|
|
var maxPrice = columns["maxPrice"];
|
|
var lowerBound = unitPrice >= minPrice;
|
|
var upperBound = unitPrice <= maxPrice;
|
|
return new Dictionary<string, string>
|
|
{
|
|
["lowerBound"] = lowerBound.Accept(visitor),
|
|
["upperBound"] = upperBound.Accept(visitor)
|
|
};
|
|
},
|
|
Assertions = result =>
|
|
{
|
|
var results = (Dictionary<string, string>)result;
|
|
Assert.That(results["lowerBound"], Does.Contain("UnitPrice"));
|
|
Assert.That(results["lowerBound"], Does.Contain("MinPrice"));
|
|
Assert.That(results["upperBound"], Does.Contain("UnitPrice"));
|
|
Assert.That(results["upperBound"], Does.Contain("MaxPrice"));
|
|
return true;
|
|
}
|
|
}
|
|
};
|
|
|
|
foreach (var testCase in testCases)
|
|
{
|
|
yield return new TestCaseData(testCase).SetName(testCase.Name);
|
|
}
|
|
}
|
|
|
|
[TestCaseSource(nameof(GenericColumnExpressionTestCases))]
|
|
public void GenericColumnExpression_GeneratesCorrectSql(ExpressionTestCase testCase)
|
|
=> ExecuteExpressionTest(testCase);
|
|
}
|