SonarQube Analysis / sonarqube (pull_request) Successful in 2m59s
Re-runs `dotnet format analyzers --diagnostics NUnit2046 NUnit2045` after the Tier 2 Assert.Multiple wrap, which exposed: - `Has.Length.EqualTo(n)` rewrites for `string[]`/array `.Length` checks (the first pass only knew about `.Count`). - `Is.Not.Empty` rewrites for `Count, Is.GreaterThan(0)`. - A handful of new NUnit2045 groups that became wrappable once the initial Multiple blocks settled the surrounding indentation. Tests still 1180/1180 passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
384 lines
11 KiB
C#
384 lines
11 KiB
C#
using Strata.SqlTools.Breakdowns.SqlServer;
|
|
|
|
namespace Strata.SqlTools.SqlServer.Tests.SqlServer;
|
|
|
|
[TestFixture]
|
|
public class QueryBreakdownCollectionTests
|
|
{
|
|
private QueryBreakdownCollection _collection = null!;
|
|
|
|
[SetUp]
|
|
public void Setup()
|
|
{
|
|
_collection = new QueryBreakdownCollection();
|
|
}
|
|
|
|
[Test]
|
|
public void Constructor_Empty_CreatesEmptyCollection()
|
|
{
|
|
// Act & Assert
|
|
Assert.That(_collection, Is.Empty);
|
|
Assert.That(_collection.QueryBreakdowns, Is.Empty);
|
|
}
|
|
|
|
[Test]
|
|
public void Constructor_WithQueries_InitializesCollection()
|
|
{
|
|
// Arrange
|
|
var queries = new List<QueryBreakdown>
|
|
{
|
|
new QueryBreakdown("ID, Name", "Users"),
|
|
new QueryBreakdown("OrderID, Amount", "Orders")
|
|
};
|
|
|
|
// Act
|
|
var collection = new QueryBreakdownCollection(queries);
|
|
|
|
// Assert
|
|
Assert.That(collection, Has.Count.EqualTo(2));
|
|
Assert.That(collection.QueryBreakdowns, Has.Count.EqualTo(2));
|
|
}
|
|
|
|
[Test]
|
|
public void Add_SingleQuery_AddsToCollection()
|
|
{
|
|
// Arrange
|
|
var query = new QueryBreakdown("ID, Name", "Users");
|
|
|
|
// Act
|
|
_collection.Add(query);
|
|
|
|
// Assert
|
|
Assert.That(_collection, Has.Count.EqualTo(1));
|
|
Assert.That(_collection.QueryBreakdowns[0], Is.EqualTo(query));
|
|
}
|
|
|
|
[Test]
|
|
public void Add_NullQuery_ThrowsArgumentNullException()
|
|
{
|
|
// Act & Assert
|
|
Assert.Throws<ArgumentNullException>(() => _collection.Add(null!));
|
|
}
|
|
|
|
[Test]
|
|
public void AddRange_MultipleQueries_AddsAllQueries()
|
|
{
|
|
// Arrange
|
|
var queries = new List<QueryBreakdown>
|
|
{
|
|
new QueryBreakdown("ID, Name", "Users"),
|
|
new QueryBreakdown("OrderID, Amount", "Orders")
|
|
};
|
|
|
|
// Act
|
|
_collection.AddRange(queries);
|
|
|
|
// Assert
|
|
Assert.That(_collection, Has.Count.EqualTo(2));
|
|
}
|
|
|
|
[Test]
|
|
public void Remove_ExistingQuery_RemovesFromCollection()
|
|
{
|
|
// Arrange
|
|
var query = new QueryBreakdown("ID, Name", "Users");
|
|
_collection.Add(query);
|
|
|
|
// Act
|
|
var removed = _collection.Remove(query);
|
|
|
|
Assert.Multiple(() =>
|
|
{
|
|
// Assert
|
|
Assert.That(removed, Is.True);
|
|
Assert.That(_collection, Is.Empty);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void Remove_NonExistentQuery_ReturnsFalse()
|
|
{
|
|
// Arrange
|
|
var query1 = new QueryBreakdown("ID, Name", "Users");
|
|
var query2 = new QueryBreakdown("OrderID, Amount", "Orders");
|
|
_collection.Add(query1);
|
|
|
|
// Act
|
|
var removed = _collection.Remove(query2);
|
|
|
|
Assert.Multiple(() =>
|
|
{
|
|
// Assert
|
|
Assert.That(removed, Is.False);
|
|
Assert.That(_collection, Has.Count.EqualTo(1));
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void Clear_WithQueries_RemovesAllQueries()
|
|
{
|
|
// Arrange
|
|
_collection.Add(new QueryBreakdown("ID, Name", "Users"));
|
|
_collection.Add(new QueryBreakdown("OrderID, Amount", "Orders"));
|
|
|
|
// Act
|
|
_collection.Clear();
|
|
|
|
// Assert
|
|
Assert.That(_collection, Is.Empty);
|
|
}
|
|
|
|
[Test]
|
|
public void GetSqlServerBatch_MultipleQueries_ContainsGoSeparators()
|
|
{
|
|
// Arrange
|
|
_collection.Add(new QueryBreakdown("ID, Name", "Users"));
|
|
_collection.Add(new QueryBreakdown("OrderID, Amount", "Orders"));
|
|
|
|
// Act
|
|
var sql = _collection.GetSqlServerBatch();
|
|
|
|
// Assert
|
|
Assert.That(sql, Does.Contain("GO"));
|
|
Assert.That(sql, Does.Contain("SELECT"));
|
|
}
|
|
|
|
[Test]
|
|
public void GetSqlServerBatch_WithTransaction_WrapsInTransaction()
|
|
{
|
|
// Arrange
|
|
_collection.Add(new QueryBreakdown("ID, Name", "Users"));
|
|
|
|
// Act
|
|
var sql = _collection.GetSqlServerBatch(includeTransaction: true);
|
|
|
|
// Assert
|
|
Assert.That(sql, Does.Contain("BEGIN TRANSACTION"));
|
|
Assert.That(sql, Does.Contain("COMMIT TRANSACTION"));
|
|
}
|
|
|
|
[Test]
|
|
public void WhereSelectContains_MatchingColumn_ReturnsQuery()
|
|
{
|
|
// Arrange
|
|
var query1 = new QueryBreakdown("ID, Name, Email", "Users");
|
|
var query2 = new QueryBreakdown("OrderID, Amount", "Orders");
|
|
_collection.Add(query1);
|
|
_collection.Add(query2);
|
|
|
|
// Act
|
|
var results = _collection.WhereSelectContains("Email").ToList();
|
|
|
|
// Assert
|
|
Assert.That(results, Has.Count.EqualTo(1));
|
|
Assert.That(results[0], Is.EqualTo(query1));
|
|
}
|
|
|
|
[Test]
|
|
public void WhereSelectContains_CaseInsensitive_ReturnsQuery()
|
|
{
|
|
// Arrange
|
|
var query = new QueryBreakdown("ID, Name, Email", "Users");
|
|
_collection.Add(query);
|
|
|
|
// Act
|
|
var results = _collection.WhereSelectContains("email").ToList();
|
|
|
|
// Assert
|
|
Assert.That(results, Has.Count.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public void WhereTableContains_MatchingTable_ReturnsQuery()
|
|
{
|
|
// Arrange
|
|
var query1 = new QueryBreakdown("ID, Name", "Users");
|
|
var query2 = new QueryBreakdown("OrderID", "Orders");
|
|
_collection.Add(query1);
|
|
_collection.Add(query2);
|
|
|
|
// Act
|
|
var results = _collection.WhereTableContains("Users").ToList();
|
|
|
|
// Assert
|
|
Assert.That(results, Has.Count.EqualTo(1));
|
|
Assert.That(results[0], Is.EqualTo(query1));
|
|
}
|
|
|
|
[Test]
|
|
public void WhereHaveWhereClause_WithWhereClauses_ReturnsMatchingQueries()
|
|
{
|
|
// Arrange
|
|
var query1 = new QueryBreakdown("ID, Name", "Users", "ID > 10");
|
|
var query2 = new QueryBreakdown("OrderID", "Orders");
|
|
_collection.Add(query1);
|
|
_collection.Add(query2);
|
|
|
|
// Act
|
|
var results = _collection.WhereHaveWhereClause().ToList();
|
|
|
|
// Assert
|
|
Assert.That(results, Has.Count.EqualTo(1));
|
|
Assert.That(results[0], Is.EqualTo(query1));
|
|
}
|
|
|
|
[Test]
|
|
public void WhereHaveNoWhereClause_WithoutWhereClauses_ReturnsMatchingQueries()
|
|
{
|
|
// Arrange
|
|
var query1 = new QueryBreakdown("ID, Name", "Users", "ID > 10");
|
|
var query2 = new QueryBreakdown("OrderID", "Orders");
|
|
_collection.Add(query1);
|
|
_collection.Add(query2);
|
|
|
|
// Act
|
|
var results = _collection.WhereHaveNoWhereClause().ToList();
|
|
|
|
// Assert
|
|
Assert.That(results, Has.Count.EqualTo(1));
|
|
Assert.That(results[0], Is.EqualTo(query2));
|
|
}
|
|
|
|
[Test]
|
|
public void GetTotalSelectedColumns_MultipleQueries_SumsColumns()
|
|
{
|
|
// Arrange
|
|
_collection.Add(new QueryBreakdown("ID, Name, Email", "Users"));
|
|
_collection.Add(new QueryBreakdown("OrderID, Amount", "Orders"));
|
|
|
|
// Act
|
|
var columnCount = _collection.GetTotalSelectedColumns();
|
|
|
|
// Assert
|
|
Assert.That(columnCount, Is.EqualTo(5));
|
|
}
|
|
|
|
[Test]
|
|
public void GetUniqueTableReferences_MultipleQueries_ReturnsUniqueTables()
|
|
{
|
|
// Arrange
|
|
_collection.Add(new QueryBreakdown("ID, Name", "Users"));
|
|
_collection.Add(new QueryBreakdown("OrderID, UserID", "Orders"));
|
|
_collection.Add(new QueryBreakdown("ID", "Users"));
|
|
|
|
// Act
|
|
var tables = _collection.GetUniqueTableReferences().ToList();
|
|
|
|
// Assert
|
|
Assert.That(tables, Has.Count.EqualTo(2));
|
|
Assert.That(tables, Does.Contain("Users"));
|
|
Assert.That(tables, Does.Contain("Orders"));
|
|
}
|
|
|
|
[Test]
|
|
public void GetQuerySummaries_MultipleQueries_ReturnsSummaryForEach()
|
|
{
|
|
// Arrange
|
|
_collection.Add(new QueryBreakdown("ID, Name", "Users"));
|
|
_collection.Add(new QueryBreakdown("OrderID, Amount", "Orders", "Amount > 100"));
|
|
|
|
// Act
|
|
var summaries = _collection.GetQuerySummaries().ToList();
|
|
|
|
// Assert
|
|
Assert.That(summaries, Has.Count.EqualTo(2));
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(summaries[0].HasSelectClause, Is.True);
|
|
Assert.That(summaries[1].HasWhereClause, Is.True);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void SynchronizeParameters_ParametersInSomeQueries_SynchronizesAcrossQueries()
|
|
{
|
|
// Arrange
|
|
var query1 = new QueryBreakdown("ID, Name", "Users", "ID = @UserId");
|
|
var query2 = new QueryBreakdown("OrderID", "Orders", "UserID = @UserId");
|
|
query1.Parameters["UserId"] = 123;
|
|
query2.Parameters["UserId"] = 456;
|
|
_collection.Add(query1);
|
|
_collection.Add(query2);
|
|
|
|
// Act
|
|
_collection.SynchronizeParameters();
|
|
|
|
// Assert
|
|
// Both should have the same value (the last one)
|
|
Assert.That(query1.Parameters["UserId"], Is.EqualTo(query2.Parameters["UserId"]));
|
|
}
|
|
|
|
[Test]
|
|
public void SynchronizeParameters_OnlyUpdatesExistingParameters()
|
|
{
|
|
// Arrange
|
|
var query1 = new QueryBreakdown("ID, Name", "Users", "ID = @UserId");
|
|
var query2 = new QueryBreakdown("OrderID", "Orders");
|
|
query1.Parameters["UserId"] = 123;
|
|
_collection.Add(query1);
|
|
_collection.Add(query2);
|
|
|
|
// Act
|
|
_collection.SynchronizeParameters();
|
|
|
|
// Assert
|
|
// query2 should NOT have UserId parameter added
|
|
Assert.That(query2.Parameters.ContainsKey("UserId"), Is.False);
|
|
}
|
|
|
|
[Test]
|
|
public void AddParameterToAll_AddsParameterToAllQueries()
|
|
{
|
|
// Arrange
|
|
_collection.Add(new QueryBreakdown("ID, Name", "Users"));
|
|
_collection.Add(new QueryBreakdown("OrderID", "Orders"));
|
|
|
|
// Act
|
|
_collection.AddParameterToAll("CompanyId", 99);
|
|
|
|
Assert.Multiple(() =>
|
|
{
|
|
// Assert
|
|
Assert.That(_collection.QueryBreakdowns[0].Parameters["CompanyId"], Is.EqualTo(99));
|
|
Assert.That(_collection.QueryBreakdowns[1].Parameters["CompanyId"], Is.EqualTo(99));
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void GetParameterUsageReport_WithParameters_ReturnsUsageReport()
|
|
{
|
|
// Arrange
|
|
var query1 = new QueryBreakdown("ID, Name", "Users", "ID = @UserId");
|
|
var query2 = new QueryBreakdown("OrderID", "Orders", "UserID = @UserId AND Status = @Status");
|
|
query1.Parameters["UserId"] = 123;
|
|
query2.Parameters["UserId"] = 123;
|
|
query2.Parameters["Status"] = "Active";
|
|
_collection.Add(query1);
|
|
_collection.Add(query2);
|
|
|
|
// Act
|
|
var report = _collection.GetParameterUsageReport().ToList();
|
|
|
|
// Assert
|
|
Assert.That(report, Is.Not.Empty);
|
|
var userIdReport = report.FirstOrDefault(r => r.ParameterName == "UserId");
|
|
Assert.That(userIdReport, Is.Not.Null);
|
|
Assert.That(userIdReport?.UsedInQueryCount, Is.EqualTo(2));
|
|
}
|
|
|
|
[Test]
|
|
public void GetParametersAsString_WithParameters_FormatsWithDataTypes()
|
|
{
|
|
// Arrange
|
|
_collection.Add(new QueryBreakdown("ID, Name", "Users", "ID = @UserId"));
|
|
_collection.QueryBreakdowns[0].Parameters["UserId"] = 123;
|
|
|
|
// Act
|
|
var paramString = _collection.GetParametersAsString(includeDataTypes: true);
|
|
|
|
// Assert
|
|
Assert.That(paramString, Does.Contain("@UserId"));
|
|
Assert.That(paramString, Does.Contain("INT"));
|
|
}
|
|
}
|