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>
366 lines
12 KiB
C#
366 lines
12 KiB
C#
using NUnit.Framework;
|
|
using Strata.SqlTools.Breakdowns.SqlServer;
|
|
using Strata.SqlTools.Builders.LinqToSql;
|
|
using Strata.SqlTools.Converters.LinqToSql;
|
|
using PostgreSqlBreakdown = Strata.SqlTools.Breakdowns.PostgreSql.QueryBreakdown;
|
|
using SnowflakeBreakdown = Strata.SqlTools.Breakdowns.Snowflake.QueryBreakdown;
|
|
|
|
namespace Strata.SqlTools.LinqToSql.Tests;
|
|
|
|
[TestFixture]
|
|
public class ReverseConverterTests
|
|
{
|
|
#region SQL Server to LINQ Conversion Tests
|
|
|
|
[Test]
|
|
public void ToLinqQueryBreakdown_FromSqlServer_PreservesAllClauses()
|
|
{
|
|
// Arrange
|
|
var sqlServerBreakdown = new QueryBreakdown();
|
|
sqlServerBreakdown.SelectClause.Clause = "Id, Name, Email";
|
|
sqlServerBreakdown.FromClause.Clause = "Users";
|
|
sqlServerBreakdown.WhereClause.Clause = "IsActive = 1";
|
|
sqlServerBreakdown.OrderByClause.Clause = "Name ASC";
|
|
|
|
// Act
|
|
var linqBreakdown = sqlServerBreakdown.ToLinqQueryBreakdown();
|
|
|
|
// Assert
|
|
Assert.That(linqBreakdown, Is.Not.Null);
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(linqBreakdown.SelectClause.Clause, Contains.Substring("Id"));
|
|
Assert.That(linqBreakdown.FromClause.Clause, Is.EqualTo("Users"));
|
|
Assert.That(linqBreakdown.WhereClause.Clause, Is.EqualTo("IsActive = 1"));
|
|
Assert.That(linqBreakdown.OrderByClause.Clause, Is.EqualTo("Name ASC"));
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ToLinqQueryBreakdown_FromSqlServer_WithGroupBy_PreservesGroupByAndHaving()
|
|
{
|
|
// Arrange
|
|
var sqlServerBreakdown = new QueryBreakdown();
|
|
sqlServerBreakdown.SelectClause.Clause = "Department, COUNT(*) as EmployeeCount";
|
|
sqlServerBreakdown.FromClause.Clause = "Employees";
|
|
sqlServerBreakdown.GroupByClause.Clause = "Department";
|
|
sqlServerBreakdown.HavingClause.Clause = "COUNT(*) > 5";
|
|
|
|
// Act
|
|
var linqBreakdown = sqlServerBreakdown.ToLinqQueryBreakdown();
|
|
|
|
Assert.Multiple(() =>
|
|
{
|
|
// Assert
|
|
Assert.That(linqBreakdown.GroupByClause.Clause, Is.EqualTo("Department"));
|
|
Assert.That(linqBreakdown.HavingClause.Clause, Is.EqualTo("COUNT(*) > 5"));
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ToLinqQueryBreakdown_FromSqlServer_WithNullInput_ThrowsArgumentNullException()
|
|
{
|
|
// Arrange
|
|
QueryBreakdown? sqlServerBreakdown = null;
|
|
|
|
// Act & Assert
|
|
#pragma warning disable CS8604 // Possible null reference argument.
|
|
Assert.Throws<ArgumentNullException>(() => sqlServerBreakdown.ToLinqQueryBreakdown());
|
|
#pragma warning restore CS8604 // Possible null reference argument.
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PostgreSQL to LINQ Conversion Tests
|
|
|
|
[Test]
|
|
public void ToLinqQueryBreakdown_FromPostgreSQL_PreservesAllClauses()
|
|
{
|
|
// Arrange
|
|
var pgBreakdown = new PostgreSqlBreakdown();
|
|
pgBreakdown.SelectClause.Clause = "user_id, user_name";
|
|
pgBreakdown.FromClause.Clause = "users";
|
|
pgBreakdown.WhereClause.Clause = "is_active = true";
|
|
|
|
// Act
|
|
var linqBreakdown = pgBreakdown.ToLinqQueryBreakdown();
|
|
|
|
// Assert
|
|
Assert.That(linqBreakdown, Is.Not.Null);
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(linqBreakdown.SelectClause.Clause, Contains.Substring("user_id"));
|
|
Assert.That(linqBreakdown.FromClause.Clause, Is.EqualTo("users"));
|
|
Assert.That(linqBreakdown.WhereClause.Clause, Is.EqualTo("is_active = true"));
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ToLinqQueryBreakdown_FromPostgreSQL_WithNullInput_ThrowsArgumentNullException()
|
|
{
|
|
// Arrange
|
|
PostgreSqlBreakdown? pgBreakdown = null;
|
|
|
|
// Act & Assert
|
|
#pragma warning disable CS8604 // Possible null reference argument.
|
|
Assert.Throws<ArgumentNullException>(() => pgBreakdown.ToLinqQueryBreakdown());
|
|
#pragma warning restore CS8604 // Possible null reference argument.
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Snowflake to LINQ Conversion Tests
|
|
|
|
[Test]
|
|
public void ToLinqQueryBreakdown_FromSnowflake_PreservesAllClauses()
|
|
{
|
|
// Arrange
|
|
var sfBreakdown = new SnowflakeBreakdown();
|
|
sfBreakdown.SelectClause.Clause = "USER_ID, USER_NAME";
|
|
sfBreakdown.FromClause.Clause = "USERS";
|
|
sfBreakdown.WhereClause.Clause = "IS_ACTIVE = TRUE";
|
|
|
|
// Act
|
|
var linqBreakdown = sfBreakdown.ToLinqQueryBreakdown();
|
|
|
|
// Assert
|
|
Assert.That(linqBreakdown, Is.Not.Null);
|
|
Assert.Multiple(() =>
|
|
{
|
|
Assert.That(linqBreakdown.SelectClause.Clause, Contains.Substring("USER_ID"));
|
|
Assert.That(linqBreakdown.FromClause.Clause, Is.EqualTo("USERS"));
|
|
Assert.That(linqBreakdown.WhereClause.Clause, Is.EqualTo("IS_ACTIVE = TRUE"));
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public void ToLinqQueryBreakdown_FromSnowflake_WithNullInput_ThrowsArgumentNullException()
|
|
{
|
|
// Arrange
|
|
SnowflakeBreakdown? sfBreakdown = null;
|
|
|
|
// Act & Assert
|
|
#pragma warning disable CS8604 // Possible null reference argument.
|
|
Assert.Throws<ArgumentNullException>(() => sfBreakdown.ToLinqQueryBreakdown());
|
|
#pragma warning restore CS8604 // Possible null reference argument.
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Dialect-to-Dialect Conversion Tests
|
|
|
|
[Test]
|
|
public void ConvertToDialect_SqlServerToPostgreSQL_ReturnsPostgreSQLBreakdown()
|
|
{
|
|
// Arrange
|
|
var sqlServerBreakdown = new QueryBreakdown();
|
|
sqlServerBreakdown.SelectClause.Clause = "Id, Name";
|
|
sqlServerBreakdown.FromClause.Clause = "Users";
|
|
|
|
// Act
|
|
var result = sqlServerBreakdown.ConvertToDialect("postgresql");
|
|
|
|
// Assert
|
|
Assert.That(result, Is.TypeOf<PostgreSqlBreakdown>());
|
|
}
|
|
|
|
[Test]
|
|
public void ConvertToDialect_SqlServerToSnowflake_ReturnsSnowflakeBreakdown()
|
|
{
|
|
// Arrange
|
|
var sqlServerBreakdown = new QueryBreakdown();
|
|
sqlServerBreakdown.SelectClause.Clause = "Id, Name";
|
|
sqlServerBreakdown.FromClause.Clause = "Users";
|
|
|
|
// Act
|
|
var result = sqlServerBreakdown.ConvertToDialect("snowflake");
|
|
|
|
// Assert
|
|
Assert.That(result, Is.TypeOf<SnowflakeBreakdown>());
|
|
}
|
|
|
|
[Test]
|
|
public void ConvertToDialect_SqlServerToLINQ_ReturnsLinqQueryBreakdown()
|
|
{
|
|
// Arrange
|
|
var sqlServerBreakdown = new QueryBreakdown();
|
|
sqlServerBreakdown.SelectClause.Clause = "Id, Name";
|
|
sqlServerBreakdown.FromClause.Clause = "Users";
|
|
|
|
// Act
|
|
var result = sqlServerBreakdown.ConvertToDialect("linq");
|
|
|
|
// Assert
|
|
Assert.That(result, Is.TypeOf<Strata.SqlTools.Breakdowns.LinqToSql.LinqQueryBreakdown>());
|
|
}
|
|
|
|
[Test]
|
|
public void ConvertToDialect_SqlServerToSqlServer_ReturnsSameSqlServerBreakdown()
|
|
{
|
|
// Arrange
|
|
var sqlServerBreakdown = new QueryBreakdown();
|
|
sqlServerBreakdown.SelectClause.Clause = "Id, Name";
|
|
sqlServerBreakdown.FromClause.Clause = "Users";
|
|
|
|
// Act
|
|
var result = sqlServerBreakdown.ConvertToDialect("sqlserver");
|
|
|
|
// Assert
|
|
Assert.That(result, Is.SameAs(sqlServerBreakdown));
|
|
}
|
|
|
|
[Test]
|
|
public void ConvertToDialect_PostgresToSqlServer_ReturnsSqlServerBreakdown()
|
|
{
|
|
// Arrange
|
|
var pgBreakdown = new PostgreSqlBreakdown();
|
|
pgBreakdown.SelectClause.Clause = "id, name";
|
|
pgBreakdown.FromClause.Clause = "users";
|
|
|
|
// Act
|
|
var result = pgBreakdown.ConvertToDialect("sqlserver");
|
|
|
|
// Assert
|
|
Assert.That(result, Is.TypeOf<QueryBreakdown>());
|
|
}
|
|
|
|
[Test]
|
|
public void ConvertToDialect_SnowflakeToPostgreSQL_ReturnsPostgresBreakdown()
|
|
{
|
|
// Arrange
|
|
var sfBreakdown = new SnowflakeBreakdown();
|
|
sfBreakdown.SelectClause.Clause = "ID, NAME";
|
|
sfBreakdown.FromClause.Clause = "USERS";
|
|
|
|
// Act
|
|
var result = sfBreakdown.ConvertToDialect("postgres");
|
|
|
|
// Assert
|
|
Assert.That(result, Is.TypeOf<PostgreSqlBreakdown>());
|
|
}
|
|
|
|
[Test]
|
|
public void ConvertToDialect_WithUnknownDialect_ThrowsArgumentException()
|
|
{
|
|
// Arrange
|
|
var sqlServerBreakdown = new QueryBreakdown();
|
|
sqlServerBreakdown.SelectClause.Clause = "Id";
|
|
sqlServerBreakdown.FromClause.Clause = "Users";
|
|
|
|
// Act & Assert
|
|
Assert.Throws<ArgumentException>(() => sqlServerBreakdown.ConvertToDialect("unknown"));
|
|
}
|
|
|
|
[Test]
|
|
public void ConvertToDialect_IsCaseInsensitive()
|
|
{
|
|
// Arrange
|
|
var sqlServerBreakdown = new QueryBreakdown();
|
|
sqlServerBreakdown.SelectClause.Clause = "Id";
|
|
sqlServerBreakdown.FromClause.Clause = "Users";
|
|
|
|
// Act
|
|
var result1 = sqlServerBreakdown.ConvertToDialect("PostgreSQL");
|
|
var result2 = sqlServerBreakdown.ConvertToDialect("POSTGRESQL");
|
|
var result3 = sqlServerBreakdown.ConvertToDialect("postgresql");
|
|
|
|
Assert.Multiple(() =>
|
|
{
|
|
// Assert
|
|
Assert.That(result1, Is.TypeOf<PostgreSqlBreakdown>());
|
|
Assert.That(result2, Is.TypeOf<PostgreSqlBreakdown>());
|
|
Assert.That(result3, Is.TypeOf<PostgreSqlBreakdown>());
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Round-Trip Conversion Tests
|
|
|
|
[Test]
|
|
public void RoundTrip_SqlServer_ToLinq_ToPostgres_ToLinq_ToSqlServer_PreservesData()
|
|
{
|
|
// Arrange
|
|
var original = LinqQueryBreakdownBuilder
|
|
.Create()
|
|
.SelectColumns("Id", "Name")
|
|
.FromTable("Users")
|
|
.Where("IsActive = true")
|
|
.OrderByAscending("Name")
|
|
.Build();
|
|
|
|
// Act - Convert: LINQ -> SqlServer -> LINQ -> PostgreSQL -> LINQ -> SqlServer
|
|
var toSqlServer = original.ConvertToSqlServerBreakdown() as QueryBreakdown;
|
|
var backToLinq = toSqlServer!.ToLinqQueryBreakdown();
|
|
var toPostgres = backToLinq.ConvertToPostgreSqlBreakdown() as PostgreSqlBreakdown;
|
|
var backToLinq2 = toPostgres!.ToLinqQueryBreakdown();
|
|
var finalToSqlServer = backToLinq2.ConvertToSqlServerBreakdown();
|
|
|
|
Assert.Multiple(() =>
|
|
{
|
|
// Assert - Check that clauses are preserved
|
|
Assert.That(backToLinq.SelectClause.Clause, Contains.Substring("Id"));
|
|
Assert.That(backToLinq.FromClause.Clause, Is.EqualTo("Users"));
|
|
Assert.That(backToLinq.WhereClause.Clause, Is.EqualTo("IsActive = true"));
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Null Handling Tests
|
|
|
|
[Test]
|
|
public void ToLinqQueryBreakdown_WithNullPostgreSQL_ThrowsArgumentNullException()
|
|
{
|
|
// Arrange
|
|
PostgreSqlBreakdown? pgBreakdown = null;
|
|
|
|
// Act & Assert
|
|
#pragma warning disable CS8604 // Possible null reference argument.
|
|
Assert.Throws<ArgumentNullException>(() => pgBreakdown.ToLinqQueryBreakdown());
|
|
#pragma warning restore CS8604 // Possible null reference argument.
|
|
}
|
|
|
|
[Test]
|
|
public void ConvertToDialect_WithNullBreakdown_ThrowsArgumentNullException()
|
|
{
|
|
// Arrange
|
|
QueryBreakdown? sqlServerBreakdown = null;
|
|
|
|
// Act & Assert
|
|
#pragma warning disable CS8604 // Possible null reference argument.
|
|
Assert.Throws<ArgumentNullException>(() => sqlServerBreakdown.ConvertToDialect("postgresql"));
|
|
#pragma warning restore CS8604 // Possible null reference argument.
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Alternative Dialect Names Tests
|
|
|
|
[Test]
|
|
public void ConvertToDialect_AcceptsAlternativeDialectNames()
|
|
{
|
|
// Arrange
|
|
var sqlServerBreakdown = new QueryBreakdown();
|
|
sqlServerBreakdown.SelectClause.Clause = "Id";
|
|
sqlServerBreakdown.FromClause.Clause = "Users";
|
|
|
|
// Act
|
|
var resultPostgres1 = sqlServerBreakdown.ConvertToDialect("postgres");
|
|
var resultPostgres2 = sqlServerBreakdown.ConvertToDialect("postgresql");
|
|
var resultSqlServer1 = sqlServerBreakdown.ConvertToDialect("sqlserver");
|
|
var resultSqlServer2 = sqlServerBreakdown.ConvertToDialect("sql_server");
|
|
|
|
Assert.Multiple(() =>
|
|
{
|
|
// Assert
|
|
Assert.That(resultPostgres1, Is.TypeOf<PostgreSqlBreakdown>());
|
|
Assert.That(resultPostgres2, Is.TypeOf<PostgreSqlBreakdown>());
|
|
Assert.That(resultSqlServer1, Is.SameAs(sqlServerBreakdown));
|
|
Assert.That(resultSqlServer2, Is.SameAs(sqlServerBreakdown));
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
}
|