chore: initial git load of code space
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
using Strata.SqlTools.Breakdowns.PostgreSql;
|
||||
using Strata.SqlTools.Markdown.PostgreSql;
|
||||
|
||||
namespace Strata.SqlTools.Markdown.Tests.PostgreSql;
|
||||
|
||||
[TestFixture]
|
||||
public class QueryBreakdownGeneratorTests
|
||||
{
|
||||
private QueryBreakdownGenerator _generator = null!;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_generator = new QueryBreakdownGenerator();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_SimplePostgreSqlQuery_GeneratesValidMermaid()
|
||||
{
|
||||
// Arrange - Using PostgreSQL syntax with lowercase identifiers
|
||||
var query = new QueryBreakdown("user_id, user_name", "users");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query, "Simple User Query");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("```mermaid"));
|
||||
Assert.That(result, Does.Contain("flowchart TD"));
|
||||
Assert.That(result, Does.Contain("### Simple User Query"));
|
||||
Assert.That(result, Does.Contain("SELECT"));
|
||||
Assert.That(result, Does.Contain("FROM"));
|
||||
Assert.That(result, Does.Contain("```"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_WithPositionalParameters_HandlesParameters()
|
||||
{
|
||||
// Arrange - PostgreSQL uses $1, $2 syntax for positional parameters
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
SELECT user_id, user_name, status
|
||||
FROM users
|
||||
WHERE user_id = $1
|
||||
AND status = $2
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("WHERE"));
|
||||
Assert.That(result, Does.Contain("```mermaid"));
|
||||
Assert.That(result, Does.Contain("flowchart TD"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_WithNamedParameters_HandlesColonSyntax()
|
||||
{
|
||||
// Arrange - PostgreSQL also supports :parameter syntax
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
SELECT user_id, user_name, email
|
||||
FROM users
|
||||
WHERE user_id = :userId
|
||||
AND status = :status
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("WHERE"));
|
||||
Assert.That(result, Does.Contain("```mermaid"));
|
||||
Assert.That(result, Does.Contain("flowchart TD"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_WithPostgreSqlCTE_ShowsWithClause()
|
||||
{
|
||||
// Arrange - PostgreSQL CTE with lowercase naming
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
WITH active_users AS (
|
||||
SELECT user_id, user_name
|
||||
FROM users
|
||||
WHERE status = 'ACTIVE'
|
||||
)
|
||||
SELECT u.user_id, u.user_name, COUNT(o.order_id) AS order_count
|
||||
FROM active_users u
|
||||
JOIN orders o ON u.user_id = o.user_id
|
||||
GROUP BY u.user_id, u.user_name
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query, "Users with Orders");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("### Users with Orders"));
|
||||
Assert.That(result, Does.Contain("```mermaid"));
|
||||
Assert.That(result, Does.Contain("flowchart TD"));
|
||||
Assert.That(result, Does.Contain("GROUP BY"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_WithLimit_HandlesLimitClause()
|
||||
{
|
||||
// Arrange - PostgreSQL LIMIT clause
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
SELECT user_id, user_name, created_at
|
||||
FROM users
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 10
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query, "Recent Users");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("SELECT"));
|
||||
Assert.That(result, Does.Contain("FROM"));
|
||||
Assert.That(result, Does.Contain("ORDER BY"));
|
||||
Assert.That(result, Does.Contain("```mermaid"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_WithLimitOffset_HandlesPagination()
|
||||
{
|
||||
// Arrange - PostgreSQL LIMIT/OFFSET for pagination
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
SELECT product_id, product_name, price
|
||||
FROM products
|
||||
ORDER BY product_name
|
||||
LIMIT 20 OFFSET 40
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("SELECT"));
|
||||
Assert.That(result, Does.Contain("ORDER BY"));
|
||||
Assert.That(result, Does.Contain("FROM"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_WithDoubleQuotedIdentifiers_HandlesPostgreSqlQuoting()
|
||||
{
|
||||
// Arrange - PostgreSQL uses "identifier" for case-sensitive names
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
SELECT ""userId"", ""userName"", ""emailAddress""
|
||||
FROM ""Users""
|
||||
WHERE ""status"" = 'ACTIVE'
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("SELECT"));
|
||||
Assert.That(result, Does.Contain("WHERE"));
|
||||
Assert.That(result, Does.Contain("FROM"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_ComplexPostgreSqlQuery_GeneratesCompleteDiagram()
|
||||
{
|
||||
// Arrange - Complex PostgreSQL query with multiple clauses
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
WITH sales_data AS (
|
||||
SELECT
|
||||
region,
|
||||
product_id,
|
||||
SUM(sales_amount) AS total_sales,
|
||||
COUNT(*) AS order_count
|
||||
FROM sales
|
||||
WHERE sale_date >= $1 AND sale_date <= $2
|
||||
GROUP BY region, product_id
|
||||
)
|
||||
SELECT
|
||||
sd.region,
|
||||
p.product_name,
|
||||
sd.total_sales,
|
||||
sd.order_count
|
||||
FROM sales_data sd
|
||||
JOIN products p ON sd.product_id = p.product_id
|
||||
WHERE sd.total_sales > $3
|
||||
ORDER BY sd.total_sales DESC
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query, "Regional Sales Analysis");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("### Regional Sales Analysis"));
|
||||
Assert.That(result, Does.Contain("```mermaid"));
|
||||
Assert.That(result, Does.Contain("flowchart TD"));
|
||||
Assert.That(result, Does.Contain("SELECT"));
|
||||
Assert.That(result, Does.Contain("FROM"));
|
||||
Assert.That(result, Does.Contain("WHERE"));
|
||||
Assert.That(result, Does.Contain("ORDER BY"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_WithGroupByAndHaving_IncludesBothClauses()
|
||||
{
|
||||
// Arrange
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
SELECT category, COUNT(*) AS product_count, AVG(price) AS avg_price
|
||||
FROM products
|
||||
GROUP BY category
|
||||
HAVING COUNT(*) > 10 AND AVG(price) < 100
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("GROUP BY"));
|
||||
Assert.That(result, Does.Contain("HAVING"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_NullTitle_GeneratesWithoutTitle()
|
||||
{
|
||||
// Arrange
|
||||
var query = new QueryBreakdown("id", "orders");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query, null);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Not.Contain("###"));
|
||||
Assert.That(result, Does.Contain("```mermaid"));
|
||||
Assert.That(result, Does.Contain("flowchart TD"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_EmptyTitle_GeneratesWithoutTitle()
|
||||
{
|
||||
// Arrange
|
||||
var query = new QueryBreakdown("order_id", "orders");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query, "");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Not.Contain("###"));
|
||||
Assert.That(result, Does.Contain("SELECT"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_PostgreSqlTypeCasting_PreservesSyntax()
|
||||
{
|
||||
// Arrange - PostgreSQL :: casting syntax
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
SELECT
|
||||
order_id::VARCHAR AS order_code,
|
||||
amount::DECIMAL(10,2) AS formatted_amount,
|
||||
create_date::TIMESTAMP AS created_at
|
||||
FROM orders
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query, "Type Cast Example");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("SELECT"));
|
||||
Assert.That(result, Does.Contain("FROM"));
|
||||
Assert.That(result, Does.Contain("### Type Cast Example"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_PostgreSqlJsonOperators_HandlesJsonNotation()
|
||||
{
|
||||
// Arrange - PostgreSQL JSON operators (-> for JSON object, ->> for text)
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
SELECT
|
||||
json_data->>'name' AS name,
|
||||
json_data->'address'->>'city' AS city,
|
||||
(json_data->>'age')::INTEGER AS age
|
||||
FROM user_json
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query, "JSON Data");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("SELECT"));
|
||||
Assert.That(result, Does.Contain("FROM"));
|
||||
Assert.That(result, Does.Contain("```mermaid"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GenerateMermaidDiagram_WithDistinct_HandlesDistinctClause()
|
||||
{
|
||||
// Arrange - PostgreSQL DISTINCT
|
||||
var query = QueryBreakdown.Parse(@"
|
||||
SELECT DISTINCT region, product_category
|
||||
FROM sales
|
||||
ORDER BY region, product_category
|
||||
");
|
||||
|
||||
// Act
|
||||
var result = _generator.GenerateMermaidDiagram(query);
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Does.Contain("SELECT"));
|
||||
Assert.That(result, Does.Contain("FROM"));
|
||||
Assert.That(result, Does.Contain("ORDER BY"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user