test(sql): Add comprehensive unit tests for breakdown classes and utilities

Introduces new unit tests for Snowflake and SQL Server-specific SQL breakdown
classes (DELETE, INSERT, UPDATE, PROCEDURE) and various general SQL utility
functions. This significantly increases test coverage, ensuring robustness
and correctness across different SQL dialects and helper logic.
This commit is contained in:
Thom Lamb
2026-06-15 08:16:22 -05:00
parent 9f9450dc6d
commit fbedea3941
13 changed files with 2575 additions and 0 deletions
@@ -0,0 +1,198 @@
using Strata.SqlTools.Breakdowns.SqlServer;
namespace Strata.SqlTools.SqlBreakdown.Tests.SqlServer;
[TestFixture]
public class DeleteBreakdownTests
{
#region Constructor Tests
[Test]
public void Constructor_Default_InitializesEmptyClauses()
{
// Arrange & Act
var breakdown = new DeleteBreakdown();
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.FromClause.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.WhereClause.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.DeleteClause.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.IsUsingWhereClause, Is.False);
});
}
[Test]
public void Constructor_WithClauses_SetsProperties()
{
// Arrange & Act
var breakdown = new DeleteBreakdown("Users", "Id = @Id");
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.FromClause.Clause, Is.EqualTo("Users"));
Assert.That(breakdown.WhereClause.Clause, Is.EqualTo("Id = @Id"));
Assert.That(breakdown.IsUsingWhereClause, Is.True);
});
}
#endregion
#region GetSql Tests
[Test]
public void GetSql_WithWhere_RendersDeleteFromWhere()
{
// Arrange
var breakdown = new DeleteBreakdown("Users", "Id = @Id");
// Act
var sql = breakdown.GetSql();
Assert.Multiple(() =>
{
// Assert
Assert.That(sql, Does.Contain("DELETE"));
Assert.That(sql, Does.Contain("FROM"));
Assert.That(sql, Does.Contain("Users"));
Assert.That(sql, Does.Contain("WHERE"));
Assert.That(sql, Does.Contain("Id = @Id"));
});
}
[Test]
public void GetSql_WithoutWhere_OmitsWhereKeyword()
{
// Arrange
var breakdown = new DeleteBreakdown("Users", string.Empty);
// Act
var sql = breakdown.GetSql();
Assert.Multiple(() =>
{
// Assert
Assert.That(sql, Does.Contain("DELETE"));
Assert.That(sql, Does.Not.Contain("WHERE"));
});
}
[Test]
public void GetSql_WithDeleteClause_RendersAlias()
{
// Arrange
var breakdown = new DeleteBreakdown("Users u", "u.Id = 1")
{
DeleteClause = { Clause = "u" }
};
// Act
var sql = breakdown.GetSql();
// Assert
Assert.That(sql, Does.Contain("DELETE"));
Assert.That(sql, Does.Contain("u"));
}
#endregion
#region Parse Tests
[Test]
public void Parse_SimpleDeleteFrom_PopulatesClauses()
{
// Arrange
var input = "DELETE FROM Users WHERE Id = 1";
// Act
var breakdown = DeleteBreakdown.Parse(input);
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.FromClause.Clause, Is.EqualTo("Users"));
Assert.That(breakdown.WhereClause.Clause, Is.EqualTo("Id = 1"));
});
}
[Test]
public void Parse_DeleteWithAlias_PopulatesDeleteAndFromClauses()
{
// Arrange - DELETE u FROM Users u WHERE ... uses the alias pattern
var input = "DELETE u FROM Users u WHERE u.Id = 1";
// Act
var breakdown = DeleteBreakdown.Parse(input);
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.DeleteClause.Clause, Is.EqualTo("u"));
Assert.That(breakdown.FromClause.Clause, Is.EqualTo("Users u"));
Assert.That(breakdown.WhereClause.Clause, Is.EqualTo("u.Id = 1"));
});
}
[Test]
public void Parse_DeleteWithoutWhere_LeavesWhereEmpty()
{
// Arrange
var input = "DELETE FROM Users";
// Act
var breakdown = DeleteBreakdown.Parse(input);
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.FromClause.Clause, Is.EqualTo("Users"));
Assert.That(breakdown.IsUsingWhereClause, Is.False);
});
}
[Test]
public void Parse_NullOrWhitespace_ThrowsArgumentNullException()
{
// Act & Assert
Assert.Throws<ArgumentNullException>(() => DeleteBreakdown.Parse(null!));
}
[Test]
public void Parse_NotADeleteStatement_ThrowsFormatException()
{
// Act & Assert
Assert.Throws<FormatException>(() => DeleteBreakdown.Parse("SELECT * FROM Users"));
}
[Test]
public void TryParse_WrongPrefix_ReturnsFalseWithMessage()
{
// Act
var success = DeleteBreakdown.TryParse("UPDATE Users SET Id = 1", out _, out var error);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.False);
Assert.That(error, Does.Contain("DELETE"));
});
}
[Test]
public void TryParse_ValidDelete_ReturnsTrue()
{
// Act
var success = DeleteBreakdown.TryParse("DELETE FROM Users WHERE Id = 1", out var breakdown);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.True);
Assert.That(breakdown.FromClause.Clause, Is.EqualTo("Users"));
});
}
#endregion
}
@@ -0,0 +1,209 @@
using Strata.SqlTools.Breakdowns.SqlServer;
namespace Strata.SqlTools.SqlBreakdown.Tests.SqlServer;
[TestFixture]
public class InsertBreakdownTests
{
#region Constructor Tests
[Test]
public void Constructor_Default_InitializesEmptyClauses()
{
// Arrange & Act
var breakdown = new InsertBreakdown();
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.TableName.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.InsertIntoClause.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.ValuesClause.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.SetupClauses, Is.Empty);
Assert.That(breakdown.FinishClauses, Is.Empty);
});
}
[Test]
public void Constructor_WithClauses_SetsProperties()
{
// Arrange & Act
var breakdown = new InsertBreakdown("Users", "Id, Name", "@Id, @Name");
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.TableName.Clause, Is.EqualTo("Users"));
Assert.That(breakdown.InsertIntoClause.Clause, Is.EqualTo("Id, Name"));
Assert.That(breakdown.ValuesClause.Clause, Is.EqualTo("@Id, @Name"));
});
}
[Test]
public void Constructor_WithClauses_ExtractsComments()
{
// Arrange & Act
var breakdown = new InsertBreakdown("Users /* target */", "Id, Name", "@Id, @Name");
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.TableName.Clause, Is.EqualTo("Users"));
Assert.That(breakdown.TableName.Comment, Does.Contain("target"));
});
}
[Test]
public void Constructor_WithColumnNames_GeneratesBracketedColumnsAndAtParameters()
{
// Arrange & Act
var breakdown = new InsertBreakdown("Users", new List<string> { "Id", "Name" });
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.TableName.Clause, Is.EqualTo("Users"));
Assert.That(breakdown.InsertIntoClause.Clause, Is.EqualTo("[Id],[Name]"));
Assert.That(breakdown.ValuesClause.Clause, Is.EqualTo("@Id,@Name"));
});
}
#endregion
#region GetSql Tests
[Test]
public void GetSql_RendersInsertIntoTableColumnsValues()
{
// Arrange
var breakdown = new InsertBreakdown("Users", "Id, Name", "@Id, @Name");
// Act
var sql = breakdown.GetSql();
Assert.Multiple(() =>
{
// Assert
Assert.That(sql, Does.Contain("INSERT INTO"));
Assert.That(sql, Does.Contain("Users"));
Assert.That(sql, Does.Contain("Id, Name"));
Assert.That(sql, Does.Contain("VALUES"));
Assert.That(sql, Does.Contain("@Id, @Name"));
});
}
[Test]
public void ToString_ReturnsGeneratedSql()
{
// Arrange
var breakdown = new InsertBreakdown("Users", "Id", "@Id");
// Act & Assert
Assert.That(breakdown.ToString(), Does.Contain("INSERT INTO"));
}
#endregion
#region Parse Tests
[Test]
public void Parse_ValidInsert_PopulatesClauses()
{
// Arrange
var input = "INSERT INTO Users (Id, Name) VALUES (1, 'Bob')";
// Act
var breakdown = InsertBreakdown.Parse(input);
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.TableName.Clause, Is.EqualTo("Users"));
Assert.That(breakdown.InsertIntoClause.Clause, Is.EqualTo("Id, Name"));
Assert.That(breakdown.ValuesClause.Clause, Is.EqualTo("1, 'Bob'"));
});
}
[Test]
public void Parse_NullOrWhitespace_ThrowsArgumentNullException()
{
// Act & Assert
Assert.Throws<ArgumentNullException>(() => InsertBreakdown.Parse(" "));
}
[Test]
public void Parse_NotAnInsertStatement_ThrowsFormatException()
{
// Act & Assert
Assert.Throws<FormatException>(() => InsertBreakdown.Parse("SELECT * FROM Users"));
}
[Test]
public void TryParse_ValidInsert_ReturnsTrue()
{
// Act
var success = InsertBreakdown.TryParse("INSERT INTO Users (Id) VALUES (1)", out var breakdown);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.True);
Assert.That(breakdown.TableName.Clause, Is.EqualTo("Users"));
});
}
[Test]
public void TryParse_WrongPrefix_ReturnsFalseWithMessage()
{
// Act
var success = InsertBreakdown.TryParse("UPDATE Users SET Id = 1", out _, out var error);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.False);
Assert.That(error, Does.Contain("INSERT INTO"));
});
}
[Test]
public void TryParse_MalformedInsert_ReturnsFalse()
{
// Act - matches the INSERT INTO prefix but not the column/values grammar
var success = InsertBreakdown.TryParse("INSERT INTO Users", out _, out var error);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.False);
Assert.That(error, Is.Not.Null.And.Not.Empty);
});
}
[Test]
public void GetSql_IncludeSetupFinish_RendersSetupAndFinishClauses()
{
// Arrange
var breakdown = new InsertBreakdown("Users", "Id", "@Id")
{
SetupClauses = { "SET NOCOUNT ON" },
FinishClauses = { "SELECT SCOPE_IDENTITY()" }
};
// Act
var withClauses = breakdown.GetSql(includeSetupFinish: true);
var withoutClauses = breakdown.GetSql(includeSetupFinish: false);
Assert.Multiple(() =>
{
// Assert
Assert.That(withClauses, Does.Contain("SET NOCOUNT ON"));
Assert.That(withClauses, Does.Contain("SELECT SCOPE_IDENTITY()"));
Assert.That(withClauses, Does.Contain("INSERT INTO"));
Assert.That(withoutClauses, Does.Not.Contain("SET NOCOUNT ON"));
Assert.That(withoutClauses, Does.Not.Contain("SELECT SCOPE_IDENTITY()"));
});
}
#endregion
}
@@ -0,0 +1,223 @@
using Strata.SqlTools.Breakdowns.SqlServer;
namespace Strata.SqlTools.SqlBreakdown.Tests.SqlServer;
[TestFixture]
public class ProcedureBreakdownTests
{
#region Constructor Tests
[Test]
public void Constructor_Default_InitializesEmptyState()
{
// Arrange & Act
var breakdown = new ProcedureBreakdown();
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.ProcedureName.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.Parameters, Is.Empty);
Assert.That(breakdown.IsUsingParameters, Is.False);
});
}
[Test]
public void Constructor_WithName_SetsProcedureName()
{
// Arrange & Act
var breakdown = new ProcedureBreakdown("dbo.GetUsers");
// Assert
Assert.That(breakdown.ProcedureName.Clause, Is.EqualTo("dbo.GetUsers"));
}
[Test]
public void Constructor_WithParameters_SetsParameters()
{
// Arrange
var parameters = new Dictionary<string, string> { ["@Id"] = "1" };
// Act
var breakdown = new ProcedureBreakdown("dbo.GetUser", parameters);
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.IsUsingParameters, Is.True);
Assert.That(breakdown.Parameters["@Id"], Is.EqualTo("1"));
});
}
#endregion
#region AddParameter Tests
[Test]
public void AddParameter_WithoutAtPrefix_AddsAtPrefix()
{
// Arrange
var breakdown = new ProcedureBreakdown("dbo.GetUser");
// Act
breakdown.AddParameter("Id", "1");
// Assert
Assert.That(breakdown.Parameters.ContainsKey("@Id"), Is.True);
}
[Test]
public void AddParameter_WithAtPrefix_KeepsSinglePrefix()
{
// Arrange
var breakdown = new ProcedureBreakdown("dbo.GetUser");
// Act
breakdown.AddParameter("@Id", "1");
// Assert
Assert.That(breakdown.Parameters.ContainsKey("@Id"), Is.True);
}
[Test]
public void AddParameter_NullName_ThrowsArgumentNullException()
{
// Arrange
var breakdown = new ProcedureBreakdown("dbo.GetUser");
// Act & Assert
Assert.Throws<ArgumentNullException>(() => breakdown.AddParameter(" ", "1"));
}
#endregion
#region GetSql Tests
[Test]
public void GetSql_WithoutParameters_RendersExecName()
{
// Arrange
var breakdown = new ProcedureBreakdown("dbo.GetUsers");
// Act
var sql = breakdown.GetSql();
Assert.Multiple(() =>
{
// Assert
Assert.That(sql, Does.Contain("EXEC"));
Assert.That(sql, Does.Contain("dbo.GetUsers"));
});
}
[Test]
public void GetSql_WithParameters_RendersNamedAssignments()
{
// Arrange
var breakdown = new ProcedureBreakdown("dbo.GetUser");
breakdown.AddParameter("@Id", "1");
// Act
var sql = breakdown.GetSql();
Assert.Multiple(() =>
{
// Assert
Assert.That(sql, Does.Contain("EXEC"));
Assert.That(sql, Does.Contain("@Id = 1"));
});
}
#endregion
#region Parse Tests
[Test]
public void Parse_ExecWithoutParameters_PopulatesName()
{
// Arrange
var input = "EXEC dbo.GetUsers";
// Act
var breakdown = ProcedureBreakdown.Parse(input);
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.ProcedureName.Clause, Is.EqualTo("dbo.GetUsers"));
Assert.That(breakdown.IsUsingParameters, Is.False);
});
}
[Test]
public void Parse_ExecWithParameters_PopulatesParameters()
{
// Arrange
var input = "EXEC dbo.GetUser @Id = 1, @Active = 1";
// Act
var breakdown = ProcedureBreakdown.Parse(input);
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.ProcedureName.Clause, Is.EqualTo("dbo.GetUser"));
Assert.That(breakdown.Parameters["@Id"], Is.EqualTo("1"));
Assert.That(breakdown.Parameters["@Active"], Is.EqualTo("1"));
});
}
[Test]
public void Parse_ExecuteKeyword_IsAccepted()
{
// Act
var breakdown = ProcedureBreakdown.Parse("EXECUTE dbo.GetUsers");
// Assert
Assert.That(breakdown.ProcedureName.Clause, Is.EqualTo("dbo.GetUsers"));
}
[Test]
public void Parse_NullOrWhitespace_ThrowsArgumentNullException()
{
// Act & Assert
Assert.Throws<ArgumentNullException>(() => ProcedureBreakdown.Parse(" "));
}
[Test]
public void Parse_NotAnExecStatement_ThrowsFormatException()
{
// Act & Assert
Assert.Throws<FormatException>(() => ProcedureBreakdown.Parse("SELECT * FROM Users"));
}
[Test]
public void TryParse_WrongPrefix_ReturnsFalseWithMessage()
{
// Act
var success = ProcedureBreakdown.TryParse("SELECT 1", out _, out var error);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.False);
Assert.That(error, Does.Contain("EXEC"));
});
}
[Test]
public void TryParse_ValidExec_ReturnsTrue()
{
// Act
var success = ProcedureBreakdown.TryParse("EXEC dbo.GetUsers", out var breakdown);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.True);
Assert.That(breakdown.ProcedureName.Clause, Is.EqualTo("dbo.GetUsers"));
});
}
#endregion
}
@@ -0,0 +1,208 @@
using Strata.SqlTools.Breakdowns.SqlServer;
namespace Strata.SqlTools.SqlBreakdown.Tests.SqlServer;
[TestFixture]
public class UpdateBreakdownTests
{
#region Constructor Tests
[Test]
public void Constructor_Default_InitializesEmptyClauses()
{
// Arrange & Act
var breakdown = new UpdateBreakdown();
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.TableName.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.SetClause.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.FromClause.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.WhereClause.Clause, Is.EqualTo(string.Empty));
Assert.That(breakdown.IsUsingFromClause, Is.False);
Assert.That(breakdown.IsUsingWhereClause, Is.False);
});
}
[Test]
public void Constructor_WithClauses_SetsProperties()
{
// Arrange & Act
var breakdown = new UpdateBreakdown("Users", "Name = @Name", "Id = @Id");
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.TableName.Clause, Is.EqualTo("Users"));
Assert.That(breakdown.SetClause.Clause, Is.EqualTo("Name = @Name"));
Assert.That(breakdown.WhereClause.Clause, Is.EqualTo("Id = @Id"));
Assert.That(breakdown.IsUsingWhereClause, Is.True);
});
}
#endregion
#region GetSql Tests
[Test]
public void GetSql_WithWhere_RendersUpdateSetWhere()
{
// Arrange
var breakdown = new UpdateBreakdown("Users", "Name = @Name", "Id = @Id");
// Act
var sql = breakdown.GetSql();
Assert.Multiple(() =>
{
// Assert
Assert.That(sql, Does.Contain("UPDATE"));
Assert.That(sql, Does.Contain("Users"));
Assert.That(sql, Does.Contain("SET"));
Assert.That(sql, Does.Contain("Name = @Name"));
Assert.That(sql, Does.Contain("WHERE"));
Assert.That(sql, Does.Contain("Id = @Id"));
});
}
[Test]
public void GetSql_WithoutWhere_OmitsWhereKeyword()
{
// Arrange
var breakdown = new UpdateBreakdown("Users", "Name = @Name", string.Empty);
// Act
var sql = breakdown.GetSql();
Assert.Multiple(() =>
{
// Assert
Assert.That(sql, Does.Contain("UPDATE"));
Assert.That(sql, Does.Not.Contain("WHERE"));
});
}
[Test]
public void GetSql_WithFromClause_RendersFromSection()
{
// Arrange
var breakdown = new UpdateBreakdown("u", "u.Name = s.Name", "u.Id = s.Id")
{
FromClause = { Clause = "Users u INNER JOIN Staging s ON u.Id = s.Id" }
};
// Act
var sql = breakdown.GetSql();
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.IsUsingFromClause, Is.True);
Assert.That(sql, Does.Contain("FROM"));
Assert.That(sql, Does.Contain("INNER JOIN Staging"));
});
}
#endregion
#region Parse Tests
[Test]
public void Parse_SimpleUpdate_PopulatesClauses()
{
// Arrange
var input = "UPDATE Users SET Name = 'Bob' WHERE Id = 1";
// Act
var breakdown = UpdateBreakdown.Parse(input);
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.TableName.Clause, Is.EqualTo("Users"));
Assert.That(breakdown.SetClause.Clause, Is.EqualTo("Name = 'Bob'"));
Assert.That(breakdown.WhereClause.Clause, Is.EqualTo("Id = 1"));
});
}
[Test]
public void Parse_UpdateWithFrom_PopulatesFromClause()
{
// Arrange
var input = "UPDATE u SET u.Name = s.Name FROM Users u INNER JOIN Staging s ON u.Id = s.Id WHERE s.Active = 1";
// Act
var breakdown = UpdateBreakdown.Parse(input);
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.TableName.Clause, Is.EqualTo("u"));
Assert.That(breakdown.IsUsingFromClause, Is.True);
Assert.That(breakdown.FromClause.Clause, Does.Contain("INNER JOIN Staging"));
Assert.That(breakdown.WhereClause.Clause, Is.EqualTo("s.Active = 1"));
});
}
[Test]
public void Parse_UpdateWithoutWhere_LeavesWhereEmpty()
{
// Arrange
var input = "UPDATE Users SET Name = 'Bob'";
// Act
var breakdown = UpdateBreakdown.Parse(input);
Assert.Multiple(() =>
{
// Assert
Assert.That(breakdown.SetClause.Clause, Is.EqualTo("Name = 'Bob'"));
Assert.That(breakdown.IsUsingWhereClause, Is.False);
});
}
[Test]
public void Parse_NullOrWhitespace_ThrowsArgumentNullException()
{
// Act & Assert
Assert.Throws<ArgumentNullException>(() => UpdateBreakdown.Parse(string.Empty));
}
[Test]
public void Parse_NotAnUpdateStatement_ThrowsFormatException()
{
// Act & Assert
Assert.Throws<FormatException>(() => UpdateBreakdown.Parse("DELETE FROM Users"));
}
[Test]
public void TryParse_WrongPrefix_ReturnsFalseWithMessage()
{
// Act
var success = UpdateBreakdown.TryParse("SELECT * FROM Users", out _, out var error);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.False);
Assert.That(error, Does.Contain("UPDATE"));
});
}
[Test]
public void TryParse_ValidUpdate_ReturnsTrue()
{
// Act
var success = UpdateBreakdown.TryParse("UPDATE Users SET Name = 'Bob' WHERE Id = 1", out var breakdown);
Assert.Multiple(() =>
{
// Assert
Assert.That(success, Is.True);
Assert.That(breakdown.TableName.Clause, Is.EqualTo("Users"));
});
}
#endregion
}