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>
This commit is contained in:
Thom Lamb
2026-05-27 11:59:47 -05:00
co-authored by Claude Opus 4.7
parent 505ada5017
commit 67512d23e1
47 changed files with 2132 additions and 1113 deletions
@@ -20,9 +20,12 @@ public class CTEColumnListTests
// Act & Assert
Assert.That(withClause.ColumnList, Has.Count.EqualTo(3));
Assert.That(withClause.ColumnList[0], Is.EqualTo("user_id"));
Assert.That(withClause.ColumnList[1], Is.EqualTo("user_name"));
Assert.That(withClause.ColumnList[2], Is.EqualTo("user_email"));
Assert.Multiple(() =>
{
Assert.That(withClause.ColumnList[0], Is.EqualTo("user_id"));
Assert.That(withClause.ColumnList[1], Is.EqualTo("user_name"));
Assert.That(withClause.ColumnList[2], Is.EqualTo("user_email"));
});
}
[Test]
@@ -269,8 +272,11 @@ public class CTEColumnListTests
// Assert
Assert.That(sql, Contains.Substring("customer_transactions (trans_date, prod_id, cust_id, trans_amount, transaction_rank)"));
var paramKeys = params_all.Keys.ToList();
Assert.That(paramKeys.Any(k => k.Contains("StartDate")));
Assert.That(paramKeys.Any(k => k.Contains("MinAmount")));
Assert.Multiple(() =>
{
Assert.That(paramKeys.Any(k => k.Contains("StartDate")));
Assert.That(paramKeys.Any(k => k.Contains("MinAmount")));
});
}
#endregion
@@ -182,9 +182,12 @@ public class QueryBreakdownCollectionTests
// Act
var result = _collection.ParseBatch(batchSql);
// Assert
Assert.That(result, Is.True);
Assert.That(_collection.Count, Is.GreaterThan(0));
Assert.Multiple(() =>
{
// Assert
Assert.That(result, Is.True);
Assert.That(_collection.Count, Is.GreaterThan(0));
});
}
[Test]
@@ -199,9 +202,12 @@ public class QueryBreakdownCollectionTests
// Act
var result = _collection.ParseBatch(batchSql);
// Assert
Assert.That(result, Is.True);
Assert.That(_collection.Count, Is.GreaterThan(0));
Assert.Multiple(() =>
{
// Assert
Assert.That(result, Is.True);
Assert.That(_collection.Count, Is.GreaterThan(0));
});
}
[Test]
@@ -284,8 +290,11 @@ public class QueryBreakdownCollectionTests
// Assert
Assert.That(sql, Does.Contain("SELECT"));
Assert.That(sql, Does.Contain(";"));
Assert.That(_collection, Has.Count.EqualTo(3));
Assert.Multiple(() =>
{
Assert.That(sql, Does.Contain(";"));
Assert.That(_collection, Has.Count.EqualTo(3));
});
}
#endregion
@@ -13,11 +13,14 @@ public class QueryBreakdownTests
// Arrange & Act
var queryBreakdown = new QueryBreakdown();
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.EqualTo(string.Empty));
Assert.That(queryBreakdown.FromClause.Clause, Is.EqualTo(string.Empty));
Assert.That(queryBreakdown.WhereClause.Clause, Is.EqualTo(string.Empty));
Assert.That(queryBreakdown.OrderByClause.Clause, Is.EqualTo(string.Empty));
Assert.Multiple(() =>
{
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.EqualTo(string.Empty));
Assert.That(queryBreakdown.FromClause.Clause, Is.EqualTo(string.Empty));
Assert.That(queryBreakdown.WhereClause.Clause, Is.EqualTo(string.Empty));
Assert.That(queryBreakdown.OrderByClause.Clause, Is.EqualTo(string.Empty));
});
}
[Test]
@@ -30,9 +33,12 @@ public class QueryBreakdownTests
// Act
var queryBreakdown = new QueryBreakdown(selectClause, fromClause);
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.EqualTo(selectClause));
Assert.That(queryBreakdown.FromClause.Clause, Is.EqualTo(fromClause));
Assert.Multiple(() =>
{
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.EqualTo(selectClause));
Assert.That(queryBreakdown.FromClause.Clause, Is.EqualTo(fromClause));
});
}
[Test]
@@ -46,10 +52,13 @@ public class QueryBreakdownTests
// Act
var queryBreakdown = new QueryBreakdown(selectClause, fromClause, whereClause);
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.EqualTo(selectClause));
Assert.That(queryBreakdown.FromClause.Clause, Is.EqualTo(fromClause));
Assert.That(queryBreakdown.WhereClause.Clause, Is.EqualTo(whereClause));
Assert.Multiple(() =>
{
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.EqualTo(selectClause));
Assert.That(queryBreakdown.FromClause.Clause, Is.EqualTo(fromClause));
Assert.That(queryBreakdown.WhereClause.Clause, Is.EqualTo(whereClause));
});
}
[Test]
@@ -64,11 +73,14 @@ public class QueryBreakdownTests
// Act
var queryBreakdown = new QueryBreakdown(selectClause, fromClause, whereClause, orderByClause);
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.EqualTo(selectClause));
Assert.That(queryBreakdown.FromClause.Clause, Is.EqualTo(fromClause));
Assert.That(queryBreakdown.WhereClause.Clause, Is.EqualTo(whereClause));
Assert.That(queryBreakdown.OrderByClause.Clause, Is.EqualTo(orderByClause));
Assert.Multiple(() =>
{
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.EqualTo(selectClause));
Assert.That(queryBreakdown.FromClause.Clause, Is.EqualTo(fromClause));
Assert.That(queryBreakdown.WhereClause.Clause, Is.EqualTo(whereClause));
Assert.That(queryBreakdown.OrderByClause.Clause, Is.EqualTo(orderByClause));
});
}
#endregion
@@ -130,9 +142,12 @@ public class QueryBreakdownTests
// Act
queryBreakdown.AddParameter("userId", 123);
// Assert
Assert.That(queryBreakdown.Parameters.ContainsKey("userId"), Is.True);
Assert.That(queryBreakdown.Parameters["userId"], Is.EqualTo(123));
Assert.Multiple(() =>
{
// Assert
Assert.That(queryBreakdown.Parameters.ContainsKey("userId"), Is.True);
Assert.That(queryBreakdown.Parameters["userId"], Is.EqualTo(123));
});
}
[Test]
@@ -148,9 +163,12 @@ public class QueryBreakdownTests
// Assert
Assert.That(queryBreakdown.Parameters.Count, Is.GreaterThanOrEqualTo(3));
Assert.That(queryBreakdown.Parameters.ContainsKey("param1"), Is.True);
Assert.That(queryBreakdown.Parameters.ContainsKey("param2"), Is.True);
Assert.That(queryBreakdown.Parameters.ContainsKey("param3"), Is.True);
Assert.Multiple(() =>
{
Assert.That(queryBreakdown.Parameters.ContainsKey("param1"), Is.True);
Assert.That(queryBreakdown.Parameters.ContainsKey("param2"), Is.True);
Assert.That(queryBreakdown.Parameters.ContainsKey("param3"), Is.True);
});
}
[Test]
@@ -182,8 +200,11 @@ public class QueryBreakdownTests
// Assert
Assert.That(queryBreakdown, Is.Not.Null);
Assert.That(queryBreakdown.SelectClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.FromClause.Clause, Is.Not.Empty);
Assert.Multiple(() =>
{
Assert.That(queryBreakdown.SelectClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.FromClause.Clause, Is.Not.Empty);
});
}
[Test]
@@ -195,9 +216,12 @@ public class QueryBreakdownTests
// Act
var queryBreakdown = QueryBreakdown.Parse(sql);
// Assert
Assert.That(queryBreakdown.WhereClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.FromClause.Clause, Does.Contain("users"));
Assert.Multiple(() =>
{
// Assert
Assert.That(queryBreakdown.WhereClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.FromClause.Clause, Does.Contain("users"));
});
}
[Test]
@@ -244,13 +268,16 @@ public class QueryBreakdownTests
// Act
var queryBreakdown = QueryBreakdown.Parse(sql);
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.FromClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.WhereClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.GroupByClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.HavingClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.OrderByClause.Clause, Is.Not.Empty);
Assert.Multiple(() =>
{
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.FromClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.WhereClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.GroupByClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.HavingClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.OrderByClause.Clause, Is.Not.Empty);
});
}
[Test]
@@ -262,10 +289,13 @@ public class QueryBreakdownTests
// Act
var success = QueryBreakdown.TryParse(sql, out var queryBreakdown, out var errorMessage);
// Assert
Assert.That(success, Is.True);
Assert.That(queryBreakdown, Is.Not.Null);
Assert.That(errorMessage, Is.Empty);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.True);
Assert.That(queryBreakdown, Is.Not.Null);
Assert.That(errorMessage, Is.Empty);
});
}
[Test]
@@ -277,9 +307,12 @@ public class QueryBreakdownTests
// Act
var success = QueryBreakdown.TryParse(sql, out var queryBreakdown, out var errorMessage);
// Assert
Assert.That(success, Is.False);
Assert.That(errorMessage, Is.Not.Empty);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.False);
Assert.That(errorMessage, Is.Not.Empty);
});
}
#endregion
@@ -308,9 +341,12 @@ public class QueryBreakdownTests
// Act
var queryBreakdown = QueryBreakdown.Parse(sql);
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.FromClause.Clause, Is.Not.Empty);
Assert.Multiple(() =>
{
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.Not.Empty);
Assert.That(queryBreakdown.FromClause.Clause, Is.Not.Empty);
});
}
[Test]
@@ -353,9 +389,12 @@ public class QueryBreakdownTests
queryBreakdown.SelectClause.Clause = "id, name";
queryBreakdown.FromClause.Clause = "users";
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.EqualTo("id, name"));
Assert.That(queryBreakdown.FromClause.Clause, Is.EqualTo("users"));
Assert.Multiple(() =>
{
// Assert
Assert.That(queryBreakdown.SelectClause.Clause, Is.EqualTo("id, name"));
Assert.That(queryBreakdown.FromClause.Clause, Is.EqualTo("users"));
});
}
[Test]
@@ -387,8 +426,11 @@ public class QueryBreakdownTests
// Assert
Assert.That(mainQuery.WithClauses, Has.Count.EqualTo(1));
Assert.That(mainQuery.WithClauses[0].TableName, Is.EqualTo("active_users_cte"));
Assert.That(mainQuery.WithClauses[0].Query, Is.EqualTo(cte));
Assert.Multiple(() =>
{
Assert.That(mainQuery.WithClauses[0].TableName, Is.EqualTo("active_users_cte"));
Assert.That(mainQuery.WithClauses[0].Query, Is.EqualTo(cte));
});
}
[Test]
@@ -448,8 +490,11 @@ public class QueryBreakdownTests
// PostgreSQL stores parameters with positional and name-based formats
Assert.That(merged.Count, Is.GreaterThanOrEqualTo(2));
var keys = merged.Keys.ToList();
Assert.That(keys.Any(k => k.Contains("UserId")));
Assert.That(keys.Any(k => k.Contains("ActiveStatus")));
Assert.Multiple(() =>
{
Assert.That(keys.Any(k => k.Contains("UserId")));
Assert.That(keys.Any(k => k.Contains("ActiveStatus")));
});
}
[Test]
@@ -468,8 +513,11 @@ public class QueryBreakdownTests
// Assert
var keys = merged.Keys.ToList();
Assert.That(keys.Any(k => k.Contains("MinDate")));
Assert.That(keys.Any(k => k.Contains("ResultLimit")));
Assert.Multiple(() =>
{
Assert.That(keys.Any(k => k.Contains("MinDate")));
Assert.That(keys.Any(k => k.Contains("ResultLimit")));
});
}
[Test]
@@ -492,9 +540,12 @@ public class QueryBreakdownTests
// Assert
var keys = merged.Keys.ToList();
Assert.That(keys.Any(k => k.Contains("Status1")));
Assert.That(keys.Any(k => k.Contains("MinDate")));
Assert.That(keys.Any(k => k.Contains("ResultLimit")));
Assert.Multiple(() =>
{
Assert.That(keys.Any(k => k.Contains("Status1")));
Assert.That(keys.Any(k => k.Contains("MinDate")));
Assert.That(keys.Any(k => k.Contains("ResultLimit")));
});
}
[Test]
@@ -514,8 +565,11 @@ public class QueryBreakdownTests
// Assert
// Find the UserId parameter value
var userIdKey = merged.Keys.FirstOrDefault(k => k.Contains("UserId") && !k.Contains('$'));
Assert.That(userIdKey, Is.Not.Null);
Assert.That(merged[userIdKey], Is.EqualTo(123)); // Main query value, not CTE value
Assert.Multiple(() =>
{
Assert.That(userIdKey, Is.Not.Null);
Assert.That(merged[userIdKey], Is.EqualTo(123)); // Main query value, not CTE value
});
}
[Test]
@@ -538,9 +592,12 @@ public class QueryBreakdownTests
// Assert
var keys = merged.Keys.ToList();
Assert.That(keys.Any(k => k.Contains("Status")), "Should include Status from nested CTE");
Assert.That(keys.Any(k => k.Contains("Level")), "Should include Level from middle CTE");
Assert.That(keys.Any(k => k.Contains("Limit")), "Should include Limit from main query");
Assert.Multiple(() =>
{
Assert.That(keys.Any(k => k.Contains("Status")), "Should include Status from nested CTE");
Assert.That(keys.Any(k => k.Contains("Level")), "Should include Level from middle CTE");
Assert.That(keys.Any(k => k.Contains("Limit")), "Should include Limit from main query");
});
}
[Test]
@@ -563,14 +620,17 @@ public class QueryBreakdownTests
var boolKey = merged.Keys.FirstOrDefault(k => k.Contains("IsActive") && !k.Contains('$'));
var doubleKey = merged.Keys.FirstOrDefault(k => k.Contains("Threshold") && !k.Contains('$'));
Assert.That(dateKey, Is.Not.Null);
Assert.That(merged[dateKey], Is.TypeOf<DateTime>());
Assert.Multiple(() =>
{
Assert.That(dateKey, Is.Not.Null);
Assert.That(merged[dateKey], Is.TypeOf<DateTime>());
Assert.That(boolKey, Is.Not.Null);
Assert.That(merged[boolKey], Is.TypeOf<bool>());
Assert.That(boolKey, Is.Not.Null);
Assert.That(merged[boolKey], Is.TypeOf<bool>());
Assert.That(doubleKey, Is.Not.Null);
Assert.That(merged[doubleKey], Is.TypeOf<double>());
Assert.That(doubleKey, Is.Not.Null);
Assert.That(merged[doubleKey], Is.TypeOf<double>());
});
}
#endregion
@@ -33,9 +33,12 @@ public class RecursiveCTETests
var isRecursive = withClause.IsRecursive;
var hasRecursiveQuery = withClause.RecursiveQuery != null;
// Assert
Assert.That(isRecursive, Is.True);
Assert.That(hasRecursiveQuery, Is.True);
Assert.Multiple(() =>
{
// Assert
Assert.That(isRecursive, Is.True);
Assert.That(hasRecursiveQuery, Is.True);
});
}
[Test]
@@ -143,10 +146,13 @@ public class RecursiveCTETests
// Assert
var keys = merged.Keys.ToList();
Assert.That(keys.Any(k => k.Contains("AnchorStatus")), "Should include anchor query parameters");
Assert.That(keys.Any(k => k.Contains("RecursiveLevel")), "Should include recursive query parameters");
Assert.That(keys.Any(k => k.Contains("RecursiveStatus")), "Should include recurring query parameters");
Assert.That(keys.Any(k => k.Contains("MainLimit")), "Should include main query parameters");
Assert.Multiple(() =>
{
Assert.That(keys.Any(k => k.Contains("AnchorStatus")), "Should include anchor query parameters");
Assert.That(keys.Any(k => k.Contains("RecursiveLevel")), "Should include recursive query parameters");
Assert.That(keys.Any(k => k.Contains("RecursiveStatus")), "Should include recurring query parameters");
Assert.That(keys.Any(k => k.Contains("MainLimit")), "Should include main query parameters");
});
}
[Test]
@@ -176,8 +182,11 @@ public class RecursiveCTETests
// Assert
// PostgreSQL stores parameters with positional syntax
var statusKey = merged.Keys.FirstOrDefault(k => k.Contains("Status") && !k.StartsWith('$'));
Assert.That(statusKey, Is.Not.Null);
Assert.That(merged[statusKey], Is.EqualTo("active"), "Main query parameter should take precedence");
Assert.Multiple(() =>
{
Assert.That(statusKey, Is.Not.Null);
Assert.That(merged[statusKey], Is.EqualTo("active"), "Main query parameter should take precedence");
});
}
#endregion
@@ -23,9 +23,12 @@ public class StatementReaderTests
// Assert
Assert.That(tokens, Is.Not.Empty);
Assert.That(tokens[0].Type, Is.EqualTo(TokenType.LeftParenthesis));
Assert.That(tokens[1].Type, Is.EqualTo(TokenType.Number));
Assert.That(tokens[1].Value, Is.EqualTo("1"));
Assert.Multiple(() =>
{
Assert.That(tokens[0].Type, Is.EqualTo(TokenType.LeftParenthesis));
Assert.That(tokens[1].Type, Is.EqualTo(TokenType.Number));
Assert.That(tokens[1].Value, Is.EqualTo("1"));
});
}
[Test]
@@ -44,10 +47,13 @@ public class StatementReaderTests
// Assert
Assert.That(tokens, Has.Count.EqualTo(5)); // "COLUMN_1" + "COLUMN_2" * 2
Assert.That(tokens[0].Type, Is.EqualTo(TokenType.ColumnIdentifier));
Assert.That(tokens[0].Value, Is.EqualTo("COLUMN_1"));
Assert.That(tokens[1].Type, Is.EqualTo(TokenType.Plus));
Assert.That(tokens[2].Type, Is.EqualTo(TokenType.ColumnIdentifier));
Assert.Multiple(() =>
{
Assert.That(tokens[0].Type, Is.EqualTo(TokenType.ColumnIdentifier));
Assert.That(tokens[0].Value, Is.EqualTo("COLUMN_1"));
Assert.That(tokens[1].Type, Is.EqualTo(TokenType.Plus));
Assert.That(tokens[2].Type, Is.EqualTo(TokenType.ColumnIdentifier));
});
}
[Test]
@@ -64,11 +70,14 @@ public class StatementReaderTests
tokens.Add((sqlReader.TokenType, sqlReader.TokenValue));
}
// Assert
Assert.That(tokens[0].Type, Is.EqualTo(TokenType.ColumnIdentifier));
Assert.That(tokens[0].Value, Is.EqualTo("MyColumn"));
Assert.That(tokens[2].Type, Is.EqualTo(TokenType.ColumnIdentifier));
Assert.That(tokens[2].Value, Is.EqualTo("AnotherColumn"));
Assert.Multiple(() =>
{
// Assert
Assert.That(tokens[0].Type, Is.EqualTo(TokenType.ColumnIdentifier));
Assert.That(tokens[0].Value, Is.EqualTo("MyColumn"));
Assert.That(tokens[2].Type, Is.EqualTo(TokenType.ColumnIdentifier));
Assert.That(tokens[2].Value, Is.EqualTo("AnotherColumn"));
});
}
[Test]
@@ -89,8 +98,11 @@ public class StatementReaderTests
Assert.That(tokens.Count, Is.GreaterThan(0));
var paramTokens = tokens.Where(t => t.Type == TokenType.Parameter).ToList();
Assert.That(paramTokens, Has.Count.EqualTo(2));
Assert.That(paramTokens[0].Value, Is.EqualTo("$1"));
Assert.That(paramTokens[1].Value, Is.EqualTo("$2"));
Assert.Multiple(() =>
{
Assert.That(paramTokens[0].Value, Is.EqualTo("$1"));
Assert.That(paramTokens[1].Value, Is.EqualTo("$2"));
});
}
[Test]