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, Is.Not.Empty); } [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, Is.Not.Empty); }); } [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, Is.Not.Empty); }); } [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 }