using NUnit.Framework; using Strata.SqlTools.Breakdowns.SqlServer; using Strata.SqlTools.SqlBreakdown.Classes; namespace Strata.SqlTools.SqlBreakdown.Tests.SqlServer.Performance; [TestFixture] public class GetClausesCachingTests { [Test] public void GetClauses_CalledMultipleTimes_ReturnsSameInstance() { // Arrange var query = new QueryBreakdown("id, name", "users"); // Act var clauses1 = query.GetClauses(); var clauses2 = query.GetClauses(); // Assert Assert.That(clauses2, Is.SameAs(clauses1), "GetClauses should return the same cached instance when clauses haven't changed"); } [Test] public void GetClauses_AfterSelectClauseChange_ReturnsNewInstance() { // Arrange var query = new QueryBreakdown("id", "users"); var clauses1 = query.GetClauses(); // Act - Replace entire clause object to trigger property setter query.SelectClause = new SqlExpressionClause { Clause = "id, name, email" }; var clauses2 = query.GetClauses(); // Assert Assert.That(clauses2, Is.Not.SameAs(clauses1), "GetClauses should return a new instance after SelectClause changes"); Assert.That(clauses2.SelectClause?.Clause, Is.EqualTo("id, name, email")); } [Test] public void GetClauses_AfterFromClauseChange_ReturnsNewInstance() { // Arrange var query = new QueryBreakdown("id", "users"); var clauses1 = query.GetClauses(); // Act - Replace entire clause object to trigger property setter query.FromClause = new SqlClause { Clause = "customers" }; var clauses2 = query.GetClauses(); // Assert Assert.That(clauses2, Is.Not.SameAs(clauses1), "GetClauses should return a new instance after FromClause changes"); Assert.That(clauses2.FromClause?.Clause, Is.EqualTo("customers")); } [Test] public void GetClauses_AfterWhereClauseChange_ReturnsNewInstance() { // Arrange var query = new QueryBreakdown("id", "users", "active = 1"); var clauses1 = query.GetClauses(); // Act - Replace entire clause object to trigger property setter query.WhereClause = new SqlExpressionClause { Clause = "active = 1 AND deleted = 0" }; var clauses2 = query.GetClauses(); // Assert Assert.That(clauses2, Is.Not.SameAs(clauses1), "GetClauses should return a new instance after WhereClause changes"); Assert.That(clauses2.WhereClause?.Clause, Is.EqualTo("active = 1 AND deleted = 0")); } [Test] public void GetClauses_AfterGroupByClauseChange_ReturnsNewInstance() { // Arrange var query = new QueryBreakdown("COUNT(*) AS total", "users"); query.GroupByClause = new SqlExpressionClause { Clause = "status" }; var clauses1 = query.GetClauses(); // Act - Replace entire clause object to trigger property setter query.GroupByClause = new SqlExpressionClause { Clause = "status, type" }; var clauses2 = query.GetClauses(); // Assert Assert.That(clauses2, Is.Not.SameAs(clauses1), "GetClauses should return a new instance after GroupByClause changes"); Assert.That(clauses2.GroupByClause?.Clause, Is.EqualTo("status, type")); } [Test] public void GetClauses_AfterHavingClauseChange_ReturnsNewInstance() { // Arrange var query = new QueryBreakdown("COUNT(*) AS total", "users"); query.HavingClause = new SqlExpressionClause { Clause = "COUNT(*) > 10" }; var clauses1 = query.GetClauses(); // Act - Replace entire clause object to trigger property setter query.HavingClause = new SqlExpressionClause { Clause = "COUNT(*) > 100" }; var clauses2 = query.GetClauses(); // Assert Assert.That(clauses2, Is.Not.SameAs(clauses1), "GetClauses should return a new instance after HavingClause changes"); Assert.That(clauses2.HavingClause?.Clause, Is.EqualTo("COUNT(*) > 100")); } [Test] public void GetClauses_AfterOrderByClauseChange_ReturnsNewInstance() { // Arrange var query = new QueryBreakdown("id, name", "users"); query.OrderByClause = new SqlExpressionClause { Clause = "id ASC" }; var clauses1 = query.GetClauses(); // Act - Replace entire clause object to trigger property setter query.OrderByClause = new SqlExpressionClause { Clause = "name DESC" }; var clauses2 = query.GetClauses(); // Assert Assert.That(clauses2, Is.Not.SameAs(clauses1), "GetClauses should return a new instance after OrderByClause changes"); Assert.That(clauses2.OrderByClause?.Clause, Is.EqualTo("name DESC")); } [Test] public void GetClauses_AfterMultipleChanges_CacheInvalidatedEachTime() { // Arrange var query = new QueryBreakdown("id", "users"); var clauses1 = query.GetClauses(); // Act & Assert - Change 1 query.SelectClause = new SqlExpressionClause { Clause = "id, name" }; var clauses2 = query.GetClauses(); Assert.That(clauses2, Is.Not.SameAs(clauses1)); // Get again without changes - should return cached var clauses2b = query.GetClauses(); Assert.That(clauses2b, Is.SameAs(clauses2)); // Act & Assert - Change 2 query.WhereClause = new SqlExpressionClause { Clause = "active = 1" }; var clauses3 = query.GetClauses(); Assert.That(clauses3, Is.Not.SameAs(clauses2)); // Get again without changes - should return cached var clauses3b = query.GetClauses(); Assert.That(clauses3b, Is.SameAs(clauses3)); } [Test] public void GetClauses_ReplacingEntireClauseObject_ReturnsNewInstance() { // Arrange var query = new QueryBreakdown("id", "users"); var clauses1 = query.GetClauses(); // Act - Replace entire clause object query.SelectClause = new SqlExpressionClause { Clause = "id, name, email" }; var clauses2 = query.GetClauses(); // Assert Assert.That(clauses2, Is.Not.SameAs(clauses1), "GetClauses should return a new instance when clause object is replaced"); Assert.That(clauses2.SelectClause?.Clause, Is.EqualTo("id, name, email")); } [Test] public void GetClauses_ApplyClauses_InvalidatesCache() { // Arrange var query = new QueryBreakdown("id", "users"); var clauses1 = query.GetClauses(); var newClauses = new SqlClauses { SelectClause = new SqlExpressionClause { Clause = "id, name" }, FromClause = new SqlClause { Clause = "customers" } }; // Act query.ApplyClauses(newClauses); var clauses2 = query.GetClauses(); // Assert Assert.That(clauses2, Is.Not.SameAs(clauses1), "GetClauses should return a new instance after ApplyClauses"); Assert.That(clauses2.SelectClause?.Clause, Is.EqualTo("id, name")); Assert.That(clauses2.FromClause?.Clause, Is.EqualTo("customers")); } [Test] public void GetClauses_InitialCall_ReturnsPopulatedObject() { // Arrange var query = new QueryBreakdown("id, name", "users", "active = 1"); query.OrderByClause.Clause = "name ASC"; // Act var clauses = query.GetClauses(); // Assert Assert.That(clauses, Is.Not.Null); Assert.That(clauses.SelectClause?.Clause, Is.EqualTo("id, name")); Assert.That(clauses.FromClause?.Clause, Is.EqualTo("users")); Assert.That(clauses.WhereClause?.Clause, Is.EqualTo("active = 1")); Assert.That(clauses.OrderByClause?.Clause, Is.EqualTo("name ASC")); } [Test] public void GetClauses_AfterNoChanges_ReturnsSameCachedInstance() { // Arrange var query = new QueryBreakdown("id, name", "users"); // Act - Call GetClauses multiple times without any modifications var clauses1 = query.GetClauses(); var clauses2 = query.GetClauses(); var clauses3 = query.GetClauses(); // Assert - All should be the same instance Assert.That(clauses2, Is.SameAs(clauses1)); Assert.That(clauses3, Is.SameAs(clauses1)); } }