Files
relspecgo/pkg/writers/sqlexec/writer_test.go
Hein adfe126758
Some checks failed
CI / Test (1.24) (push) Successful in -25m17s
CI / Test (1.25) (push) Successful in -25m15s
CI / Build (push) Successful in -25m45s
CI / Lint (push) Successful in -25m31s
Integration Tests / Integration Tests (push) Failing after -25m58s
Added a scripts execution ability
2025-12-31 00:44:14 +02:00

202 lines
5.7 KiB
Go

package sqlexec
import (
"testing"
"git.warky.dev/wdevs/relspecgo/pkg/models"
"git.warky.dev/wdevs/relspecgo/pkg/writers"
)
func TestNewWriter(t *testing.T) {
opts := &writers.WriterOptions{
Metadata: map[string]any{
"connection_string": "postgres://localhost/test",
},
}
writer := NewWriter(opts)
if writer == nil {
t.Fatal("Expected non-nil writer")
}
if writer.options != opts {
t.Error("Writer options not set correctly")
}
}
func TestWriter_WriteDatabase_NilDatabase(t *testing.T) {
writer := NewWriter(&writers.WriterOptions{
Metadata: map[string]any{
"connection_string": "postgres://localhost/test",
},
})
err := writer.WriteDatabase(nil)
if err == nil {
t.Error("Expected error for nil database, got nil")
}
}
func TestWriter_WriteDatabase_MissingConnectionString(t *testing.T) {
writer := NewWriter(&writers.WriterOptions{
Metadata: map[string]any{},
})
db := &models.Database{
Name: "test",
Schemas: []*models.Schema{
{
Name: "public",
Scripts: []*models.Script{
{Name: "test", SQL: "SELECT 1;"},
},
},
},
}
err := writer.WriteDatabase(db)
if err == nil {
t.Error("Expected error for missing connection_string, got nil")
}
}
func TestWriter_WriteSchema_NilSchema(t *testing.T) {
writer := NewWriter(&writers.WriterOptions{
Metadata: map[string]any{
"connection_string": "postgres://localhost/test",
},
})
err := writer.WriteSchema(nil)
if err == nil {
t.Error("Expected error for nil schema, got nil")
}
}
func TestWriter_WriteSchema_MissingConnectionString(t *testing.T) {
writer := NewWriter(&writers.WriterOptions{
Metadata: map[string]any{},
})
schema := &models.Schema{
Name: "public",
Scripts: []*models.Script{
{Name: "test", SQL: "SELECT 1;"},
},
}
err := writer.WriteSchema(schema)
if err == nil {
t.Error("Expected error for missing connection_string, got nil")
}
}
func TestWriter_WriteTable(t *testing.T) {
writer := NewWriter(&writers.WriterOptions{})
err := writer.WriteTable(&models.Table{})
if err == nil {
t.Error("Expected error for WriteTable (not supported), got nil")
}
}
// TestScriptSorting verifies that scripts are sorted correctly by Priority then Sequence
func TestScriptSorting(t *testing.T) {
scripts := []*models.Script{
{Name: "script1", Priority: 2, Sequence: 1, SQL: "SELECT 1;"},
{Name: "script2", Priority: 1, Sequence: 3, SQL: "SELECT 2;"},
{Name: "script3", Priority: 1, Sequence: 1, SQL: "SELECT 3;"},
{Name: "script4", Priority: 1, Sequence: 2, SQL: "SELECT 4;"},
{Name: "script5", Priority: 3, Sequence: 1, SQL: "SELECT 5;"},
{Name: "script6", Priority: 2, Sequence: 2, SQL: "SELECT 6;"},
}
// Create a copy and sort it using the same logic as executeScripts
sortedScripts := make([]*models.Script, len(scripts))
copy(sortedScripts, scripts)
// Use the same sorting logic from executeScripts
for i := 0; i < len(sortedScripts)-1; i++ {
for j := i + 1; j < len(sortedScripts); j++ {
if sortedScripts[i].Priority > sortedScripts[j].Priority ||
(sortedScripts[i].Priority == sortedScripts[j].Priority &&
sortedScripts[i].Sequence > sortedScripts[j].Sequence) {
sortedScripts[i], sortedScripts[j] = sortedScripts[j], sortedScripts[i]
}
}
}
// Expected order after sorting
expectedOrder := []string{
"script3", // Priority 1, Sequence 1
"script4", // Priority 1, Sequence 2
"script2", // Priority 1, Sequence 3
"script1", // Priority 2, Sequence 1
"script6", // Priority 2, Sequence 2
"script5", // Priority 3, Sequence 1
}
for i, expected := range expectedOrder {
if sortedScripts[i].Name != expected {
t.Errorf("Position %d: expected %s, got %s", i, expected, sortedScripts[i].Name)
}
}
// Verify priorities are ascending
for i := 0; i < len(sortedScripts)-1; i++ {
if sortedScripts[i].Priority > sortedScripts[i+1].Priority {
t.Errorf("Priority not ascending at position %d: %d > %d",
i, sortedScripts[i].Priority, sortedScripts[i+1].Priority)
}
// Within same priority, sequences should be ascending
if sortedScripts[i].Priority == sortedScripts[i+1].Priority &&
sortedScripts[i].Sequence > sortedScripts[i+1].Sequence {
t.Errorf("Sequence not ascending at position %d with same priority %d: %d > %d",
i, sortedScripts[i].Priority, sortedScripts[i].Sequence, sortedScripts[i+1].Sequence)
}
}
}
func TestWriter_WriteSchema_EmptyScripts(t *testing.T) {
// This test verifies that writing an empty script list doesn't cause errors
// even without a database connection (should return early)
writer := NewWriter(&writers.WriterOptions{
Metadata: map[string]any{
"connection_string": "postgres://invalid/test",
},
})
schema := &models.Schema{
Name: "public",
Scripts: []*models.Script{},
}
// Note: This will try to connect even with empty scripts
// In a real scenario, the executeScripts function returns early for empty scripts
// but the connection is made before that. This test documents the behavior.
err := writer.WriteSchema(schema)
// We expect a connection error since we're using an invalid connection string
if err == nil {
t.Error("Expected connection error, got nil")
}
}
// NOTE: Integration tests for actual database execution should be added separately
// Those tests would require:
// 1. A running PostgreSQL instance
// 2. Test database setup/teardown
// 3. Verification of actual script execution
// 4. Testing error handling during execution
// 5. Testing transaction behavior if added
//
// Example integration test structure:
// func TestWriter_Integration_ExecuteScripts(t *testing.T) {
// if testing.Short() {
// t.Skip("Skipping integration test")
// }
// // Setup test database
// // Create test scripts
// // Execute scripts
// // Verify results
// // Cleanup
// }