Files
sql-utilities/tests/Strata.SqlTools.PostgreSql.Tests/PostgreSql/QueryBreakdownCollectionTests.cs
T
Thom LambandClaude Opus 4.7 67512d23e1 chore(sonar): wrap independent assertions in Assert.Multiple (NUnit2045)
Driven by `dotnet format analyzers --diagnostics NUnit2045`. The fixer
groups consecutive independent `Assert.That(...)` calls into
`Assert.Multiple(() => { ... })`, so a failing assertion no longer
short-circuits the block — every failure inside the group is reported,
which gives much better diagnostics on multi-property tests.

Audit confirmed no Assert.Throws / Assert.Fail / Assert.Catch / Assert.Pass
/ Assert.DoesNotThrow got pulled inside a Multiple block (those need to
short-circuit). All 1180 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 11:59:47 -05:00

353 lines
9.0 KiB
C#

using Strata.SqlTools.Breakdowns.PostgreSql;
namespace Strata.SqlTools.SqlBreakdown.Tests.PostgreSql;
[TestFixture]
public class QueryBreakdownCollectionTests
{
private QueryBreakdownCollection _collection = null!;
[SetUp]
public void Setup()
{
_collection = new QueryBreakdownCollection();
}
#region Constructor Tests
[Test]
public void Constructor_Default_CreatesEmptyCollection()
{
// Arrange & Act
var collection = new QueryBreakdownCollection();
// Assert
Assert.That(collection, Is.Empty);
}
#endregion
#region Add Tests
[Test]
public void Add_SingleQueryBreakdown_AddsSuccessfully()
{
// Arrange
var query = new QueryBreakdown("id, name", "users");
// Act
_collection.Add(query);
// Assert
Assert.That(_collection.Count, Is.GreaterThan(0));
}
[Test]
public void Add_MultipleQueryBreakdowns_AddsMultiple()
{
// Arrange
var query1 = new QueryBreakdown("id, name", "users");
var query2 = new QueryBreakdown("order_id, amount", "orders");
var query3 = new QueryBreakdown("product_id, price", "products");
// Act
_collection.Add(query1);
_collection.Add(query2);
_collection.Add(query3);
// Assert
Assert.That(_collection, Has.Count.EqualTo(3));
}
#endregion
#region GetPostgreSqlBatch Tests
[Test]
public void GetPostgreSqlBatch_EmptyCollection_ReturnsEmptyString()
{
// Arrange - empty collection created in SetUp
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Is.Not.Null);
}
[Test]
public void GetPostgreSqlBatch_SingleQuery_GeneratesValidSql()
{
// Arrange
var query = new QueryBreakdown("id, name", "users");
_collection.Add(query);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Is.Not.Null);
Assert.That(sql, Does.Contain("SELECT").Or.Contain("select"));
}
[Test]
public void GetPostgreSqlBatch_MultipleQueries_SeparatesWithSemicolon()
{
// Arrange
var query1 = new QueryBreakdown("id", "users");
var query2 = new QueryBreakdown("id", "orders");
_collection.Add(query1);
_collection.Add(query2);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Is.Not.Null);
// PostgreSQL batch should contain semicolons separating statements
Assert.That(sql, Does.Contain(";"));
}
[Test]
public void GetPostgreSqlBatch_WithWhereClause_IncludesConditions()
{
// Arrange
var query = new QueryBreakdown("id, name", "users");
query.WhereClause.Clause = "active = true";
_collection.Add(query);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Does.Contain("active"));
}
[Test]
public void GetPostgreSqlBatch_WithOrderBy_IncludesOrderBy()
{
// Arrange
var query = new QueryBreakdown("id, name", "users");
query.OrderByClause.Clause = "name ASC";
_collection.Add(query);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Does.Contain("ORDER BY").Or.Contain("order by"));
}
[Test]
public void GetPostgreSqlBatch_WithGroupBy_IncludesGroupBy()
{
// Arrange
var query = new QueryBreakdown("category, COUNT(*) as count", "products");
query.GroupByClause.Clause = "category";
_collection.Add(query);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Does.Contain("GROUP BY").Or.Contain("group by"));
}
[Test]
public void GetPostgreSqlBatch_WithHaving_IncludesHaving()
{
// Arrange
var query = new QueryBreakdown("category, COUNT(*) as count", "products");
query.GroupByClause.Clause = "category";
query.HavingClause.Clause = "COUNT(*) > 5";
_collection.Add(query);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Does.Contain("HAVING").Or.Contain("having"));
}
#endregion
#region ParseBatch Tests
[Test]
public void ParseBatch_WithValidSql_Succeeds()
{
// Arrange
var batchSql = "SELECT id, name FROM users WHERE active = true; SELECT order_id FROM orders;";
// Act
var result = _collection.ParseBatch(batchSql);
Assert.Multiple(() =>
{
// Assert
Assert.That(result, Is.True);
Assert.That(_collection.Count, Is.GreaterThan(0));
});
}
[Test]
public void ParseBatch_WithMultipleStatements_ParsesAllQueries()
{
// Arrange
var batchSql = @"
SELECT id, name FROM users WHERE active = true;
SELECT order_id, amount FROM orders WHERE user_id = $1;
";
// Act
var result = _collection.ParseBatch(batchSql);
Assert.Multiple(() =>
{
// Assert
Assert.That(result, Is.True);
Assert.That(_collection.Count, Is.GreaterThan(0));
});
}
[Test]
public void ParseBatch_WithSingleStatement_ParsesSingleQuery()
{
// Arrange
var batchSql = "SELECT id, name FROM users";
// Act
var result = _collection.ParseBatch(batchSql);
// Assert
Assert.That(result, Is.True);
}
#endregion
#region Complex Query Tests
[Test]
public void GetPostgreSqlBatch_ComplexQueryWithMultipleClauses_GeneratesValidBatch()
{
// Arrange
var query1 = new QueryBreakdown("id, name", "users");
query1.WhereClause.Clause = "id = $1";
var query2 = new QueryBreakdown("order_id, amount", "orders");
query2.WhereClause.Clause = "user_id = $1";
query2.OrderByClause.Clause = "created_at DESC";
_collection.Add(query1);
_collection.Add(query2);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Does.Contain(";"));
Assert.That(sql, Does.Contain("SELECT"));
Assert.That(sql, Does.Contain("WHERE"));
}
[Test]
public void GetPostgreSqlBatch_WithParameters_IncludesParameterValues()
{
// Arrange
var query = new QueryBreakdown("id, name", "users");
query.AddParameter("userId", 123);
_collection.Add(query);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Does.Contain("SELECT"));
Assert.That(sql, Is.Not.Null);
}
[Test]
public void GetPostgreSqlBatch_MultipleQueriesWithDifferentClauses_GeneratesValidBatch()
{
// Arrange
var query1 = new QueryBreakdown("id, name", "users");
query1.WhereClause.Clause = "active = true";
var query2 = new QueryBreakdown("order_id, total", "orders");
query2.WhereClause.Clause = "status = 'pending'";
query2.OrderByClause.Clause = "created_at DESC";
var query3 = new QueryBreakdown("product_id, price", "products");
query3.WhereClause.Clause = "in_stock = true";
query3.OrderByClause.Clause = "price ASC";
_collection.Add(query1);
_collection.Add(query2);
_collection.Add(query3);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Does.Contain("SELECT"));
Assert.Multiple(() =>
{
Assert.That(sql, Does.Contain(";"));
Assert.That(_collection, Has.Count.EqualTo(3));
});
}
#endregion
#region Edge Cases
[Test]
public void GetPostgreSqlBatch_MultipleQueriesWithJoins_GeneratesValidBatch()
{
// Arrange
var query = new QueryBreakdown("u.id, u.name, o.order_id", "users u LEFT JOIN orders o ON u.id = o.user_id");
query.WhereClause.Clause = "u.active = true";
_collection.Add(query);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Does.Contain("JOIN"));
}
[Test]
public void GetPostgreSqlBatch_WithDoubleQuotedIdentifiers_PreservesQuotes()
{
// Arrange
var query = new QueryBreakdown("\"Id\", \"Name\"", "\"Users\"");
_collection.Add(query);
// Act
var sql = _collection.GetPostgreSqlBatch();
// Assert
Assert.That(sql, Does.Contain("\""));
}
[Test]
public void ParseBatch_WithComments_IgnoresComments()
{
// Arrange
var batchSql = @"
-- This is a user query
SELECT id, name FROM users;
-- This is an orders query
SELECT order_id FROM orders;
";
// Act
var result = _collection.ParseBatch(batchSql);
// Assert
Assert.That(result, Is.True);
}
#endregion
}