Files
sql-utilities/tests/Strata.SqlTools.LinqToSql.Tests/ReverseConverterTests.cs
T

345 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.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
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.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.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
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 - 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
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
}