Files
sql-utilities/tests/Strata.SqlTools.Snowflake.Tests/Snowflake/CommentTests.cs
T
Thom LambandClaude Opus 4.7 67512d23e1 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>
2026-05-27 11:59:47 -05:00

405 lines
13 KiB
C#

using Strata.SqlTools.Breakdowns.Snowflake;
namespace Strata.SqlTools.SqlBreakdown.Tests.Snowflake;
[TestFixture]
public class CommentTests
{
[Test]
public void Parse_WithSingleLineCommentInSelect_PreservesComment()
{
// Arrange
var sql = @"SELECT
ID,
NAME, -- This is a customer name
EMAIL
FROM USERS";
// Act
var query = QueryBreakdown.Parse(sql);
// Assert
Assert.That(query.SelectClause.Clause, Does.Contain("ID"));
Assert.That(query.SelectClause.Clause, Does.Contain("NAME"));
Assert.Multiple(() =>
{
Assert.That(query.SelectClause.Clause, Does.Contain("EMAIL"));
Assert.That(query.SelectClause.Comment, Does.Contain("-- This is a customer name"));
});
}
[Test]
public void Parse_WithMultiLineCommentInSelect_PreservesComment()
{
// Arrange
var sql = @"SELECT
ID,
/* Multi-line comment
explaining the query */
NAME,
EMAIL
FROM USERS";
// Act
var query = QueryBreakdown.Parse(sql);
// Assert
Assert.That(query.SelectClause.Clause, Does.Contain("ID"));
Assert.Multiple(() =>
{
Assert.That(query.SelectClause.Clause, Does.Contain("NAME"));
Assert.That(query.SelectClause.Comment, Does.Contain("/* Multi-line comment"));
});
Assert.That(query.SelectClause.Comment, Does.Contain("explaining the query */"));
}
[Test]
public void Parse_WithCommentsInMultipleClauses_PreservesAllComments()
{
// Arrange
var sql = @"SELECT
-- Select specific columns
ID, NAME, EMAIL
FROM USERS -- Main user table
WHERE
/* Active users only */
STATUS = 'Active'
ORDER BY
NAME -- Sort by name";
// Act
var query = QueryBreakdown.Parse(sql);
Assert.Multiple(() =>
{
// Assert
Assert.That(query.SelectClause.Comment, Does.Contain("-- Select specific columns"));
Assert.That(query.FromClause.Comment, Does.Contain("-- Main user table"));
Assert.That(query.WhereClause.Comment, Does.Contain("/* Active users only */"));
Assert.That(query.OrderByClause.Comment, Does.Contain("-- Sort by name"));
});
}
[Test]
public void GetSql_WithComments_ReturnsCommentsInOutput()
{
// Arrange
var sql = @"SELECT
-- Important columns
ID, NAME
FROM USERS -- User table
WHERE STATUS = 'Active'";
var query = QueryBreakdown.Parse(sql);
// Act
var result = query.GetSql();
// Assert
Assert.That(result, Does.Contain("-- Important columns"));
Assert.That(result, Does.Contain("-- User table"));
}
[Test]
public void Parse_WithNoComments_HasNullCommentProperties()
{
// Arrange
var sql = "SELECT ID, NAME FROM USERS WHERE STATUS = 'Active'";
// Act
var query = QueryBreakdown.Parse(sql);
Assert.Multiple(() =>
{
// Assert
Assert.That(query.SelectClause.Comment, Is.Null.Or.Empty);
Assert.That(query.FromClause.Comment, Is.Null.Or.Empty);
Assert.That(query.WhereClause.Comment, Is.Null.Or.Empty);
});
}
[Test]
public void Clone_WithComments_PreservesComments()
{
// Arrange
var sql = @"SELECT
-- Select columns
ID, NAME
FROM USERS
WHERE STATUS = 'Active'";
var original = QueryBreakdown.Parse(sql);
// Act
var cloned = (QueryBreakdown)original.Clone();
Assert.Multiple(() =>
{
// Assert
Assert.That(cloned.SelectClause.Comment, Is.EqualTo(original.SelectClause.Comment));
Assert.That(cloned.FromClause.Comment, Is.EqualTo(original.FromClause.Comment));
Assert.That(cloned.WhereClause.Comment, Is.EqualTo(original.WhereClause.Comment));
});
}
[Test]
public void Parse_WithCommentInGroupBy_PreservesComment()
{
// Arrange
var sql = @"SELECT
DEPARTMENT, COUNT(*) AS EMPLOYEE_COUNT
FROM EMPLOYEES
GROUP BY
-- Group by department
DEPARTMENT";
// Act
var query = QueryBreakdown.Parse(sql);
// Assert
Assert.That(query.GroupByClause.Comment, Does.Contain("-- Group by department"));
}
[Test]
public void Parse_WithCommentInHaving_PreservesComment()
{
// Arrange
var sql = @"SELECT
DEPARTMENT, COUNT(*) AS EMPLOYEE_COUNT
FROM EMPLOYEES
GROUP BY DEPARTMENT
HAVING
/* Only departments with more than 10 employees */
COUNT(*) > 10";
// Act
var query = QueryBreakdown.Parse(sql);
// Assert
Assert.That(query.HavingClause.Comment, Does.Contain("/* Only departments with more than 10 employees */"));
}
[Test]
public void GetSql_RoundTrip_WithComments_PreservesComments()
{
// Arrange
var sql = @"SELECT
-- Customer details
ID, NAME, EMAIL
FROM USERS
WHERE STATUS = 'Active'";
var query = QueryBreakdown.Parse(sql);
// Act
var generatedSql = query.GetSql();
var reparsed = QueryBreakdown.Parse(generatedSql);
// Assert
Assert.That(reparsed.SelectClause.Comment, Does.Contain("-- Customer details"));
}
[Test]
public void Parse_WithMultipleCommentsInSameClause_PreservesAllComments()
{
// Arrange
var sql = @"SELECT
-- First comment
ID,
NAME, -- Second comment
/* Third comment */
EMAIL
FROM USERS";
// Act
var query = QueryBreakdown.Parse(sql);
// Assert
Assert.That(query.SelectClause.Comment, Does.Contain("-- First comment"));
Assert.That(query.SelectClause.Comment, Does.Contain("-- Second comment"));
Assert.That(query.SelectClause.Comment, Does.Contain("/* Third comment */"));
}
[Test]
public void ExtractSqlComments_WithMultipleCommentTypes_ExtractsAll()
{
// Arrange
var sql = @"SELECT
ID, -- Single line
/* Multi
line */ NAME
FROM USERS";
// Act
var parser = new Strata.SqlTools.Statements.Snowflake.StatementParser();
var cleanSql = parser.ExtractSqlComments(sql, out var comments);
// Assert
Assert.That(comments, Has.Count.EqualTo(2));
Assert.Multiple(() =>
{
Assert.That(comments[0], Does.Contain("-- Single line"));
Assert.That(comments[1], Does.Contain("/* Multi"));
});
Assert.Multiple(() =>
{
Assert.That(comments[1], Does.Contain("line */"));
Assert.That(cleanSql, Does.Not.Contain("-- Single line"));
});
Assert.That(cleanSql, Does.Not.Contain("/*"));
}
[Test]
public void Demo_CompleteRoundTrip_WithComments()
{
// Arrange - Snowflake SQL with various comment styles
var originalSql = @"
SELECT
-- Primary key
ID,
NAME, -- Customer name field
/* Email address for notifications */
EMAIL,
STATUS
FROM
USERS -- Main user table
WHERE
/* Filter for active users only */
STATUS = 'Active'
ORDER BY
NAME -- Sort alphabetically
";
// Act - Parse SQL
var query = QueryBreakdown.Parse(originalSql);
// Assert - Comments are preserved in separate properties
Assert.That(query.SelectClause.Clause, Does.Contain("ID"));
Assert.That(query.SelectClause.Clause, Does.Contain("NAME"));
Assert.That(query.SelectClause.Clause, Does.Contain("EMAIL"));
Assert.That(query.SelectClause.Clause, Does.Not.Contain("--"));
Assert.Multiple(() =>
{
Assert.That(query.SelectClause.Clause, Does.Not.Contain("/*"));
Assert.That(query.SelectClause.Comment, Does.Contain("-- Primary key"));
});
Assert.That(query.SelectClause.Comment, Does.Contain("-- Customer name field"));
Assert.Multiple(() =>
{
Assert.That(query.SelectClause.Comment, Does.Contain("/* Email address for notifications */"));
Assert.That(query.FromClause.Comment, Does.Contain("-- Main user table"));
Assert.That(query.WhereClause.Comment, Does.Contain("/* Filter for active users only */"));
Assert.That(query.OrderByClause.Comment, Does.Contain("-- Sort alphabetically"));
});
// Act - Generate SQL
var regeneratedSql = query.GetSql();
// Assert - Comments are included in output
Assert.That(regeneratedSql, Does.Contain("-- Primary key"));
Assert.That(regeneratedSql, Does.Contain("-- Customer name field"));
Assert.That(regeneratedSql, Does.Contain("/* Email address for notifications */"));
Assert.That(regeneratedSql, Does.Contain("-- Main user table"));
Assert.That(regeneratedSql, Does.Contain("/* Filter for active users only */"));
Assert.That(regeneratedSql, Does.Contain("-- Sort alphabetically"));
// Display the generated SQL
TestContext.WriteLine("Regenerated Snowflake SQL:");
TestContext.WriteLine(regeneratedSql);
}
[Test]
public void Parse_WithDoubleQuotedIdentifiersAndComments_PreservesComments()
{
// Arrange - Snowflake-specific double-quoted identifiers
var sql = @"SELECT
-- Primary key column
""ID"",
""Name"", -- Customer name
""Email Address"" -- Email with space in column name
FROM ""Users""";
// Act
var query = QueryBreakdown.Parse(sql);
// Assert
Assert.That(query.SelectClause.Comment, Does.Contain("-- Primary key column"));
Assert.That(query.SelectClause.Comment, Does.Contain("-- Customer name"));
Assert.That(query.SelectClause.Comment, Does.Contain("-- Email with space in column name"));
}
[Test]
public void Parse_WithSnowflakeParameterSyntaxAndComments_PreservesComments()
{
// Arrange - Snowflake :parameter syntax
var sql = @"SELECT
ID,
NAME,
EMAIL
FROM USERS
WHERE
-- Filter by status parameter
STATUS = :status
AND -- Additional condition
CREATED_DATE > :start_date";
// Act
var query = QueryBreakdown.Parse(sql);
query.SetParameterValue(":status", "Active");
query.SetParameterValue(":start_date", "2024-01-01");
// Assert
Assert.That(query.WhereClause.Comment, Does.Contain("-- Filter by status parameter"));
Assert.Multiple(() =>
{
Assert.That(query.WhereClause.Comment, Does.Contain("-- Additional condition"));
Assert.That(query.Parameters, Contains.Key(":status"));
});
Assert.That(query.Parameters, Contains.Key(":start_date"));
}
[Test]
public void Parse_WithQualifyClauseAndComments_PreservesComments()
{
// Arrange - Snowflake-specific QUALIFY clause
var sql = @"SELECT
ID,
NAME,
ROW_NUMBER() OVER (PARTITION BY DEPARTMENT ORDER BY SALARY DESC) AS RN
FROM EMPLOYEES
QUALIFY
-- Get only the top earner per department
RN = 1";
// Act
var query = QueryBreakdown.Parse(sql);
// Assert - Note: QUALIFY handling depends on implementation
Assert.That(query.SelectClause.Clause, Does.Contain("ID"));
Assert.That(query.SelectClause.Clause, Does.Contain("NAME"));
}
[Test]
public void Parse_WithLimitClauseAndComments_PreservesComments()
{
// Arrange - Snowflake LIMIT syntax
var sql = @"SELECT
ID,
NAME,
EMAIL
FROM USERS
ORDER BY
NAME
LIMIT 100 -- Limit to first 100 records";
// Act
var query = QueryBreakdown.Parse(sql);
// Assert
Assert.That(query.OrderByClause.Comment, Does.Contain("-- Limit to first 100 records"));
}
}